Implement off-screen rendering support using delegated rendering (issue #1257).

This implementation supports both GPU compositing and software compositing (used when GPU is not supported or when passing `--disable-gpu --disable-gpu-compositing` command-line flags). GPU-accelerated features (WebGL and 3D CSS) that did not work with the previous off-screen rendering implementation do work with this implementation when GPU support is available.

Rendering now operates on a per-frame basis. The frame rate is configurable via CefBrowserSettings.windowless_frame_rate up to a maximum of 60fps (potentially limited by how fast the system can generate new frames). CEF generates a bitmap from the compositor backing and passes it to CefRenderHandler::OnPaint.

The previous CefRenderHandler/CefBrowserHost API for off-screen rendering has been restored mostly as-is with some minor changes:

- CefBrowserHost::Invalidate no longer accepts a CefRect region argument. Instead of invalidating a specific region it now triggers generation of a new frame.
- The |dirtyRects| argument to CefRenderHandler::OnPaint will now always be a single CefRect representing the whole view (frame) size. Previously, invalidated regions were listed separately.
- Linux: CefBrowserHost::SendKeyEvent now expects X11 event information instead of GTK event information. See cefclient for an example of converting GTK events to the necessary format.
- Sizes passed to the CefRenderHandler OnPaint and OnPopupSize methods are now already DPI scaled. Previously, the client had to perform DPI scaling.
- Includes drag&drop implementation from issue #1032.
- Includes unit test fixes from issue #1245.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1751 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2014-06-30 22:30:29 +00:00
parent 133317eeec
commit dea4daffd7
106 changed files with 13053 additions and 176 deletions

55
cef.gyp
View File

@ -183,6 +183,7 @@
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'gtk',
'gtkglext',
'libcef',
],
'link_settings': {
@ -397,6 +398,8 @@
'tests/cefclient/client_app.h',
'tests/cefclient/client_switches.cpp',
'tests/cefclient/client_switches.h',
'tests/cefclient/resource_util.h',
'tests/cefclient/res/osr_test.html',
'tests/unittests/browser_info_map_unittest.cc',
'tests/unittests/command_line_unittest.cc',
'tests/unittests/cookie_unittest.cc',
@ -409,6 +412,7 @@
'tests/unittests/life_span_unittest.cc',
'tests/unittests/message_router_unittest.cc',
'tests/unittests/navigation_unittest.cc',
'tests/unittests/os_rendering_unittest.cc',
'tests/unittests/process_message_unittest.cc',
'tests/unittests/request_context_unittest.cc',
'tests/unittests/request_handler_unittest.cc',
@ -438,6 +442,7 @@
'tests/unittests/zip_reader_unittest.cc',
],
'mac_bundle_resources': [
'tests/cefclient/res/osr_test.html',
'tests/unittests/mac/unittests.icns',
'tests/unittests/mac/English.lproj/InfoPlist.strings',
'tests/unittests/mac/English.lproj/MainMenu.xib',
@ -467,6 +472,10 @@
'cef_sandbox',
'libcef',
],
'sources': [
'tests/cefclient/cefclient.rc',
'tests/cefclient/resource_util_win.cpp',
],
'msvs_settings': {
'VCManifestTool': {
'AdditionalManifestFiles': [
@ -553,6 +562,10 @@
],
},
'sources': [
'tests/cefclient/resource_util_mac.mm',
'tests/cefclient/resource_util_posix.cpp',
'tests/unittests/os_rendering_unittest_mac.h',
'tests/unittests/os_rendering_unittest_mac.mm',
'tests/unittests/run_all_unittests_mac.mm',
],
}],
@ -560,6 +573,18 @@
'dependencies': [
'libcef',
],
'sources': [
'tests/cefclient/resource_util_linux.cpp',
'tests/cefclient/resource_util_posix.cpp',
],
'copies': [
{
'destination': '<(PRODUCT_DIR)/files',
'files': [
'tests/cefclient/res/osr_test.html',
],
},
],
}],
],
},
@ -901,6 +926,8 @@
'libcef/browser/printing/print_view_manager_base.h',
'libcef/browser/process_util_impl.cc',
'libcef/browser/proxy_stubs.cc',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/resource_dispatcher_host_delegate.cc',
'libcef/browser/resource_dispatcher_host_delegate.h',
'libcef/browser/resource_request_job.cc',
@ -931,6 +958,8 @@
'libcef/browser/url_request_interceptor.h',
'libcef/browser/url_request_user_data.cc',
'libcef/browser/url_request_user_data.h',
'libcef/browser/web_contents_view_osr.cc',
'libcef/browser/web_contents_view_osr.h',
'libcef/browser/web_plugin_impl.cc',
'libcef/browser/web_plugin_impl.h',
'libcef/browser/xml_reader_impl.cc',
@ -1073,6 +1102,7 @@
'libcef/browser/javascript_dialog_win.cc',
'libcef/browser/menu_creator_runner_win.cc',
'libcef/browser/menu_creator_runner_win.h',
'libcef/browser/render_widget_host_view_osr_win.cc',
# Include sources for printing.
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_win.cc',
],
@ -1085,6 +1115,9 @@
'libcef/browser/javascript_dialog_mac.mm',
'libcef/browser/menu_creator_runner_mac.h',
'libcef/browser/menu_creator_runner_mac.mm',
'libcef/browser/render_widget_host_view_osr_mac.mm',
'libcef/browser/text_input_client_osr_mac.mm',
'libcef/browser/text_input_client_osr_mac.h',
# Include sources for printing.
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_mac.mm',
# Include sources for CoreAnimation support.
@ -1100,6 +1133,7 @@
'libcef/browser/javascript_dialog_linux.cc',
'libcef/browser/menu_creator_runner_linux.cc',
'libcef/browser/menu_creator_runner_linux.h',
'libcef/browser/render_widget_host_view_osr_linux.cc',
'libcef/browser/window_x11.cc',
'libcef/browser/window_x11.h',
#Include sources for printing.
@ -1632,6 +1666,27 @@
],
},
},
{
'target_name': 'gtkglext',
'type': 'none',
'variables': {
# gtkglext is required by the cefclient OSR example.
'gtk_packages': 'gtkglext-1.0',
},
'direct_dependent_settings': {
'cflags': [
'<!@(pkg-config --cflags <(gtk_packages))',
],
},
'link_settings': {
'ldflags': [
'<!@(pkg-config --libs-only-L --libs-only-other <(gtk_packages))',
],
'libraries': [
'<!@(pkg-config --libs-only-l <(gtk_packages))',
],
},
},
],
}], # OS=="linux" or OS=="freebsd" or OS=="openbsd"
[ 'OS=="win"', {

View File

@ -41,6 +41,7 @@
'include/cef_path_util.h',
'include/cef_process_message.h',
'include/cef_process_util.h',
'include/cef_render_handler.h',
'include/cef_render_process_handler.h',
'include/cef_request.h',
'include/cef_request_context.h',
@ -92,6 +93,7 @@
'include/capi/cef_path_util_capi.h',
'include/capi/cef_process_message_capi.h',
'include/capi/cef_process_util_capi.h',
'include/capi/cef_render_handler_capi.h',
'include/capi/cef_render_process_handler_capi.h',
'include/capi/cef_request_capi.h',
'include/capi/cef_request_context_capi.h',
@ -210,6 +212,8 @@
'libcef_dll/cpptoc/quota_callback_cpptoc.h',
'libcef_dll/ctocpp/read_handler_ctocpp.cc',
'libcef_dll/ctocpp/read_handler_ctocpp.h',
'libcef_dll/ctocpp/render_handler_ctocpp.cc',
'libcef_dll/ctocpp/render_handler_ctocpp.h',
'libcef_dll/ctocpp/render_process_handler_ctocpp.cc',
'libcef_dll/ctocpp/render_process_handler_ctocpp.h',
'libcef_dll/cpptoc/request_cpptoc.cc',
@ -370,6 +374,8 @@
'libcef_dll/ctocpp/quota_callback_ctocpp.h',
'libcef_dll/cpptoc/read_handler_cpptoc.cc',
'libcef_dll/cpptoc/read_handler_cpptoc.h',
'libcef_dll/cpptoc/render_handler_cpptoc.cc',
'libcef_dll/cpptoc/render_handler_cpptoc.h',
'libcef_dll/cpptoc/render_process_handler_cpptoc.cc',
'libcef_dll/cpptoc/render_process_handler_cpptoc.h',
'libcef_dll/ctocpp/request_ctocpp.cc',

View File

@ -91,6 +91,7 @@
'tests/cefclient/res/domaccess.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/osr_test.html',
'tests/cefclient/res/other_tests.html',
'tests/cefclient/res/performance.html',
'tests/cefclient/res/performance2.html',
@ -103,6 +104,8 @@
'tests/cefclient/cefclient.h',
'tests/cefclient/binding_test.cpp',
'tests/cefclient/binding_test.h',
'tests/cefclient/bytes_write_handler.cpp',
'tests/cefclient/bytes_write_handler.h',
'tests/cefclient/client_app.cpp',
'tests/cefclient/client_app.h',
'tests/cefclient/client_app_delegates.cpp',
@ -116,6 +119,9 @@
'tests/cefclient/dialog_test.h',
'tests/cefclient/dom_test.cpp',
'tests/cefclient/dom_test.h',
'tests/cefclient/dragdrop_events.h',
'tests/cefclient/osrenderer.h',
'tests/cefclient/osrenderer.cpp',
'tests/cefclient/performance_test.cpp',
'tests/cefclient/performance_test.h',
'tests/cefclient/performance_test_setup.h',
@ -133,6 +139,10 @@
'cefclient_sources_win': [
'tests/cefclient/cefclient.exe.manifest',
'tests/cefclient/cefclient.rc',
'tests/cefclient/cefclient_osr_dragdrop_win.h',
'tests/cefclient/cefclient_osr_dragdrop_win.cpp',
'tests/cefclient/cefclient_osr_widget_win.h',
'tests/cefclient/cefclient_osr_widget_win.cpp',
'tests/cefclient/cefclient_win.cpp',
'tests/cefclient/client_handler_win.cpp',
'tests/cefclient/resource.h',
@ -143,6 +153,8 @@
],
'cefclient_sources_mac': [
'tests/cefclient/cefclient_mac.mm',
'tests/cefclient/cefclient_osr_widget_mac.h',
'tests/cefclient/cefclient_osr_widget_mac.mm',
'tests/cefclient/client_handler_mac.mm',
'tests/cefclient/resource_util_mac.mm',
'tests/cefclient/resource_util_posix.cpp',
@ -191,6 +203,8 @@
],
'cefclient_sources_linux': [
'tests/cefclient/cefclient_gtk.cpp',
'tests/cefclient/cefclient_osr_widget_gtk.h',
'tests/cefclient/cefclient_osr_widget_gtk.cpp',
'tests/cefclient/client_handler_gtk.cpp',
'tests/cefclient/resource_util_linux.cpp',
'tests/cefclient/resource_util_posix.cpp',

View File

@ -39,6 +39,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_drag_data_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_process_message_capi.h"
#include "include/capi/cef_request_context_capi.h"
@ -357,6 +358,46 @@ typedef struct _cef_browser_host_t {
int (CEF_CALLBACK *is_mouse_cursor_change_disabled)(
struct _cef_browser_host_t* self);
///
// Returns true (1) if window rendering is disabled.
///
int (CEF_CALLBACK *is_window_rendering_disabled)(
struct _cef_browser_host_t* self);
///
// Notify the browser that the widget has been resized. The browser will first
// call cef_render_handler_t::GetViewRect to get the new size and then call
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
// function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *was_resized)(struct _cef_browser_host_t* self);
///
// Notify the browser that it has been hidden or shown. Layouting and
// cef_render_handler_t::OnPaint notification will stop when the browser is
// hidden. This function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *was_hidden)(struct _cef_browser_host_t* self, int hidden);
///
// Send a notification to the browser that the screen info has changed. The
// browser will then call cef_render_handler_t::GetScreenInfo to update the
// screen information with the new values. This simulates moving the webview
// window from one display to another, or changing the properties of the
// current display. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *notify_screen_info_changed)(
struct _cef_browser_host_t* self);
///
// Invalidate the view. The browser will call cef_render_handler_t::OnPaint
// asynchronously. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *invalidate)(struct _cef_browser_host_t* self,
cef_paint_element_type_t type);
///
// Send a key event to the browser.
///
@ -382,6 +423,8 @@ typedef struct _cef_browser_host_t {
// Send a mouse wheel event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view. The |deltaX| and |deltaY|
// values represent the movement delta in the X and Y directions respectively.
// In order to scroll inside select popups with window rendering disabled
// cef_render_handler_t::GetScreenPoint should be implemented properly.
///
void (CEF_CALLBACK *send_mouse_wheel_event)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event, int deltaX, int deltaY);
@ -397,6 +440,90 @@ typedef struct _cef_browser_host_t {
///
void (CEF_CALLBACK *send_capture_lost_event)(
struct _cef_browser_host_t* self);
///
// Get the NSTextInputContext implementation for enabling IME on Mac when
// window rendering is disabled.
///
cef_text_input_context_t (CEF_CALLBACK *get_nstext_input_context)(
struct _cef_browser_host_t* self);
///
// Handles a keyDown event prior to passing it through the NSTextInputClient
// machinery.
///
void (CEF_CALLBACK *handle_key_event_before_text_input_client)(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent);
///
// Performs any additional actions after NSTextInputClient handles the event.
///
void (CEF_CALLBACK *handle_key_event_after_text_input_client)(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent);
///
// Call this function when the user drags the mouse into the web view (before
// calling DragTargetDragOver/DragTargetLeave/DragTargetDrop). |drag_data|
// should not contain file contents as this type of data is not allowed to be
// dragged into the web view. File contents can be removed using
// cef_drag_data_t::ResetFileContents (for example, if |drag_data| comes from
// cef_render_handler_t::StartDragging). This function is only used when
// window rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_enter)(struct _cef_browser_host_t* self,
struct _cef_drag_data_t* drag_data,
const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops);
///
// Call this function each time the mouse is moved across the web view during
// a drag operation (after calling DragTargetDragEnter and before calling
// DragTargetDragLeave/DragTargetDrop). This function is only used when window
// rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_over)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops);
///
// Call this function when the user drags the mouse out of the web view (after
// calling DragTargetDragEnter). This function is only used when window
// rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_leave)(struct _cef_browser_host_t* self);
///
// Call this function when the user completes the drag operation by dropping
// the object onto the web view (after calling DragTargetDragEnter). The
// object being dropped is |drag_data|, given as an argument to the previous
// DragTargetDragEnter call. This function is only used when window rendering
// is disabled.
///
void (CEF_CALLBACK *drag_target_drop)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event);
///
// Call this function when the drag operation started by a
// cef_render_handler_t::StartDragging call has ended either in a drop or by
// being cancelled. |x| and |y| are mouse coordinates relative to the upper-
// left corner of the view. If the web view is both the drag source and the
// drag target then all DragTarget* functions should be called before
// DragSource* mthods. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *drag_source_ended_at)(struct _cef_browser_host_t* self,
int x, int y, cef_drag_operations_mask_t op);
///
// Call this function when the drag operation started by a
// cef_render_handler_t::StartDragging call has completed. This function may
// be called immediately without first calling DragSourceEndedAt to cancel a
// drag operation. If the web view is both the drag source and the drag target
// then all DragTarget* functions should be called before DragSource* mthods.
// This function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *drag_source_system_drag_ended)(
struct _cef_browser_host_t* self);
} cef_browser_host_t;

View File

@ -51,6 +51,7 @@
#include "include/capi/cef_life_span_handler_capi.h"
#include "include/capi/cef_load_handler_capi.h"
#include "include/capi/cef_process_message_capi.h"
#include "include/capi/cef_render_handler_capi.h"
#include "include/capi/cef_request_handler_capi.h"
#ifdef __cplusplus
@ -138,6 +139,12 @@ typedef struct _cef_client_t {
struct _cef_load_handler_t* (CEF_CALLBACK *get_load_handler)(
struct _cef_client_t* self);
///
// Return the handler for off-screen rendering events.
///
struct _cef_render_handler_t* (CEF_CALLBACK *get_render_handler)(
struct _cef_client_t* self);
///
// Return the handler for browser request events.
///

View File

@ -39,6 +39,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_stream_capi.h"
#ifdef __cplusplus
extern "C" {
@ -55,6 +56,16 @@ typedef struct _cef_drag_data_t {
///
cef_base_t base;
///
// Returns a copy of the current object.
///
struct _cef_drag_data_t* (CEF_CALLBACK *clone)(struct _cef_drag_data_t* self);
///
// Returns true (1) if this object is read-only.
///
int (CEF_CALLBACK *is_read_only)(struct _cef_drag_data_t* self);
///
// Returns true (1) if the drag data is a link.
///
@ -120,15 +131,79 @@ typedef struct _cef_drag_data_t {
cef_string_userfree_t (CEF_CALLBACK *get_file_name)(
struct _cef_drag_data_t* self);
///
// Write the contents of the file being dragged out of the web view into
// |writer|. Returns the number of bytes sent to |writer|. If |writer| is NULL
// this function will return the size of the file contents in bytes. Call
// get_file_name() to get a suggested name for the file.
///
size_t (CEF_CALLBACK *get_file_contents)(struct _cef_drag_data_t* self,
struct _cef_stream_writer_t* writer);
///
// Retrieve the list of file names that are being dragged into the browser
// window.
///
int (CEF_CALLBACK *get_file_names)(struct _cef_drag_data_t* self,
cef_string_list_t names);
///
// Set the link URL that is being dragged.
///
void (CEF_CALLBACK *set_link_url)(struct _cef_drag_data_t* self,
const cef_string_t* url);
///
// Set the title associated with the link being dragged.
///
void (CEF_CALLBACK *set_link_title)(struct _cef_drag_data_t* self,
const cef_string_t* title);
///
// Set the metadata associated with the link being dragged.
///
void (CEF_CALLBACK *set_link_metadata)(struct _cef_drag_data_t* self,
const cef_string_t* data);
///
// Set the plain text fragment that is being dragged.
///
void (CEF_CALLBACK *set_fragment_text)(struct _cef_drag_data_t* self,
const cef_string_t* text);
///
// Set the text/html fragment that is being dragged.
///
void (CEF_CALLBACK *set_fragment_html)(struct _cef_drag_data_t* self,
const cef_string_t* html);
///
// Set the base URL that the fragment came from.
///
void (CEF_CALLBACK *set_fragment_base_url)(struct _cef_drag_data_t* self,
const cef_string_t* base_url);
///
// Reset the file contents. You should do this before calling
// cef_browser_host_t::DragTargetDragEnter as the web view does not allow us
// to drag in this kind of data.
///
void (CEF_CALLBACK *reset_file_contents)(struct _cef_drag_data_t* self);
///
// Add a file that is being dragged into the webview.
///
void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self,
const cef_string_t* path, const cef_string_t* display_name);
} cef_drag_data_t;
///
// Create a new cef_drag_data_t object.
///
CEF_EXPORT cef_drag_data_t* cef_drag_data_create();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,163 @@
// Copyright (c) 2014 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_drag_data_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Implement this structure to handle events when window rendering is disabled.
// The functions of this structure will be called on the UI thread.
///
typedef struct _cef_render_handler_t {
///
// Base structure.
///
cef_base_t base;
///
// Called to retrieve the root window rectangle in screen coordinates. Return
// true (1) if the rectangle was provided.
///
int (CEF_CALLBACK *get_root_screen_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the view rectangle which is relative to screen
// coordinates. Return true (1) if the rectangle was provided.
///
int (CEF_CALLBACK *get_view_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true (1) if the screen coordinates were provided.
///
int (CEF_CALLBACK *get_screen_point)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int viewX, int viewY, int* screenX,
int* screenY);
///
// Called to allow the client to fill in the CefScreenInfo object with
// appropriate values. Return true (1) if the |screen_info| structure has been
// modified.
//
// If the screen info rectangle is left NULL the rectangle from GetViewRect
// will be used. If the rectangle is still NULL or invalid popups may not be
// drawn correctly.
///
int (CEF_CALLBACK *get_screen_info)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, struct _cef_screen_info_t* screen_info);
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true (1) and hidden if |show| is false (0).
///
void (CEF_CALLBACK *on_popup_show)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int show);
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size.
///
void (CEF_CALLBACK *on_popup_size)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, const cef_rect_t* rect);
///
// Called when an element should be painted. |type| indicates whether the
// element is the view or the popup widget. |buffer| contains the pixel data
// for the whole image. |dirtyRects| contains the set of rectangles that need
// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes in
// size and represents a BGRA image with an upper-left origin.
///
void (CEF_CALLBACK *on_paint)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_paint_element_type_t type,
size_t dirtyRectsCount, cef_rect_t const* dirtyRects, const void* buffer,
int width, int height);
///
// Called when the browser window's cursor has changed.
///
void (CEF_CALLBACK *on_cursor_change)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_cursor_handle_t cursor);
///
// Called when the user starts dragging content in the web view. Contextual
// information about the dragged content is supplied by |drag_data|. OS APIs
// that run a system message loop may be used within the StartDragging call.
//
// Return false (0) to abort the drag operation. Don't call any of
// cef_browser_host_t::DragSource*Ended* functions after returning false (0).
//
// Return true (1) to handle the drag operation. Call
// cef_browser_host_t::DragSourceEndedAt and DragSourceSystemDragEnded either
// synchronously or asynchronously to inform the web view that the drag
// operation has ended.
///
int (CEF_CALLBACK *start_dragging)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, struct _cef_drag_data_t* drag_data,
cef_drag_operations_mask_t allowed_ops, int x, int y);
///
// Called when the web view wants to update the mouse cursor during a drag &
// drop operation. |operation| describes the allowed operation (none, move,
// copy, link).
///
void (CEF_CALLBACK *update_drag_cursor)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_drag_operations_mask_t operation);
///
// Called when the scroll offset has changed.
///
void (CEF_CALLBACK *on_scroll_offset_changed)(
struct _cef_render_handler_t* self, struct _cef_browser_t* browser);
} cef_render_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_

View File

@ -39,6 +39,7 @@
#pragma once
#include "include/cef_base.h"
#include "include/cef_drag_data.h"
#include "include/cef_frame.h"
#include "include/cef_process_message.h"
#include "include/cef_request_context.h"
@ -218,8 +219,10 @@ class CefRunFileDialogCallback : public virtual CefBase {
/*--cef(source=library)--*/
class CefBrowserHost : public virtual CefBase {
public:
typedef cef_drag_operations_mask_t DragOperationsMask;
typedef cef_file_dialog_mode_t FileDialogMode;
typedef cef_mouse_button_type_t MouseButtonType;
typedef cef_paint_element_type_t PaintElementType;
///
// Create a new browser window using the window parameters specified by
@ -401,6 +404,48 @@ class CefBrowserHost : public virtual CefBase {
/*--cef()--*/
virtual bool IsMouseCursorChangeDisabled() =0;
///
// Returns true if window rendering is disabled.
///
/*--cef()--*/
virtual bool IsWindowRenderingDisabled() =0;
///
// Notify the browser that the widget has been resized. The browser will first
// call CefRenderHandler::GetViewRect to get the new size and then call
// CefRenderHandler::OnPaint asynchronously with the updated regions. This
// method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void WasResized() =0;
///
// Notify the browser that it has been hidden or shown. Layouting and
// CefRenderHandler::OnPaint notification will stop when the browser is
// hidden. This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void WasHidden(bool hidden) =0;
///
// Send a notification to the browser that the screen info has changed. The
// browser will then call CefRenderHandler::GetScreenInfo to update the
// screen information with the new values. This simulates moving the webview
// window from one display to another, or changing the properties of the
// current display. This method is only used when window rendering is
// disabled.
///
/*--cef()--*/
virtual void NotifyScreenInfoChanged() =0;
///
// Invalidate the view. The browser will call CefRenderHandler::OnPaint
// asynchronously. This method is only used when window rendering is
// disabled.
///
/*--cef()--*/
virtual void Invalidate(PaintElementType type) =0;
///
// Send a key event to the browser.
///
@ -428,6 +473,8 @@ class CefBrowserHost : public virtual CefBase {
// Send a mouse wheel event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view. The |deltaX| and |deltaY|
// values represent the movement delta in the X and Y directions respectively.
// In order to scroll inside select popups with window rendering disabled
// CefRenderHandler::GetScreenPoint should be implemented properly.
///
/*--cef()--*/
virtual void SendMouseWheelEvent(const CefMouseEvent& event,
@ -444,6 +491,92 @@ class CefBrowserHost : public virtual CefBase {
///
/*--cef()--*/
virtual void SendCaptureLostEvent() =0;
///
// Get the NSTextInputContext implementation for enabling IME on Mac when
// window rendering is disabled.
///
/*--cef(default_retval=NULL)--*/
virtual CefTextInputContext GetNSTextInputContext() =0;
///
// Handles a keyDown event prior to passing it through the NSTextInputClient
// machinery.
///
/*--cef()--*/
virtual void HandleKeyEventBeforeTextInputClient(CefEventHandle keyEvent) =0;
///
// Performs any additional actions after NSTextInputClient handles the event.
///
/*--cef()--*/
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0;
///
// Call this method when the user drags the mouse into the web view (before
// calling DragTargetDragOver/DragTargetLeave/DragTargetDrop).
// |drag_data| should not contain file contents as this type of data is not
// allowed to be dragged into the web view. File contents can be removed using
// CefDragData::ResetFileContents (for example, if |drag_data| comes from
// CefRenderHandler::StartDragging).
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
const CefMouseEvent& event,
DragOperationsMask allowed_ops) =0;
///
// Call this method each time the mouse is moved across the web view during
// a drag operation (after calling DragTargetDragEnter and before calling
// DragTargetDragLeave/DragTargetDrop).
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragTargetDragOver(const CefMouseEvent& event,
DragOperationsMask allowed_ops) =0;
///
// Call this method when the user drags the mouse out of the web view (after
// calling DragTargetDragEnter).
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragTargetDragLeave() =0;
///
// Call this method when the user completes the drag operation by dropping
// the object onto the web view (after calling DragTargetDragEnter).
// The object being dropped is |drag_data|, given as an argument to
// the previous DragTargetDragEnter call.
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragTargetDrop(const CefMouseEvent& event) =0;
///
// Call this method when the drag operation started by a
// CefRenderHandler::StartDragging call has ended either in a drop or
// by being cancelled. |x| and |y| are mouse coordinates relative to the
// upper-left corner of the view. If the web view is both the drag source
// and the drag target then all DragTarget* methods should be called before
// DragSource* mthods.
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op) =0;
///
// Call this method when the drag operation started by a
// CefRenderHandler::StartDragging call has completed. This method may be
// called immediately without first calling DragSourceEndedAt to cancel a
// drag operation. If the web view is both the drag source and the drag
// target then all DragTarget* methods should be called before DragSource*
// mthods.
// This method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void DragSourceSystemDragEnded() =0;
};
#endif // CEF_INCLUDE_CEF_BROWSER_H_

View File

@ -51,6 +51,7 @@
#include "include/cef_life_span_handler.h"
#include "include/cef_load_handler.h"
#include "include/cef_process_message.h"
#include "include/cef_render_handler.h"
#include "include/cef_request_handler.h"
///
@ -152,6 +153,14 @@ class CefClient : public virtual CefBase {
return NULL;
}
///
// Return the handler for off-screen rendering events.
///
/*--cef()--*/
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() {
return NULL;
}
///
// Return the handler for browser request events.
///

View File

@ -39,6 +39,7 @@
#pragma once
#include "include/cef_base.h"
#include "include/cef_stream.h"
#include <vector>
///
@ -48,6 +49,24 @@
/*--cef(source=library)--*/
class CefDragData : public virtual CefBase {
public:
///
// Create a new CefDragData object.
///
/*--cef()--*/
static CefRefPtr<CefDragData> Create();
///
// Returns a copy of the current object.
///
/*--cef()--*/
virtual CefRefPtr<CefDragData> Clone() =0;
///
// Returns true if this object is read-only.
///
/*--cef()--*/
virtual bool IsReadOnly() =0;
///
// Returns true if the drag data is a link.
///
@ -109,12 +128,71 @@ class CefDragData : public virtual CefBase {
/*--cef()--*/
virtual CefString GetFileName() =0;
///
// Write the contents of the file being dragged out of the web view into
// |writer|. Returns the number of bytes sent to |writer|. If |writer| is
// NULL this method will return the size of the file contents in bytes.
// Call GetFileName() to get a suggested name for the file.
///
/*--cef(optional_param=writer)--*/
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer) =0;
///
// Retrieve the list of file names that are being dragged into the browser
// window.
///
/*--cef()--*/
virtual bool GetFileNames(std::vector<CefString>& names) =0;
///
// Set the link URL that is being dragged.
///
/*--cef(optional_param=url)--*/
virtual void SetLinkURL(const CefString& url) =0;
///
// Set the title associated with the link being dragged.
///
/*--cef(optional_param=title)--*/
virtual void SetLinkTitle(const CefString& title) =0;
///
// Set the metadata associated with the link being dragged.
///
/*--cef(optional_param=data)--*/
virtual void SetLinkMetadata(const CefString& data) =0;
///
// Set the plain text fragment that is being dragged.
///
/*--cef(optional_param=text)--*/
virtual void SetFragmentText(const CefString& text) =0;
///
// Set the text/html fragment that is being dragged.
///
/*--cef(optional_param=html)--*/
virtual void SetFragmentHtml(const CefString& html) =0;
///
// Set the base URL that the fragment came from.
///
/*--cef(optional_param=base_url)--*/
virtual void SetFragmentBaseURL(const CefString& base_url) =0;
///
// Reset the file contents. You should do this before calling
// CefBrowserHost::DragTargetDragEnter as the web view does not allow us to
// drag in this kind of data.
///
/*--cef()--*/
virtual void ResetFileContents() =0;
///
// Add a file that is being dragged into the webview.
///
/*--cef(optional_param=display_name)--*/
virtual void AddFile(const CefString& path, const CefString& display_name) =0;
};
#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_

View File

@ -0,0 +1,170 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_RENDER_HANDLER_H_
#define CEF_INCLUDE_CEF_RENDER_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "include/cef_drag_data.h"
#include <vector>
///
// Implement this interface to handle events when window rendering is disabled.
// The methods of this class will be called on the UI thread.
///
/*--cef(source=client)--*/
class CefRenderHandler : public virtual CefBase {
public:
typedef cef_drag_operations_mask_t DragOperation;
typedef cef_drag_operations_mask_t DragOperationsMask;
typedef cef_paint_element_type_t PaintElementType;
typedef std::vector<CefRect> RectList;
///
// Called to retrieve the root window rectangle in screen coordinates. Return
// true if the rectangle was provided.
///
/*--cef()--*/
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) { return false; }
///
// Called to retrieve the view rectangle which is relative to screen
// coordinates. Return true if the rectangle was provided.
///
/*--cef()--*/
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) =0;
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true if the screen coordinates were provided.
///
/*--cef()--*/
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) { return false; }
///
// Called to allow the client to fill in the CefScreenInfo object with
// appropriate values. Return true if the |screen_info| structure has been
// modified.
//
// If the screen info rectangle is left empty the rectangle from GetViewRect
// will be used. If the rectangle is still empty or invalid popups may not be
// drawn correctly.
///
/*--cef()--*/
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) { return false; }
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true and hidden if |show| is false.
///
/*--cef()--*/
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {}
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size.
///
/*--cef()--*/
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {}
///
// Called when an element should be painted. |type| indicates whether the
// element is the view or the popup widget. |buffer| contains the pixel data
// for the whole image. |dirtyRects| contains the set of rectangles that need
// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes
// in size and represents a BGRA image with an upper-left origin.
///
/*--cef()--*/
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) =0;
///
// Called when the browser window's cursor has changed.
///
/*--cef()--*/
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {}
///
// Called when the user starts dragging content in the web view. Contextual
// information about the dragged content is supplied by |drag_data|.
// OS APIs that run a system message loop may be used within the
// StartDragging call.
//
// Return false to abort the drag operation. Don't call any of
// CefBrowserHost::DragSource*Ended* methods after returning false.
//
// Return true to handle the drag operation. Call
// CefBrowserHost::DragSourceEndedAt and DragSourceSystemDragEnded either
// synchronously or asynchronously to inform the web view that the drag
// operation has ended.
///
/*--cef()--*/
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
DragOperationsMask allowed_ops,
int x, int y) { return false; }
///
// Called when the web view wants to update the mouse cursor during a
// drag & drop operation. |operation| describes the allowed operation
// (none, move, copy, link).
///
/*--cef()--*/
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
DragOperation operation) {}
///
// Called when the scroll offset has changed.
///
/*--cef()--*/
virtual void OnScrollOffsetChanged(CefRefPtr<CefBrowser> browser) {}
};
#endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_

View File

@ -72,6 +72,7 @@ class CefCriticalSection {
#define CefCursorHandle cef_cursor_handle_t
#define CefEventHandle cef_event_handle_t
#define CefWindowHandle cef_window_handle_t
#define CefTextInputContext cef_text_input_context_t
struct CefMainArgsTraits {
typedef cef_main_args_t struct_type;
@ -113,6 +114,8 @@ struct CefWindowInfoTraits {
target->width = src->width;
target->height = src->height;
target->parent_window = src->parent_window;
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
target->transparent_painting_enabled = src->transparent_painting_enabled;
target->window = src->window;
}
};
@ -137,6 +140,24 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
width = windowRect.width;
height = windowRect.height;
}
///
// Create the browser using windowless (off-screen) rendering. No window
// will be created for the browser and all rendering will occur via the
// CefRenderHandler interface. The |parent| value will be used to identify
// monitor info and to act as the parent window for dialogs, context menus,
// etc. If |parent| is not provided then the main screen monitor will be used
// and some functionality that requires a parent window may not function
// correctly. If |transparent| is true a transparent background color will be
// used (RGBA=0x00000000). If |transparent| is false the background will be
// white and opaque. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
void SetAsWindowless(CefWindowHandle parent, bool transparent) {
windowless_rendering_enabled = true;
parent_window = parent;
transparent_painting_enabled = transparent;
}
};
#endif // OS_LINUX

View File

@ -72,6 +72,7 @@ class CefCriticalSection {
#define CefCursorHandle cef_cursor_handle_t
#define CefEventHandle cef_event_handle_t
#define CefWindowHandle cef_window_handle_t
#define CefTextInputContext cef_text_input_context_t
struct CefMainArgsTraits {
typedef cef_main_args_t struct_type;
@ -119,6 +120,8 @@ struct CefWindowInfoTraits {
target->height = src->height;
target->hidden = src->hidden;
target->parent_view = src->parent_view;
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
target->transparent_painting_enabled = src->transparent_painting_enabled;
target->view = src->view;
}
};
@ -144,6 +147,24 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
this->height = height;
hidden = false;
}
///
// Create the browser using windowless (off-screen) rendering. No view
// will be created for the browser and all rendering will occur via the
// CefRenderHandler interface. The |parent| value will be used to identify
// monitor info and to act as the parent view for dialogs, context menus,
// etc. If |parent| is not provided then the main screen monitor will be used
// and some functionality that requires a parent view may not function
// correctly. If |transparent| is true a transparent background color will be
// used (RGBA=0x00000000). If |transparent| is false the background will be
// white and opaque. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
void SetAsWindowless(CefWindowHandle parent, bool transparent) {
windowless_rendering_enabled = true;
parent_view = parent;
transparent_painting_enabled = transparent;
}
};
#endif // OS_MACOSX

View File

@ -223,6 +223,13 @@ typedef struct _cef_settings_t {
///
int multi_threaded_message_loop;
///
// Set to true (1) to enable windowless (off-screen) rendering support. Do not
// enable this value if the application does not use windowless rendering as
// it may reduce rendering performance on some systems.
///
int windowless_rendering_enabled;
///
// Set to true (1) to disable configuration of browser process features using
// standard CEF and Chromium command-line arguments. Configuration can still
@ -393,6 +400,14 @@ typedef struct _cef_browser_settings_t {
///
size_t size;
///
// The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint
// will be called for a windowless browser. The actual fps may be lower if
// the browser cannot generate frames at the requested rate. The minimum
// value is 1 and the maximum value is 60 (default 30).
///
int windowless_frame_rate;
// The below values map to WebPreferences settings.
///
@ -1306,6 +1321,14 @@ typedef struct _cef_mouse_event_t {
uint32 modifiers;
} cef_mouse_event_t;
///
// Paint element types.
///
typedef enum {
PET_VIEW = 0,
PET_POPUP,
} cef_paint_element_type_t;
///
// Supported event bit flags.
///

View File

@ -60,6 +60,7 @@ extern "C" {
// thread-safe and must only be accessed on the browser process UI thread.
///
CEF_EXPORT XDisplay* cef_get_xdisplay();
#define cef_text_input_context_t void*
///
// Structure representing CefExecuteProcess arguments.
@ -83,6 +84,26 @@ typedef struct _cef_window_info_t {
///
cef_window_handle_t parent_window;
///
// Set to true (1) to create the browser using windowless (off-screen)
// rendering. No window will be created for the browser and all rendering will
// occur via the CefRenderHandler interface. The |parent_window| value will be
// used to identify monitor info and to act as the parent window for dialogs,
// context menus, etc. If |parent_window| is not provided then the main screen
// monitor will be used and some functionality that requires a parent window
// may not function correctly. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
int windowless_rendering_enabled;
///
// Set to true (1) to enable transparent painting in combination with
// windowless rendering. When this value is true a transparent background
// color will be used (RGBA=0x00000000). When this value is false the
// background will be white and opaque.
///
int transparent_painting_enabled;
///
// Pointer for the new browser window. Only used with windowed rendering.
///

View File

@ -43,18 +43,22 @@
@class NSCursor;
@class NSEvent;
@class NSView;
@class NSTextInputContext;
#else
class NSCursor;
class NSEvent;
struct NSView;
class NSTextInputContext;
#endif
#define cef_cursor_handle_t NSCursor*
#define cef_event_handle_t NSEvent*
#define cef_window_handle_t NSView*
#define cef_text_input_context_t NSTextInputContext*
#else
#define cef_cursor_handle_t void*
#define cef_event_handle_t void*
#define cef_window_handle_t void*
#define cef_text_input_context_t void*
#endif
#define kNullCursorHandle NULL
@ -93,6 +97,26 @@ typedef struct _cef_window_info_t {
///
cef_window_handle_t parent_view;
///
// Set to true (1) to create the browser using windowless (off-screen)
// rendering. No view will be created for the browser and all rendering will
// occur via the CefRenderHandler interface. The |parent_view| value will be
// used to identify monitor info and to act as the parent view for dialogs,
// context menus, etc. If |parent_view| is not provided then the main screen
// monitor will be used and some functionality that requires a parent view
// may not function correctly. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
int windowless_rendering_enabled;
///
// Set to true (1) to enable transparent painting in combination with
// windowless rendering. When this value is true a transparent background
// color will be used (RGBA=0x00000000). When this value is false the
// background will be white and opaque.
///
int transparent_painting_enabled;
///
// NSView pointer for the new browser view. Only used with windowed rendering.
///

View File

@ -42,6 +42,7 @@
#define cef_cursor_handle_t HCURSOR
#define cef_event_handle_t MSG*
#define cef_window_handle_t HWND
#define cef_text_input_context_t void*
#define kNullCursorHandle NULL
#define kNullEventHandle NULL
@ -73,6 +74,26 @@ typedef struct _cef_window_info_t {
cef_window_handle_t parent_window;
HMENU menu;
///
// Set to true (1) to create the browser using windowless (off-screen)
// rendering. No window will be created for the browser and all rendering will
// occur via the CefRenderHandler interface. The |parent_window| value will be
// used to identify monitor info and to act as the parent window for dialogs,
// context menus, etc. If |parent_window| is not provided then the main screen
// monitor will be used and some functionality that requires a parent window
// may not function correctly. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
int windowless_rendering_enabled;
///
// Set to true (1) to enable transparent painting in combination with
// windowless rendering. When this value is true a transparent background
// color will be used (RGBA=0x00000000). When this value is false the
// background will be white and opaque.
///
int transparent_painting_enabled;
///
// Handle for the new browser window. Only used with windowed rendering.
///

View File

@ -349,6 +349,7 @@ struct CefSettingsTraits {
src->browser_subprocess_path.length,
&target->browser_subprocess_path, copy);
target->multi_threaded_message_loop = src->multi_threaded_message_loop;
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
target->command_line_args_disabled = src->command_line_args_disabled;
cef_string_set(src->cache_path.str, src->cache_path.length,
@ -405,6 +406,8 @@ struct CefBrowserSettingsTraits {
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
target->windowless_frame_rate = src->windowless_frame_rate;
cef_string_set(src->standard_font_family.str,
src->standard_font_family.length, &target->standard_font_family, copy);
cef_string_set(src->fixed_font_family.str, src->fixed_font_family.length,

View File

@ -71,6 +71,7 @@ class CefCriticalSection {
#define CefCursorHandle cef_cursor_handle_t
#define CefEventHandle cef_event_handle_t
#define CefWindowHandle cef_window_handle_t
#define CefTextInputContext cef_text_input_context_t
struct CefMainArgsTraits {
typedef cef_main_args_t struct_type;
@ -118,6 +119,8 @@ struct CefWindowInfoTraits {
target->height = src->height;
target->parent_window = src->parent_window;
target->menu = src->menu;
target->transparent_painting_enabled = src->transparent_painting_enabled;
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
target->window = src->window;
}
};
@ -160,6 +163,24 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
cef_string_copy(windowName.c_str(), windowName.length(), &window_name);
}
///
// Create the browser using windowless (off-screen) rendering. No window
// will be created for the browser and all rendering will occur via the
// CefRenderHandler interface. The |parent| value will be used to identify
// monitor info and to act as the parent window for dialogs, context menus,
// etc. If |parent| is not provided then the main screen monitor will be used
// and some functionality that requires a parent window may not function
// correctly. If |transparent| is true a transparent background color will be
// used (RGBA=0x00000000). If |transparent| is false the background will be
// white and opaque. In order to create windowless browsers the
// CefSettings.windowless_rendering_enabled value must be set to true.
///
void SetAsWindowless(CefWindowHandle parent, bool transparent) {
windowless_rendering_enabled = TRUE;
parent_window = parent;
transparent_painting_enabled = transparent;
}
};
#endif // OS_WIN

View File

@ -19,8 +19,10 @@
#include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/navigate_params.h"
#include "libcef/browser/printing/print_view_manager.h"
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/scheme_handler.h"
#include "libcef/browser/web_contents_view_osr.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/cef_switches.h"
@ -33,6 +35,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/view_messages.h"
#include "content/public/browser/download_manager.h"
@ -284,6 +287,18 @@ bool CefBrowserHost::CreateBrowser(
return false;
}
// Verify windowless rendering requirements.
if (windowInfo.windowless_rendering_enabled) {
if (!client->GetRenderHandler().get()) {
NOTREACHED() << "CefRenderHandler implementation is required";
return false;
}
if (!content::IsDelegatedRendererEnabled()) {
NOTREACHED() << "Delegated renderer must be enabled";
return false;
}
}
// Create the browser on the UI thread.
CreateBrowserHelper* helper =
new CreateBrowserHelper(windowInfo, client, url, settings,
@ -337,8 +352,22 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
CefWindowHandle opener,
bool is_popup,
CefRefPtr<CefRequestContext> request_context) {
// Verify windowless rendering requirements.
if (windowInfo.windowless_rendering_enabled) {
if (!client->GetRenderHandler().get()) {
NOTREACHED() << "CefRenderHandler implementation is required";
return NULL;
}
if (!content::IsDelegatedRendererEnabled()) {
NOTREACHED() << "Delegated renderer must be enabled";
return NULL;
}
}
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->CreateBrowserInfo(is_popup);
info->set_windowless(windowInfo.windowless_rendering_enabled ? true : false);
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::CreateInternal(windowInfo, settings, client, NULL,
info, opener, request_context);
@ -377,15 +406,24 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
content::WebContents::CreateParams create_params(
browser_context);
if (window_info.windowless_rendering_enabled) {
// Use the OSR view instead of the default view.
CefWebContentsViewOSR* view_or = new CefWebContentsViewOSR(
web_contents,
CefContentBrowserClient::Get()->GetWebContentsViewDelegate(
web_contents));
create_params.view = view_or;
create_params.delegate_view = view_or;
}
web_contents = content::WebContents::Create(create_params);
}
CefRefPtr<CefBrowserHostImpl> browser =
new CefBrowserHostImpl(window_info, settings, client, web_contents,
browser_info, opener);
if (!browser->PlatformCreateWindow()) {
if (!browser->IsWindowless() && !browser->PlatformCreateWindow())
return NULL;
}
#if defined(OS_LINUX) || defined(OS_ANDROID)
content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
@ -606,7 +644,8 @@ void CefBrowserHostImpl::CloseBrowser(bool force_close) {
if (CEF_CURRENTLY_ON_UIT()) {
// Exit early if a close attempt is already pending and this method is
// called again from somewhere other than WindowDestroyed().
if (destruction_state_ >= DESTRUCTION_STATE_PENDING && !window_destroyed_) {
if (destruction_state_ >= DESTRUCTION_STATE_PENDING &&
(IsWindowless() || !window_destroyed_)) {
if (force_close && destruction_state_ == DESTRUCTION_STATE_PENDING) {
// Upgrade the destruction state.
destruction_state_ = DESTRUCTION_STATE_ACCEPTED;
@ -856,6 +895,101 @@ bool CefBrowserHostImpl::IsMouseCursorChangeDisabled() {
return mouse_cursor_change_disabled_;
}
bool CefBrowserHostImpl::IsWindowRenderingDisabled() {
return IsWindowless();
}
void CefBrowserHostImpl::WasResized() {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::Bind(&CefBrowserHostImpl::WasResized, this));
return;
}
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->WasResized();
}
void CefBrowserHostImpl::WasHidden(bool hidden) {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHost::WasHidden, this, hidden));
return;
}
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view) {
if (hidden)
view->WasHidden();
else
view->WasShown();
}
}
void CefBrowserHostImpl::NotifyScreenInfoChanged() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::NotifyScreenInfoChanged, this));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->OnScreenInfoChanged();
}
void CefBrowserHostImpl::Invalidate(PaintElementType type) {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::Invalidate, this, type));
return;
}
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->Invalidate(type);
}
void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
@ -866,9 +1000,20 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
content::NativeWebKeyboardEvent web_event;
PlatformTranslateKeyEvent(web_event, event);
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardKeyboardEvent(web_event);
if (!IsWindowless()) {
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardKeyboardEvent(web_event);
} else {
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->SendKeyEvent(web_event);
}
}
void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event,
@ -913,9 +1058,20 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
blink::WebMouseWheelEvent web_event;
PlatformTranslateWheelEvent(web_event, event, deltaX, deltaY);
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardWheelEvent(web_event);
if (!IsWindowless()) {
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardWheelEvent(web_event);
} else {
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->SendMouseWheelEvent(web_event);
}
}
int CefBrowserHostImpl::TranslateModifiers(uint32 cef_modifiers) {
@ -949,9 +1105,20 @@ int CefBrowserHostImpl::TranslateModifiers(uint32 cef_modifiers) {
}
void CefBrowserHostImpl::SendMouseEvent(const blink::WebMouseEvent& event) {
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardMouseEvent(event);
if (!IsWindowless()) {
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->ForwardMouseEvent(event);
} else {
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->SendMouseEvent(event);
}
}
void CefBrowserHostImpl::SendFocusEvent(bool setFocus) {
@ -961,19 +1128,17 @@ void CefBrowserHostImpl::SendFocusEvent(bool setFocus) {
return;
}
if (!web_contents())
return;
content::RenderWidgetHostImpl* widget =
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
if (!widget)
return;
if (setFocus) {
widget->GotFocus();
widget->SetActive(true);
if (!IsWindowless()) {
SetFocus(setFocus);
} else {
widget->SetActive(false);
widget->Blur();
if (!web_contents())
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents()->GetRenderViewHost()->GetView());
if (view)
view->SendFocusEvent(setFocus);
}
}
@ -989,9 +1154,8 @@ void CefBrowserHostImpl::SendCaptureLostEvent() {
content::RenderWidgetHostImpl* widget =
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
if (!widget)
return;
widget->LostCapture();
if (widget)
widget->LostCapture();
}
// CefBrowser methods.
@ -1180,6 +1344,14 @@ bool CefBrowserHostImpl::SendProcessMessage(
// CefBrowserHostImpl public methods.
// -----------------------------------------------------------------------------
bool CefBrowserHostImpl::IsWindowless() const {
return window_info_.windowless_rendering_enabled ? true : false;
}
bool CefBrowserHostImpl::IsTransparent() const {
return window_info_.transparent_painting_enabled ? true : false;
}
void CefBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT();
DCHECK(!window_destroyed_);
@ -1234,6 +1406,16 @@ gfx::NativeView CefBrowserHostImpl::GetContentView() const {
#endif
}
void CefBrowserHostImpl::CancelContextMenu() {
#if defined(OS_LINUX) && defined(USE_AURA)
CEF_REQUIRE_UIT();
// Special case for dismissing views-based context menus on Linux Aura
// when using windowless rendering.
if (IsWindowless() && menu_creator_)
menu_creator_->CancelContextMenu();
#endif
}
content::WebContents* CefBrowserHostImpl::GetWebContents() const {
CEF_REQUIRE_UIT();
return web_contents_.get();
@ -1533,6 +1715,208 @@ void CefBrowserHostImpl::RunFileChooser(
callback));
}
#if !defined(OS_MACOSX)
CefTextInputContext CefBrowserHostImpl::GetNSTextInputContext() {
NOTREACHED();
return NULL;
}
void CefBrowserHostImpl::HandleKeyEventBeforeTextInputClient(
CefEventHandle keyEvent) {
NOTREACHED();
}
void CefBrowserHostImpl::HandleKeyEventAfterTextInputClient(
CefEventHandle keyEvent) {
NOTREACHED();
}
#endif // !defined(OS_MACOSX)
void CefBrowserHostImpl::DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
const CefMouseEvent& event,
CefBrowserHost::DragOperationsMask allowed_ops) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragTargetDragEnter, this, drag_data,
event, allowed_ops));
return;
}
if (!drag_data.get()) {
NOTREACHED();
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
int screenX, screenY;
if (!client_->GetRenderHandler()->GetScreenPoint(
this, event.x, event.y, screenX, screenY)) {
screenX = event.x;
screenY = event.y;
}
CefDragDataImpl* data_impl = static_cast<CefDragDataImpl*>(drag_data.get());
CefDragDataImpl::AutoLock lock_scope(data_impl);
const content::DropData& drop_data = data_impl->drop_data();
gfx::Point client_pt(event.x, event.y);
gfx::Point screen_pt(screenX, screenY);
blink::WebDragOperationsMask ops =
static_cast<blink::WebDragOperationsMask>(allowed_ops);
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
rvh->DragTargetDragEnter(drop_data, client_pt, screen_pt, ops, modifiers);
}
void CefBrowserHostImpl::DragTargetDragOver(const CefMouseEvent& event,
CefBrowserHost::DragOperationsMask allowed_ops) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragTargetDragOver, this, event,
allowed_ops));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
int screenX, screenY;
if (!client_->GetRenderHandler()->GetScreenPoint(
this, event.x, event.y, screenX, screenY)) {
screenX = event.x;
screenY = event.y;
}
gfx::Point client_pt(event.x, event.y);
gfx::Point screen_pt(screenX, screenY);
blink::WebDragOperationsMask ops =
static_cast<blink::WebDragOperationsMask>(allowed_ops);
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
rvh->DragTargetDragOver(client_pt, screen_pt, ops, modifiers);
}
void CefBrowserHostImpl::DragTargetDragLeave() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragTargetDragLeave, this));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
rvh->DragTargetDragLeave();
}
void CefBrowserHostImpl::DragTargetDrop(const CefMouseEvent& event) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragTargetDrop, this, event));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
int screenX, screenY;
if (!client_->GetRenderHandler()->GetScreenPoint(
this, event.x, event.y, screenX, screenY)) {
screenX = event.x;
screenY = event.y;
}
gfx::Point client_pt(event.x, event.y);
gfx::Point screen_pt(screenX, screenY);
int modifiers = CefBrowserHostImpl::TranslateModifiers(event.modifiers);
rvh->DragTargetDrop(client_pt, screen_pt, modifiers);
}
void CefBrowserHostImpl::DragSourceSystemDragEnded() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragSourceSystemDragEnded, this));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
rvh->DragSourceSystemDragEnded();
}
void CefBrowserHostImpl::DragSourceEndedAt(
int x, int y, CefBrowserHost::DragOperationsMask op) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::DragSourceEndedAt, this, x, y, op));
return;
}
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
content::RenderViewHost* rvh =
web_contents() ? web_contents()->GetRenderViewHost() : NULL;
if (!rvh)
return;
int screenX, screenY;
if (!client_->GetRenderHandler()->GetScreenPoint(
this, x, y, screenX, screenY)) {
screenX = x;
screenY = y;
}
blink::WebDragOperation drag_op = static_cast<blink::WebDragOperation>(op);
rvh->DragSourceEndedAt(x, y, screenX, screenY, drag_op);
}
// content::WebContentsDelegate methods.
// -----------------------------------------------------------------------------
@ -1579,7 +1963,7 @@ void CefBrowserHostImpl::CloseContents(content::WebContents* source) {
// If this method is called in response to something other than
// WindowDestroyed() ask the user if the browser should close.
if (client_.get() && !window_destroyed_) {
if (client_.get() && (IsWindowless() || !window_destroyed_)) {
CefRefPtr<CefLifeSpanHandler> handler =
client_->GetLifeSpanHandler();
if (handler.get()) {
@ -1591,7 +1975,7 @@ void CefBrowserHostImpl::CloseContents(content::WebContents* source) {
if (destruction_state_ != DESTRUCTION_STATE_ACCEPTED)
destruction_state_ = DESTRUCTION_STATE_ACCEPTED;
if (!window_destroyed_) {
if (!IsWindowless() && !window_destroyed_) {
// A window exists so try to close it using the platform method. Will
// result in a call to WindowDestroyed() if/when the window is destroyed
// via the platform window destruction mechanism.
@ -1603,8 +1987,10 @@ void CefBrowserHostImpl::CloseContents(content::WebContents* source) {
// No window exists. Destroy the browser immediately.
DestroyBrowser();
// Release the reference added in PlatformCreateWindow().
Release();
if (!IsWindowless()) {
// Release the reference added in PlatformCreateWindow().
Release();
}
}
} else if (destruction_state_ != DESTRUCTION_STATE_NONE) {
destruction_state_ = DESTRUCTION_STATE_NONE;
@ -1722,15 +2108,47 @@ bool CefBrowserHostImpl::CanDragEnter(
blink::WebDragOperationsMask mask) {
CefRefPtr<CefDragHandler> handler = client_->GetDragHandler();
if (handler.get()) {
CefRefPtr<CefDragData> drag_data(new CefDragDataImpl(data));
if (handler->OnDragEnter(this, drag_data,
static_cast<CefDragHandler::DragOperationsMask>(mask))) {
CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(data));
drag_data->SetReadOnly(true);
if (handler->OnDragEnter(
this,
drag_data.get(),
static_cast<CefDragHandler::DragOperationsMask>(mask))) {
return false;
}
}
return true;
}
bool CefBrowserHostImpl::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace,
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view) {
// In cases where the navigation will occur in a new render process the
// |route_id| value will be MSG_ROUTING_NONE here (because the existing
// renderer will not be able to communicate with the new renderer) and
// OpenURLFromTab will be called after WebContentsCreated.
base::AutoLock lock_scope(pending_popup_info_lock_);
DCHECK(pending_popup_info_.get());
if (pending_popup_info_->window_info.windowless_rendering_enabled) {
// Use the OSR view instead of the default view.
CefWebContentsViewOSR* view_or = new CefWebContentsViewOSR(
web_contents,
CefContentBrowserClient::Get()->GetWebContentsViewDelegate(
web_contents));
*view = view_or;
*delegate_view = view_or;
}
return true;
}
void CefBrowserHostImpl::WebContentsCreated(
content::WebContents* source_contents,
int opener_render_frame_id,
@ -1870,8 +2288,9 @@ void CefBrowserHostImpl::RenderFrameCreated(
void CefBrowserHostImpl::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
browser_info_->remove_render_frame_id(render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRoutingID());
browser_info_->remove_render_frame_id(
render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRoutingID());
}
void CefBrowserHostImpl::RenderViewCreated(
@ -2208,6 +2627,14 @@ CefBrowserHostImpl::CefBrowserHostImpl(
// Make sure RenderViewCreated is called at least one time.
RenderViewCreated(web_contents->GetRenderViewHost());
if (IsWindowless()) {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents->GetRenderViewHost()->GetView());
if (view)
view->set_browser_impl(this);
}
}
CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(

View File

@ -35,6 +35,10 @@
#include "ui/base/cursor/cursor.h"
#endif
#if defined(USE_X11)
#include "ui/base/x/x11_util.h"
#endif
namespace content {
struct NativeWebKeyboardEvent;
}
@ -152,6 +156,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
virtual void CloseDevTools() OVERRIDE;
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
virtual bool IsWindowRenderingDisabled() OVERRIDE;
virtual void WasResized() OVERRIDE;
virtual void WasHidden(bool hidden) OVERRIDE;
virtual void NotifyScreenInfoChanged() OVERRIDE;
virtual void Invalidate(PaintElementType type) OVERRIDE;
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
virtual void SendMouseClickEvent(const CefMouseEvent& event,
MouseButtonType type,
@ -162,6 +171,20 @@ class CefBrowserHostImpl : public CefBrowserHost,
int deltaX, int deltaY) OVERRIDE;
virtual void SendFocusEvent(bool setFocus) OVERRIDE;
virtual void SendCaptureLostEvent() OVERRIDE;
virtual CefTextInputContext GetNSTextInputContext() OVERRIDE;
virtual void HandleKeyEventBeforeTextInputClient(CefEventHandle keyEvent)
OVERRIDE;
virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent)
OVERRIDE;
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
const CefMouseEvent& event,
DragOperationsMask allowed_ops);
virtual void DragTargetDragOver(const CefMouseEvent& event,
DragOperationsMask allowed_ops);
virtual void DragTargetDragLeave();
virtual void DragTargetDrop(const CefMouseEvent& event);
virtual void DragSourceSystemDragEnded();
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op);
// CefBrowser methods.
virtual CefRefPtr<CefBrowserHost> GetHost() OVERRIDE;
@ -188,6 +211,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE;
// Returns true if windowless rendering is enabled.
bool IsWindowless() const;
// Returns true if transparent painting is enabled.
bool IsTransparent() const;
// Called when the OS window hosting the browser is destroyed.
void WindowDestroyed();
@ -195,6 +223,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// native browser window is not longer processing messages.
void DestroyBrowser();
// Cancel display of the context menu, if any.
void CancelContextMenu();
// Returns the native view for the WebContents.
gfx::NativeView GetContentView() const;
@ -340,6 +371,16 @@ class CefBrowserHostImpl : public CefBrowserHost,
content::WebContents* source,
const content::DropData& data,
blink::WebDragOperationsMask operations_allowed) OVERRIDE;
virtual bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace,
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view) OVERRIDE;
virtual void WebContentsCreated(content::WebContents* source_contents,
int opener_render_frame_id,
const base::string16& frame_name,
@ -608,6 +649,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
#endif // defined(USE_AURA)
#if defined(USE_X11)
CefWindowX11* window_x11_;
scoped_ptr<ui::XScopedCursor> invisible_cursor_;
#endif // defined(USE_X11)
IMPLEMENT_REFCOUNTING(CefBrowserHostImpl);

View File

@ -6,6 +6,7 @@
#include "libcef/browser/browser_host_impl.h"
#include <sys/sysinfo.h>
#include <X11/cursorfont.h>
#include "libcef/browser/context.h"
#include "libcef/browser/window_delegate_view.h"
@ -29,8 +30,120 @@ long GetSystemUptime() {
return 0;
}
// Based on ui/base/cursor/cursor_loader_x11.cc.
using blink::WebCursorInfo;
int ToCursorID(WebCursorInfo::Type type) {
switch (type) {
case WebCursorInfo::TypePointer:
return XC_left_ptr;
case WebCursorInfo::TypeCross:
return XC_crosshair;
case WebCursorInfo::TypeHand:
return XC_hand2;
case WebCursorInfo::TypeIBeam:
return XC_xterm;
case WebCursorInfo::TypeWait:
return XC_watch;
case WebCursorInfo::TypeHelp:
return XC_question_arrow;
case WebCursorInfo::TypeEastResize:
return XC_right_side;
case WebCursorInfo::TypeNorthResize:
return XC_top_side;
case WebCursorInfo::TypeNorthEastResize:
return XC_top_right_corner;
case WebCursorInfo::TypeNorthWestResize:
return XC_top_left_corner;
case WebCursorInfo::TypeSouthResize:
return XC_bottom_side;
case WebCursorInfo::TypeSouthEastResize:
return XC_bottom_right_corner;
case WebCursorInfo::TypeSouthWestResize:
return XC_bottom_left_corner;
case WebCursorInfo::TypeWestResize:
return XC_left_side;
case WebCursorInfo::TypeNorthSouthResize:
return XC_sb_v_double_arrow;
case WebCursorInfo::TypeEastWestResize:
return XC_sb_h_double_arrow;
case WebCursorInfo::TypeNorthEastSouthWestResize:
return XC_left_ptr;
case WebCursorInfo::TypeNorthWestSouthEastResize:
return XC_left_ptr;
case WebCursorInfo::TypeColumnResize:
return XC_sb_h_double_arrow;
case WebCursorInfo::TypeRowResize:
return XC_sb_v_double_arrow;
case WebCursorInfo::TypeMiddlePanning:
return XC_fleur;
case WebCursorInfo::TypeEastPanning:
return XC_sb_right_arrow;
case WebCursorInfo::TypeNorthPanning:
return XC_sb_up_arrow;
case WebCursorInfo::TypeNorthEastPanning:
return XC_top_right_corner;
case WebCursorInfo::TypeNorthWestPanning:
return XC_top_left_corner;
case WebCursorInfo::TypeSouthPanning:
return XC_sb_down_arrow;
case WebCursorInfo::TypeSouthEastPanning:
return XC_bottom_right_corner;
case WebCursorInfo::TypeSouthWestPanning:
return XC_bottom_left_corner;
case WebCursorInfo::TypeWestPanning:
return XC_sb_left_arrow;
case WebCursorInfo::TypeMove:
return XC_fleur;
case WebCursorInfo::TypeVerticalText:
return XC_left_ptr;
case WebCursorInfo::TypeCell:
return XC_left_ptr;
case WebCursorInfo::TypeContextMenu:
return XC_left_ptr;
case WebCursorInfo::TypeAlias:
return XC_left_ptr;
case WebCursorInfo::TypeProgress:
return XC_left_ptr;
case WebCursorInfo::TypeNoDrop:
return XC_left_ptr;
case WebCursorInfo::TypeCopy:
return XC_left_ptr;
case WebCursorInfo::TypeNotAllowed:
return XC_left_ptr;
case WebCursorInfo::TypeZoomIn:
return XC_left_ptr;
case WebCursorInfo::TypeZoomOut:
return XC_left_ptr;
case WebCursorInfo::TypeGrab:
return XC_left_ptr;
case WebCursorInfo::TypeGrabbing:
return XC_left_ptr;
case WebCursorInfo::TypeCustom:
case WebCursorInfo::TypeNone:
break;
}
NOTREACHED();
return 0;
}
} // namespace
ui::PlatformCursor CefBrowserHostImpl::GetPlatformCursor(
blink::WebCursorInfo::Type type) {
if (type == WebCursorInfo::TypeNone) {
if (!invisible_cursor_) {
invisible_cursor_.reset(
new ui::XScopedCursor(ui::CreateInvisibleCursor(),
gfx::GetXDisplay()));
}
return invisible_cursor_->get();
} else {
return ui::GetXCursor(ToCursorID(type));
}
}
bool CefBrowserHostImpl::PlatformCreateWindow() {
DCHECK(!window_x11_);
DCHECK(!window_widget_);
@ -119,7 +232,7 @@ void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window;
return IsWindowless() ? window_info_.parent_window : window_info_.window;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
@ -175,7 +288,32 @@ void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) {
NOTIMPLEMENTED();
result.timeStampSeconds = GetSystemUptime();
result.windowsKeyCode = key_event.windows_key_code;
result.nativeKeyCode = key_event.native_key_code;
result.isSystemKey = key_event.is_system_key ? 1 : 0;
switch (key_event.type) {
case KEYEVENT_RAWKEYDOWN:
case KEYEVENT_KEYDOWN:
result.type = blink::WebInputEvent::RawKeyDown;
break;
case KEYEVENT_KEYUP:
result.type = blink::WebInputEvent::KeyUp;
break;
case KEYEVENT_CHAR:
result.type = blink::WebInputEvent::Char;
break;
default:
NOTREACHED();
}
result.text[0] = key_event.character;
result.unmodifiedText[0] = key_event.unmodified_character;
result.setKeyIdentifierFromWindowsKeyCode();
result.modifiers |= TranslateModifiers(key_event.modifiers);
}
void CefBrowserHostImpl::PlatformTranslateClickEvent(
@ -274,7 +412,14 @@ void CefBrowserHostImpl::PlatformTranslateMouseEvent(
result.globalX = result.x;
result.globalY = result.y;
// TODO(linux): Convert global{X,Y} to screen coordinates.
if (IsWindowless()) {
GetClient()->GetRenderHandler()->GetScreenPoint(
GetBrowser(),
result.x, result.y,
result.globalX, result.globalY);
} else {
// TODO(linux): Convert global{X,Y} to screen coordinates.
}
// modifiers
result.modifiers |= TranslateModifiers(mouse_event.modifiers);

View File

@ -8,6 +8,8 @@
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h>
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/text_input_client_osr_mac.h"
#include "libcef/browser/thread_util.h"
#include "base/file_util.h"
@ -286,6 +288,59 @@ bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
return false;
}
CefTextInputContext CefBrowserHostImpl::GetNSTextInputContext() {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return NULL;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "Called on invalid thread";
return NULL;
}
CefRenderWidgetHostViewOSR* rwhv = static_cast<CefRenderWidgetHostViewOSR*>(
GetWebContents()->GetRenderWidgetHostView());
return rwhv->GetNSTextInputContext();
}
void CefBrowserHostImpl::HandleKeyEventBeforeTextInputClient(
CefEventHandle keyEvent) {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "Called on invalid thread";
return;
}
CefRenderWidgetHostViewOSR* rwhv = static_cast<CefRenderWidgetHostViewOSR*>(
GetWebContents()->GetRenderWidgetHostView());
rwhv->HandleKeyEventBeforeTextInputClient(keyEvent);
}
void CefBrowserHostImpl::HandleKeyEventAfterTextInputClient(
CefEventHandle keyEvent) {
if (!IsWindowless()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
NOTREACHED() << "Called on invalid thread";
return;
}
CefRenderWidgetHostViewOSR* rwhv = static_cast<CefRenderWidgetHostViewOSR*>(
GetWebContents()->GetRenderWidgetHostView());
rwhv->HandleKeyEventAfterTextInputClient(keyEvent);
}
bool CefBrowserHostImpl::PlatformCreateWindow() {
base::mac::ScopedNSAutoreleasePool autorelease_pool;
@ -382,7 +437,7 @@ void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
web_contents_->GetRenderWidgetHostView()) {
view->SetActive(focus);
if (focus) {
if (focus && !IsWindowless()) {
// Give keyboard focus to the native view.
NSView* view = web_contents_->GetContentNativeView();
DCHECK([view canBecomeKeyView]);
@ -402,7 +457,7 @@ void CefBrowserHostImpl::PlatformSetWindowVisibility(bool visible) {
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.view;
return IsWindowless() ? window_info_.parent_view : window_info_.view;
}
void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
@ -616,14 +671,21 @@ void CefBrowserHostImpl::PlatformTranslateMouseEvent(
result.globalX = result.x;
result.globalY = result.y;
NSView* view = window_info_.parent_view;
if (view) {
NSRect bounds = [view bounds];
NSPoint view_pt = {result.x, bounds.size.height - result.y};
NSPoint window_pt = [view convertPoint:view_pt toView:nil];
NSPoint screen_pt = [[view window] convertBaseToScreen:window_pt];
result.globalX = screen_pt.x;
result.globalY = screen_pt.y;
if (IsWindowless()) {
GetClient()->GetRenderHandler()->GetScreenPoint(
GetBrowser(),
result.x, result.y,
result.globalX, result.globalY);
} else {
NSView* view = window_info_.parent_view;
if (view) {
NSRect bounds = [view bounds];
NSPoint view_pt = {result.x, bounds.size.height - result.y};
NSPoint window_pt = [view convertPoint:view_pt toView:nil];
NSPoint screen_pt = [[view window] convertBaseToScreen:window_pt];
result.globalX = screen_pt.x;
result.globalY = screen_pt.y;
}
}
// modifiers

View File

@ -716,7 +716,7 @@ void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window;
return IsWindowless() ? window_info_.parent_window : window_info_.window;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
@ -922,11 +922,17 @@ void CefBrowserHostImpl::PlatformTranslateMouseEvent(
result.globalX = result.x;
result.globalY = result.y;
// global position
POINT globalPoint = { result.x, result.y };
ClientToScreen(GetWindowHandle(), &globalPoint);
result.globalX = globalPoint.x;
result.globalY = globalPoint.y;
if (IsWindowless()) {
GetClient()->GetRenderHandler()->GetScreenPoint(
GetBrowser(),
result.x, result.y,
result.globalX, result.globalY);
} else {
POINT globalPoint = { result.x, result.y };
ClientToScreen(GetWindowHandle(), &globalPoint);
result.globalX = globalPoint.x;
result.globalY = globalPoint.y;
}
// modifiers
result.modifiers |= TranslateModifiers(mouse_event.modifiers);

View File

@ -7,13 +7,18 @@
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
: browser_id_(browser_id),
is_popup_(is_popup) {
is_popup_(is_popup),
is_windowless_(false) {
DCHECK_GT(browser_id, 0);
}
CefBrowserInfo::~CefBrowserInfo() {
}
void CefBrowserInfo::set_windowless(bool windowless) {
is_windowless_ = windowless;
}
void CefBrowserInfo::add_render_view_id(
int render_process_id, int render_routing_id) {
add_render_id(&render_view_id_set_, render_process_id, render_routing_id);

View File

@ -24,6 +24,9 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
int browser_id() const { return browser_id_; };
bool is_popup() const { return is_popup_; }
bool is_windowless() const { return is_windowless_; }
void set_windowless(bool windowless);
// Adds an ID pair if it doesn't already exist.
void add_render_view_id(int render_process_id, int render_routing_id);
@ -55,6 +58,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
int browser_id_;
bool is_popup_;
bool is_windowless_;
base::Lock lock_;

View File

@ -91,6 +91,7 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
render_frame_routing_id);
params->browser_id = info->browser_id();
params->is_popup = info->is_popup();
params->is_windowless = info->is_windowless();
}
void CefBrowserMessageFilter::OnCreateWindow(

View File

@ -74,6 +74,8 @@ class CefAccessTokenStore : public content::AccessTokenStore {
private:
AccessTokenSet access_token_set_;
DISALLOW_COPY_AND_ASSIGN(CefAccessTokenStore);
};
class CefQuotaCallbackImpl : public CefQuotaCallback {
@ -134,6 +136,7 @@ class CefQuotaCallbackImpl : public CefQuotaCallback {
content::QuotaPermissionContext::PermissionCallback callback_;
IMPLEMENT_REFCOUNTING(CefQuotaCallbackImpl);
DISALLOW_COPY_AND_ASSIGN(CefQuotaCallbackImpl);
};
class CefAllowCertificateErrorCallbackImpl
@ -164,6 +167,7 @@ class CefAllowCertificateErrorCallbackImpl
base::Callback<void(bool)> callback_;
IMPLEMENT_REFCOUNTING(CefAllowCertificateErrorCallbackImpl);
DISALLOW_COPY_AND_ASSIGN(CefAllowCertificateErrorCallbackImpl);
};
class CefQuotaPermissionContext : public content::QuotaPermissionContext {
@ -214,6 +218,8 @@ class CefQuotaPermissionContext : public content::QuotaPermissionContext {
private:
virtual ~CefQuotaPermissionContext() {
}
DISALLOW_COPY_AND_ASSIGN(CefQuotaPermissionContext);
};
class CefPluginServiceFilter : public content::PluginServiceFilter {
@ -255,6 +261,8 @@ class CefPluginServiceFilter : public content::PluginServiceFilter {
const base::FilePath& path) OVERRIDE {
return true;
}
DISALLOW_COPY_AND_ASSIGN(CefPluginServiceFilter);
};
void TranslatePopupFeatures(const blink::WebWindowFeatures& webKitFeatures,

View File

@ -103,6 +103,11 @@ bool CefMenuCreator::CreateContextMenu(
return runner_->RunContextMenu(this);
}
void CefMenuCreator::CancelContextMenu() {
if (IsShowingContextMenu())
runner_->CancelContextMenu();
}
bool CefMenuCreator::CreateRunner() {
if (!runner_.get()) {
// Create the menu runner.

View File

@ -24,6 +24,7 @@ class CefMenuCreator : public CefMenuModelImpl::Delegate {
public:
virtual ~Runner() {}
virtual bool RunContextMenu(CefMenuCreator* manager) =0;
virtual void CancelContextMenu() {}
virtual bool FormatLabel(base::string16& label) { return false; }
};
@ -35,6 +36,7 @@ class CefMenuCreator : public CefMenuModelImpl::Delegate {
// Create the context menu.
bool CreateContextMenu(const content::ContextMenuParams& params);
void CancelContextMenu();
CefBrowserHostImpl* browser() { return browser_; }
ui::MenuModel* model() { return model_->model(); }

View File

@ -24,14 +24,34 @@ CefMenuCreatorRunnerLinux::~CefMenuCreatorRunnerLinux() {
bool CefMenuCreatorRunnerLinux::RunContextMenu(CefMenuCreator* manager) {
menu_.reset(new views::MenuRunner(manager->model()));
// We can't use aura::Window::GetBoundsInScreen on Linux because it will
// return bounds from DesktopWindowTreeHostX11 which in our case is relative
// to the parent window instead of the root window (screen).
const gfx::Rect& bounds_in_screen =
manager->browser()->window_x11()->GetBoundsInScreen();
gfx::Point screen_point =
gfx::Point(bounds_in_screen.x() + manager->params().x,
bounds_in_screen.y() + manager->params().y);
gfx::Point screen_point;
if (manager->browser()->IsWindowless()) {
CefRefPtr<CefClient> client = manager->browser()->GetClient();
if (!client.get())
return false;
CefRefPtr<CefRenderHandler> handler = client->GetRenderHandler();
if (!handler.get())
return false;
int screenX = 0, screenY = 0;
if (!handler->GetScreenPoint(manager->browser(),
manager->params().x, manager->params().y,
screenX, screenY)) {
return false;
}
screen_point = gfx::Point(screenX, screenY);
} else {
// We can't use aura::Window::GetBoundsInScreen on Linux because it will
// return bounds from DesktopWindowTreeHostX11 which in our case is relative
// to the parent window instead of the root window (screen).
const gfx::Rect& bounds_in_screen =
manager->browser()->window_x11()->GetBoundsInScreen();
screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x,
bounds_in_screen.y() + manager->params().y);
}
views::MenuRunner::RunResult result =
menu_->RunMenuAt(manager->browser()->window_widget(),
@ -44,6 +64,11 @@ bool CefMenuCreatorRunnerLinux::RunContextMenu(CefMenuCreator* manager) {
return true;
}
void CefMenuCreatorRunnerLinux::CancelContextMenu() {
if (menu_)
menu_->Cancel();
}
bool CefMenuCreatorRunnerLinux::FormatLabel(base::string16& label) {
// Remove the accelerator indicator (&) from label strings.
const char16 replace[] = {L'&', 0};

View File

@ -18,6 +18,7 @@ class CefMenuCreatorRunnerLinux: public CefMenuCreator::Runner {
// CefMemoryManager::Runner methods.
virtual bool RunContextMenu(CefMenuCreator* manager) OVERRIDE;
virtual void CancelContextMenu() OVERRIDE;
virtual bool FormatLabel(base::string16& label) OVERRIDE;
private:

View File

@ -61,9 +61,33 @@ bool CefMenuCreatorRunnerMac::RunContextMenu(CefMenuCreator* manager) {
base::mac::ScopedSendingEvent sendingEventScoper;
// Show the menu. Blocks until the menu is dismissed.
[NSMenu popUpContextMenu:[menu_controller_ menu]
withEvent:clickEvent
forView:parent_view];
if (manager->browser()->IsWindowless()) {
// Showing the menu in OSR is pretty much self contained, only using
// the initialized menu_controller_ in this function, and the scoped
// variables in this block.
int screenX = 0, screenY = 0;
CefRefPtr<CefRenderHandler> handler =
manager->browser()->GetClient()->GetRenderHandler();
if (!handler->GetScreenPoint(manager->browser(),
manager->params().x, manager->params().y,
screenX, screenY)) {
return false;
}
// Don't show the menu unless there is a parent native window to tie it to
if (!manager->browser()->GetWindowHandle())
return false;
NSPoint screen_position =
NSPointFromCGPoint(gfx::Point(screenX, screenY).ToCGPoint());
[[menu_controller_ menu] popUpMenuPositioningItem:nil
atLocation:screen_position
inView:nil];
} else {
[NSMenu popUpContextMenu:[menu_controller_ menu]
withEvent:clickEvent
forView:parent_view];
}
}
return true;

View File

@ -24,10 +24,29 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) {
gfx::Point screen_point;
aura::Window* window = manager->browser()->GetContentView();
const gfx::Rect& bounds_in_screen = window->GetBoundsInScreen();
screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x,
bounds_in_screen.y() + manager->params().y);
if (manager->browser()->IsWindowless()) {
CefRefPtr<CefClient> client = manager->browser()->GetClient();
if (!client.get())
return false;
CefRefPtr<CefRenderHandler> handler = client->GetRenderHandler();
if (!handler.get())
return false;
int screenX = 0, screenY = 0;
if (!handler->GetScreenPoint(manager->browser(),
manager->params().x, manager->params().y,
screenX, screenY)) {
return false;
}
screen_point = gfx::Point(screenX, screenY);
} else {
aura::Window* window = manager->browser()->GetContentView();
const gfx::Rect& bounds_in_screen = window->GetBoundsInScreen();
screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x,
bounds_in_screen.y() + manager->params().y);
}
// Show the menu. Blocks until the menu is dismissed.
menu_->RunMenuAt(screen_point, views::Menu2::ALIGN_TOPLEFT);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,341 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_
#define CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_
#pragma once
#include <vector>
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/compositor/delegated_frame_host.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "ui/compositor/compositor.h"
#if defined(OS_WIN)
#include "ui/gfx/win/window_impl.h"
#endif
namespace content {
class RenderWidgetHost;
class RenderWidgetHostImpl;
class BackingStore;
}
class CefBrowserHostImpl;
class CefWebContentsViewOSR;
#if defined(OS_MACOSX)
#ifdef __OBJC__
@class NSWindow;
#else
class NSWindow;
#endif
#endif
#if defined(USE_X11)
class CefWindowX11;
#endif
///////////////////////////////////////////////////////////////////////////////
// CefRenderWidgetHostViewOSR
//
// An object representing the "View" of a rendered web page. This object is
// responsible for sending paint events to the the CefRenderHandler
// when window rendering is disabled. It is the implementation of the
// RenderWidgetHostView that the cross-platform RenderWidgetHost object uses
// to display the data.
//
// Comment excerpted from render_widget_host.h:
//
// "The lifetime of the RenderWidgetHostView is tied to the render process.
// If the render process dies, the RenderWidgetHostView goes away and all
// references to it must become NULL."
//
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
///////////////////////////////////////////////////////////////////////////////
class CefRenderWidgetHostViewOSR
: public content::RenderWidgetHostViewBase,
public content::DelegatedFrameHostClient {
public:
explicit CefRenderWidgetHostViewOSR(content::RenderWidgetHost* widget);
virtual ~CefRenderWidgetHostViewOSR();
// RenderWidgetHostView implementation.
virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
virtual content::RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void SetBounds(const gfx::Rect& rect) OVERRIDE;
virtual gfx::NativeView GetNativeView() const OVERRIDE;
virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
virtual void Focus() OVERRIDE;
virtual bool HasFocus() const OVERRIDE;
virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsShowing() OVERRIDE;
virtual gfx::Rect GetViewBounds() const OVERRIDE;
virtual void SetBackgroundOpaque(bool opaque) OVERRIDE;
virtual bool LockMouse() OVERRIDE;
virtual void UnlockMouse() OVERRIDE;
#if defined(OS_MACOSX)
virtual void SetActive(bool active) OVERRIDE;
virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual void WindowFrameChanged() OVERRIDE;
virtual void ShowDefinitionForSelection() OVERRIDE;
virtual bool SupportsSpeech() const OVERRIDE;
virtual void SpeakSelection() OVERRIDE;
virtual bool IsSpeaking() const OVERRIDE;
virtual void StopSpeaking() OVERRIDE;
#endif // defined(OS_MACOSX)
// RenderWidgetHostViewBase implementation.
virtual void OnSwapCompositorFrame(
uint32 output_surface_id,
scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
virtual void InitAsPopup(content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) OVERRIDE;
virtual void InitAsFullscreen(
content::RenderWidgetHostView* reference_host_view) OVERRIDE;
virtual void WasShown() OVERRIDE;
virtual void WasHidden() OVERRIDE;
virtual void MovePluginWindows(
const std::vector<content::WebPluginGeometry>& moves) OVERRIDE;
virtual void Blur() OVERRIDE;
virtual void UpdateCursor(const content::WebCursor& cursor) OVERRIDE;
virtual void SetIsLoading(bool is_loading) OVERRIDE;
virtual void TextInputTypeChanged(ui::TextInputType type,
ui::TextInputMode input_mode,
bool can_compose_inline) OVERRIDE;
virtual void ImeCancelComposition() OVERRIDE;
virtual void RenderProcessGone(base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual gfx::Size GetRequestedRendererSize() const OVERRIDE;
virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE;
virtual void SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
virtual void ScrollOffsetChanged() OVERRIDE;
virtual void CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback,
const SkBitmap::Config config) OVERRIDE;
virtual void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) OVERRIDE;
virtual bool CanCopyToVideoFrame() const OVERRIDE;
virtual bool CanSubscribeFrame() const OVERRIDE;
virtual void BeginFrameSubscription(
scoped_ptr<content::RenderWidgetHostViewFrameSubscriber> subscriber)
OVERRIDE;
virtual void EndFrameSubscription() OVERRIDE;
virtual void AcceleratedSurfaceInitialized(int host_id,
int route_id) OVERRIDE;
virtual void AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
virtual void AcceleratedSurfaceRelease() OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE;
virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
virtual void SetScrollOffsetPinning(
bool is_pinned_to_left,
bool is_pinned_to_right) OVERRIDE;
#if defined(OS_MACOSX)
virtual bool PostProcessEventForPluginIme(
const content::NativeWebKeyboardEvent& event) OVERRIDE;
#endif
#if defined(OS_MACOSX) || defined(USE_AURA)
virtual void ImeCompositionRangeChanged(
const gfx::Range& range,
const std::vector<gfx::Rect>& character_bounds) OVERRIDE;
#endif
#if defined(OS_WIN)
virtual void SetParentNativeViewAccessible(
gfx::NativeViewAccessible accessible_parent) OVERRIDE;
virtual gfx::NativeViewId GetParentForWindowlessPlugin() const OVERRIDE;
#endif
// DelegatedFrameHost implementation.
virtual ui::Compositor* GetCompositor() const OVERRIDE;
virtual ui::Layer* GetLayer() OVERRIDE;
virtual content::RenderWidgetHostImpl* GetHost() OVERRIDE;
virtual void SchedulePaintInRect(
const gfx::Rect& damage_rect_in_dip) OVERRIDE;
virtual void DelegatedCompositorDidSwapBuffers() OVERRIDE;
virtual void DelegatedCompositorAbortedSwapBuffers() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
virtual scoped_ptr<content::ResizeLock> CreateResizeLock(
bool defer_compositor_lock) OVERRIDE;
virtual gfx::Size DesiredFrameSize() OVERRIDE;
virtual float CurrentDeviceScaleFactor() OVERRIDE;
virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) OVERRIDE;
virtual content::DelegatedFrameHost* GetDelegatedFrameHost() const OVERRIDE;
bool InstallTransparency();
void WasResized();
void OnScreenInfoChanged();
void Invalidate(CefBrowserHost::PaintElementType type);
void SendKeyEvent(const content::NativeWebKeyboardEvent& event);
void SendMouseEvent(const blink::WebMouseEvent& event);
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event);
void SendFocusEvent(bool focus);
void HoldResize();
void ReleaseResize();
bool IsPopupWidget() const {
return popup_type_ != blink::WebPopupTypeNone;
}
#if defined(OS_MACOSX)
NSTextInputContext* GetNSTextInputContext();
void HandleKeyEventBeforeTextInputClient(CefEventHandle keyEvent);
void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent);
bool GetCachedFirstRectForCharacterRange(gfx::Range range, gfx::Rect* rect,
gfx::Range* actual_range) const;
#endif // defined(OS_MACOSX)
CefRefPtr<CefBrowserHostImpl> browser_impl() const { return browser_impl_; }
void set_browser_impl(CefRefPtr<CefBrowserHostImpl> browser) {
browser_impl_ = browser;
}
void set_popup_host_view(CefRenderWidgetHostViewOSR* popup_view) {
popup_host_view_ = popup_view;
}
ui::Compositor* compositor() const { return compositor_.get(); }
content::RenderWidgetHostImpl* render_widget_host() const
{ return render_widget_host_; }
private:
void SetFrameRate();
void ResizeRootLayer();
// Implementation based on RendererOverridesHandler::InnerSwapCompositorFrame
// and DelegatedFrameHost::CopyFromCompositingSurface.
void GenerateFrame(bool force_frame);
void InternalGenerateFrame();
void CopyFromCompositingSurfaceHasResult(
scoped_ptr<cc::CopyOutputResult> result);
void PrepareTextureCopyOutputResult(
scoped_ptr<cc::CopyOutputResult> result);
static void CopyFromCompositingSurfaceFinishedProxy(
base::WeakPtr<CefRenderWidgetHostViewOSR> view,
scoped_ptr<cc::SingleReleaseCallback> release_callback,
scoped_ptr<SkBitmap> bitmap,
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
bool result);
void CopyFromCompositingSurfaceFinished(
scoped_ptr<SkBitmap> bitmap,
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
bool result);
void PrepareBitmapCopyOutputResult(
scoped_ptr<cc::CopyOutputResult> result);
void OnFrameCaptureFailure();
void OnFrameCaptureSuccess(
const SkBitmap& bitmap,
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock);
void OnFrameCaptureCompletion(bool force_frame);
void CancelPopupWidget();
#if defined(OS_MACOSX)
// Returns composition character boundary rectangle. The |range| is
// composition based range. Also stores |actual_range| which is corresponding
// to actually used range for returned rectangle.
gfx::Rect GetFirstRectForCompositionRange(const gfx::Range& range,
gfx::Range* actual_range) const;
// Converts from given whole character range to composition oriented range. If
// the conversion failed, return gfx::Range::InvalidRange.
gfx::Range ConvertCharacterRangeToCompositionRange(
const gfx::Range& request_range) const;
// Returns true if there is line break in |range| and stores line breaking
// point to |line_breaking_point|. The |line_break_point| is valid only if
// this function returns true.
static bool GetLineBreakIndex(const std::vector<gfx::Rect>& bounds,
const gfx::Range& range,
size_t* line_break_point);
void DestroyNSTextInputOSR();
#endif // defined(OS_MACOSX)
void PlatformCreateCompositorWidget();
void PlatformDestroyCompositorWidget();
scoped_ptr<content::DelegatedFrameHost> delegated_frame_host_;
scoped_ptr<ui::Compositor> compositor_;
gfx::AcceleratedWidget compositor_widget_;
scoped_ptr<ui::Layer> root_layer_;
#if defined(OS_WIN)
scoped_ptr<gfx::WindowImpl> window_;
#elif defined(OS_MACOSX)
NSWindow* window_;
#elif defined(USE_X11)
CefWindowX11* window_;
#endif
int frame_rate_threshold_ms_;
base::TimeTicks frame_start_time_;
bool frame_pending_;
bool frame_in_progress_;
int frame_retry_count_;
scoped_ptr<SkBitmap> bitmap_;
bool hold_resize_;
bool pending_resize_;
// The associated Model. While |this| is being Destroyed,
// |render_widget_host_| is NULL and the message loop is run one last time
// Message handlers must check for a NULL |render_widget_host_|.
content::RenderWidgetHostImpl* render_widget_host_;
CefRenderWidgetHostViewOSR* parent_host_view_;
CefRenderWidgetHostViewOSR* popup_host_view_;
CefRefPtr<CefBrowserHostImpl> browser_impl_;
bool is_showing_;
bool is_destroyed_;
gfx::Rect popup_position_;
#if defined(OS_MACOSX)
NSTextInputContext* text_input_context_osr_mac_;
#endif
base::WeakPtrFactory<CefRenderWidgetHostViewOSR> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefRenderWidgetHostViewOSR);
};
#endif // CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_

View File

@ -0,0 +1,25 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/render_widget_host_view_osr.h"
#include <X11/Xlib.h>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/window_x11.h"
#include "ui/gfx/x/x11_types.h"
void CefRenderWidgetHostViewOSR::PlatformCreateCompositorWidget() {
// Create a hidden 1x1 window. It will delete itself on close.
window_ = new CefWindowX11(NULL, None, gfx::Rect(0, 0, 1, 1));
compositor_widget_ = window_->xwindow();
}
void CefRenderWidgetHostViewOSR::PlatformDestroyCompositorWidget() {
DCHECK(window_);
window_->Close();
compositor_widget_ = gfx::kNullAcceleratedWidget;
}

View File

@ -0,0 +1,283 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/render_widget_host_view_osr.h"
#import <Cocoa/Cocoa.h>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/text_input_client_osr_mac.h"
#include "content/browser/compositor/browser_compositor_view_mac.h"
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif
namespace {
CefTextInputClientOSRMac* GetInputClientFromContext(
const NSTextInputContext* context) {
if (!context)
return NULL;
return reinterpret_cast<CefTextInputClientOSRMac*>([context client]);
}
} // namespace
void CefRenderWidgetHostViewOSR::SetActive(bool active) {
}
void CefRenderWidgetHostViewOSR::SetTakesFocusOnlyOnMouseDown(bool flag) {
}
void CefRenderWidgetHostViewOSR::SetWindowVisibility(bool visible) {
}
void CefRenderWidgetHostViewOSR::WindowFrameChanged() {
}
void CefRenderWidgetHostViewOSR::ShowDefinitionForSelection() {
}
bool CefRenderWidgetHostViewOSR::SupportsSpeech() const {
return false;
}
void CefRenderWidgetHostViewOSR::SpeakSelection() {
}
bool CefRenderWidgetHostViewOSR::IsSpeaking() const {
return false;
}
void CefRenderWidgetHostViewOSR::StopSpeaking() {
}
void CefRenderWidgetHostViewOSR::TextInputTypeChanged(
ui::TextInputType type,
ui::TextInputMode mode,
bool can_compose_inline) {
[NSApp updateWindows];
}
void CefRenderWidgetHostViewOSR::ImeCancelComposition() {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
if (client)
[client cancelComposition];
}
bool CefRenderWidgetHostViewOSR::PostProcessEventForPluginIme(
const content::NativeWebKeyboardEvent& event) {
return false;
}
void CefRenderWidgetHostViewOSR::ImeCompositionRangeChanged(
const gfx::Range& range,
const std::vector<gfx::Rect>& character_bounds) {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
if (!client)
return;
client->markedRange_ = range.ToNSRange();
client->composition_range_ = range;
client->composition_bounds_ = character_bounds;
}
CefTextInputContext CefRenderWidgetHostViewOSR::GetNSTextInputContext() {
if (!text_input_context_osr_mac_) {
CefTextInputClientOSRMac* text_input_client_osr_mac =
[[CefTextInputClientOSRMac alloc] initWithRenderWidgetHostViewOSR:
this];
text_input_context_osr_mac_ = [[NSTextInputContext alloc] initWithClient:
text_input_client_osr_mac];
}
return text_input_context_osr_mac_;
}
void CefRenderWidgetHostViewOSR::HandleKeyEventBeforeTextInputClient(
CefEventHandle keyEvent) {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
if (client)
[client HandleKeyEventBeforeTextInputClient: keyEvent];
}
void CefRenderWidgetHostViewOSR::HandleKeyEventAfterTextInputClient(
CefEventHandle keyEvent) {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
if (client)
[client HandleKeyEventAfterTextInputClient: keyEvent];
}
bool CefRenderWidgetHostViewOSR::GetCachedFirstRectForCharacterRange(
gfx::Range range, gfx::Rect* rect, gfx::Range* actual_range) const {
DCHECK(rect);
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
// If requested range is same as caret location, we can just return it.
if (selection_range_.is_empty() && gfx::Range(range) == selection_range_) {
if (actual_range)
*actual_range = range;
*rect = client->caret_rect_;
return true;
}
const gfx::Range request_range_in_composition =
ConvertCharacterRangeToCompositionRange(gfx::Range(range));
if (request_range_in_composition == gfx::Range::InvalidRange())
return false;
// If firstRectForCharacterRange in WebFrame is failed in renderer,
// ImeCompositionRangeChanged will be sent with empty vector.
if (client->composition_bounds_.empty())
return false;
DCHECK_EQ(client->composition_bounds_.size(),
client->composition_range_.length());
gfx::Range ui_actual_range;
*rect = GetFirstRectForCompositionRange(request_range_in_composition,
&ui_actual_range);
if (actual_range) {
*actual_range = gfx::Range(
client->composition_range_.start() + ui_actual_range.start(),
client->composition_range_.start() + ui_actual_range.end()).ToNSRange();
}
return true;
}
gfx::Rect CefRenderWidgetHostViewOSR::GetFirstRectForCompositionRange(
const gfx::Range& range, gfx::Range* actual_range) const {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
DCHECK(client);
DCHECK(actual_range);
DCHECK(!client->composition_bounds_.empty());
DCHECK_LE(range.start(), client->composition_bounds_.size());
DCHECK_LE(range.end(), client->composition_bounds_.size());
if (range.is_empty()) {
*actual_range = range;
if (range.start() == client->composition_bounds_.size()) {
return gfx::Rect(client->composition_bounds_[range.start() - 1].right(),
client->composition_bounds_[range.start() - 1].y(),
0,
client->composition_bounds_[range.start() - 1].height());
} else {
return gfx::Rect(client->composition_bounds_[range.start()].x(),
client->composition_bounds_[range.start()].y(),
0,
client->composition_bounds_[range.start()].height());
}
}
size_t end_idx;
if (!GetLineBreakIndex(client->composition_bounds_,
range, &end_idx)) {
end_idx = range.end();
}
*actual_range = gfx::Range(range.start(), end_idx);
gfx::Rect rect = client->composition_bounds_[range.start()];
for (size_t i = range.start() + 1; i < end_idx; ++i) {
rect.Union(client->composition_bounds_[i]);
}
return rect;
}
gfx::Range CefRenderWidgetHostViewOSR::ConvertCharacterRangeToCompositionRange(
const gfx::Range& request_range) const {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
DCHECK(client);
if (client->composition_range_.is_empty())
return gfx::Range::InvalidRange();
if (request_range.is_reversed())
return gfx::Range::InvalidRange();
if (request_range.start() < client->composition_range_.start()
|| request_range.start() > client->composition_range_.end()
|| request_range.end() > client->composition_range_.end())
return gfx::Range::InvalidRange();
return gfx::Range(request_range.start() - client->composition_range_.start(),
request_range.end() - client->composition_range_.start());
}
bool CefRenderWidgetHostViewOSR::GetLineBreakIndex(
const std::vector<gfx::Rect>& bounds,
const gfx::Range& range,
size_t* line_break_point) {
DCHECK(line_break_point);
if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty())
return false;
// We can't check line breaking completely from only rectangle array. Thus we
// assume the line breaking as the next character's y offset is larger than
// a threshold. Currently the threshold is determined as minimum y offset plus
// 75% of maximum height.
const size_t loop_end_idx = std::min(bounds.size(), range.end());
int max_height = 0;
int min_y_offset = kint32max;
for (size_t idx = range.start(); idx < loop_end_idx; ++idx) {
max_height = std::max(max_height, bounds[idx].height());
min_y_offset = std::min(min_y_offset, bounds[idx].y());
}
int line_break_threshold = min_y_offset + (max_height * 3 / 4);
for (size_t idx = range.start(); idx < loop_end_idx; ++idx) {
if (bounds[idx].y() > line_break_threshold) {
*line_break_point = idx;
return true;
}
}
return false;
}
void CefRenderWidgetHostViewOSR::DestroyNSTextInputOSR() {
CefTextInputClientOSRMac* client = GetInputClientFromContext(
text_input_context_osr_mac_);
if (client) {
[client release];
client = NULL;
}
[text_input_context_osr_mac_ release];
text_input_context_osr_mac_ = NULL;
}
void CefRenderWidgetHostViewOSR::PlatformCreateCompositorWidget() {
// Create a borderless non-visible 1x1 window.
window_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1)
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
BrowserCompositorViewMac* view =
[[BrowserCompositorViewMac alloc] initWithSuperview:[window_ contentView]
withClient:NULL];
compositor_.reset([view compositor]);
DCHECK(compositor_);
compositor_widget_ = view;
}
void CefRenderWidgetHostViewOSR::PlatformDestroyCompositorWidget() {
DCHECK(window_);
// Compositor is owned by and will be freed by BrowserCompositorViewMac.
ui::Compositor* compositor = compositor_.release();
UNUSED(compositor);
[window_ close];
window_ = nil;
compositor_widget_ = gfx::kNullAcceleratedWidget;
}

View File

@ -0,0 +1,59 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/browser_host_impl.h"
namespace {
class CefCompositorHostWin : public gfx::WindowImpl {
public:
CefCompositorHostWin() {
// Create a hidden 1x1 borderless window.
set_window_style(WS_POPUP | WS_SYSMENU);
Init(NULL, gfx::Rect(0, 0, 1, 1));
}
virtual ~CefCompositorHostWin() {
DestroyWindow(hwnd());
}
private:
CR_BEGIN_MSG_MAP_EX(CompositorHostWin)
CR_MSG_WM_PAINT(OnPaint)
CR_END_MSG_MAP()
void OnPaint(HDC dc) {
ValidateRect(hwnd(), NULL);
}
DISALLOW_COPY_AND_ASSIGN(CefCompositorHostWin);
};
} // namespace
void CefRenderWidgetHostViewOSR::SetParentNativeViewAccessible(
gfx::NativeViewAccessible accessible_parent) {
}
gfx::NativeViewId
CefRenderWidgetHostViewOSR::GetParentForWindowlessPlugin() const {
if (browser_impl_.get()) {
return reinterpret_cast<gfx::NativeViewId>(
browser_impl_->GetWindowHandle());
}
return NULL;
}
void CefRenderWidgetHostViewOSR::PlatformCreateCompositorWidget() {
DCHECK(!window_);
window_.reset(new CefCompositorHostWin());
compositor_widget_ = window_->hwnd();
}
void CefRenderWidgetHostViewOSR::PlatformDestroyCompositorWidget() {
window_.reset(NULL);
compositor_widget_ = gfx::kNullAcceleratedWidget;
}

View File

@ -0,0 +1,89 @@
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_TEXT_INPUT_CLIENT_OSR_MAC_H_
#define CEF_LIBCEF_BROWSER_TEXT_INPUT_CLIENT_OSR_MAC_H_
#pragma once
#import <Cocoa/Cocoa.h>
#include <vector>
#include "libcef/browser/render_widget_host_view_osr.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/edit_command.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
// Implementation for the NSTextInputClient protocol used for enabling IME on
// mac when window rendering is disabled.
@interface CefTextInputClientOSRMac : NSObject<NSTextInputClient> {
@public
// The range of current marked text inside the whole content of the DOM node
// being edited.
NSRange markedRange_;
// The current composition character range and its bounds.
gfx::Range composition_range_;
std::vector<gfx::Rect> composition_bounds_;
// The current caret bounds.
gfx::Rect caret_rect_;
@private
// Represents the input-method attributes supported by this object.
base::scoped_nsobject<NSArray> validAttributesForMarkedText_;
// Indicates if we are currently handling a key down event.
BOOL handlingKeyDown_;
// Indicates if there is any marked text.
BOOL hasMarkedText_;
// Indicates whether there was any marked text prior to handling
// the current key event.
BOOL oldHasMarkedText_;
// Indicates if unmarkText is called or not when handling a keyboard
// event.
BOOL unmarkTextCalled_;
// The selected range, cached from a message sent by the renderer.
NSRange selectedRange_;
// Text to be inserted which was generated by handling a key down event.
base::string16 textToBeInserted_;
// Marked text which was generated by handling a key down event.
base::string16 markedText_;
// Underline information of the |markedText_|.
std::vector<blink::WebCompositionUnderline> underlines_;
// Indicates if doCommandBySelector method receives any edit command when
// handling a key down event.
BOOL hasEditCommands_;
// Contains edit commands received by the -doCommandBySelector: method when
// handling a key down event, not including inserting commands, eg. insertTab,
// etc.
content::EditCommands editCommands_;
CefRenderWidgetHostViewOSR* renderWidgetHostView_;
}
@property(nonatomic, readonly) NSRange selectedRange;
@property(nonatomic) BOOL handlingKeyDown;
- (id)initWithRenderWidgetHostViewOSR:(CefRenderWidgetHostViewOSR*) rwhv;
- (void)HandleKeyEventBeforeTextInputClient:(NSEvent*)keyEvent;
- (void)HandleKeyEventAfterTextInputClient:(NSEvent*)keyEvent;
- (void)cancelComposition;
@end
#endif // CEF_LIBCEF_BROWSER_TEXT_INPUT_CLIENT_OSR_MAC_H_

View File

@ -0,0 +1,359 @@
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "libcef/browser/text_input_client_osr_mac.h"
#include "libcef/browser/browser_host_impl.h"
#include "base/strings/sys_string_conversions.h"
#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
#import "content/browser/renderer_host/text_input_client_mac.h"
#include "content/common/input_messages.h"
namespace {
// TODO(suzhe): Upstream this function.
blink::WebColor WebColorFromNSColor(NSColor *color) {
CGFloat r, g, b, a;
[color getRed:&r green:&g blue:&b alpha:&a];
return
std::max(0, std::min(static_cast<int>(lroundf(255.0f * a)), 255)) << 24 |
std::max(0, std::min(static_cast<int>(lroundf(255.0f * r)), 255)) << 16 |
std::max(0, std::min(static_cast<int>(lroundf(255.0f * g)), 255)) << 8 |
std::max(0, std::min(static_cast<int>(lroundf(255.0f * b)), 255));
}
// Extract underline information from an attributed string. Mostly copied from
// third_party/WebKit/Source/WebKit/mac/WebView/WebHTMLView.mm
void ExtractUnderlines(NSAttributedString* string,
std::vector<blink::WebCompositionUnderline>* underlines) {
int length = [[string string] length];
int i = 0;
while (i < length) {
NSRange range;
NSDictionary* attrs = [string attributesAtIndex:i
longestEffectiveRange:&range
inRange:NSMakeRange(i, length - i)];
NSNumber *style = [attrs objectForKey: NSUnderlineStyleAttributeName];
if (style) {
blink::WebColor color = SK_ColorBLACK;
if (NSColor *colorAttr =
[attrs objectForKey:NSUnderlineColorAttributeName]) {
color = WebColorFromNSColor(
[colorAttr colorUsingColorSpaceName:NSDeviceRGBColorSpace]);
}
underlines->push_back(blink::WebCompositionUnderline(
range.location, NSMaxRange(range), color, [style intValue] > 1));
}
i = range.location + range.length;
}
}
} // namespace
extern "C" {
extern NSString* NSTextInputReplacementRangeAttributeName;
}
@implementation CefTextInputClientOSRMac
@synthesize selectedRange = selectedRange_;
@synthesize handlingKeyDown = handlingKeyDown_;
- (id)initWithRenderWidgetHostViewOSR:(CefRenderWidgetHostViewOSR*)rwhv {
self = [super init];
renderWidgetHostView_ = rwhv;
return self;
}
- (NSArray*)validAttributesForMarkedText {
if (!validAttributesForMarkedText_) {
validAttributesForMarkedText_.reset([[NSArray alloc] initWithObjects:
NSUnderlineStyleAttributeName,
NSUnderlineColorAttributeName,
NSMarkedClauseSegmentAttributeName,
NSTextInputReplacementRangeAttributeName,
nil]);
}
return validAttributesForMarkedText_.get();
}
- (NSRange)markedRange {
return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0);
}
- (BOOL)hasMarkedText {
return hasMarkedText_;
}
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange {
BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]];
NSString* im_text = isAttributedString ? [aString string] : aString;
if (handlingKeyDown_) {
textToBeInserted_.append(base::SysNSStringToUTF16(im_text));
} else {
gfx::Range replacement_range(replacementRange);
renderWidgetHostView_->render_widget_host()->ImeConfirmComposition(
base::SysNSStringToUTF16(im_text), replacement_range, false);
}
// Inserting text will delete all marked text automatically.
hasMarkedText_ = NO;
}
- (void)doCommandBySelector:(SEL)aSelector {
// An input method calls this function to dispatch an editing command to be
// handled by this view.
if (aSelector == @selector(noop:))
return;
std::string command([content::RenderWidgetHostViewMacEditCommandHelper::
CommandNameForSelector(aSelector) UTF8String]);
// If this method is called when handling a key down event, then we need to
// handle the command in the key event handler. Otherwise we can just handle
// it here.
if (handlingKeyDown_) {
hasEditCommands_ = YES;
// We ignore commands that insert characters, because this was causing
// strange behavior (e.g. tab always inserted a tab rather than moving to
// the next field on the page).
if (!StartsWithASCII(command, "insert", false))
editCommands_.push_back(content::EditCommand(command, ""));
} else {
renderWidgetHostView_->render_widget_host()->Send(
new InputMsg_ExecuteEditCommand(
renderWidgetHostView_->render_widget_host()->GetRoutingID(),
command, ""));
}
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelRange
replacementRange:(NSRange)replacementRange {
// An input method updates the composition string.
// We send the given text and range to the renderer so it can update the
// composition node of WebKit.
BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]];
NSString* im_text = isAttributedString ? [aString string] : aString;
int length = [im_text length];
// |markedRange_| will get set on a callback from ImeSetComposition().
selectedRange_ = newSelRange;
markedText_ = base::SysNSStringToUTF16(im_text);
hasMarkedText_ = (length > 0);
underlines_.clear();
if (isAttributedString) {
ExtractUnderlines(aString, &underlines_);
} else {
// Use a thin black underline by default.
underlines_.push_back(blink::WebCompositionUnderline(0, length,
SK_ColorBLACK, false));
}
// If we are handling a key down event, then SetComposition() will be
// called in keyEvent: method.
// Input methods of Mac use setMarkedText calls with an empty text to cancel
// an ongoing composition. So, we should check whether or not the given text
// is empty to update the input method state. (Our input method backend can
// automatically cancels an ongoing composition when we send an empty text.
// So, it is OK to send an empty text to the renderer.)
if (!handlingKeyDown_) {
renderWidgetHostView_->render_widget_host()->ImeSetComposition(
markedText_, underlines_, newSelRange.location,
NSMaxRange(newSelRange));
}
}
- (void)unmarkText {
// Delete the composition node of the renderer and finish an ongoing
// composition.
// It seems an input method calls the setMarkedText method and set an empty
// text when it cancels an ongoing composition, i.e. I have never seen an
// input method calls this method.
hasMarkedText_ = NO;
markedText_.clear();
underlines_.clear();
// If we are handling a key down event, then ConfirmComposition() will be
// called in keyEvent: method.
if (!handlingKeyDown_) {
renderWidgetHostView_->render_widget_host()->ImeConfirmComposition(
base::string16(), gfx::Range::InvalidRange(), false);
} else {
unmarkTextCalled_ = YES;
}
}
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range
actualRange:(NSRangePointer)actualRange {
if (actualRange)
*actualRange = range;
NSAttributedString* str = content::TextInputClientMac::GetInstance()->
GetAttributedSubstringFromRange(
renderWidgetHostView_->GetRenderWidgetHost(), range);
return str;
}
- (NSRect)firstViewRectForCharacterRange:(NSRange)theRange
actualRange:(NSRangePointer)actualRange {
NSRect rect;
gfx::Rect gfxRect;
gfx::Range range(theRange);
gfx::Range actual_range;
if (!renderWidgetHostView_->GetCachedFirstRectForCharacterRange(range,
&gfxRect, &actual_range)) {
rect = content::TextInputClientMac::GetInstance()->
GetFirstRectForRange(renderWidgetHostView_->GetRenderWidgetHost(),
range.ToNSRange());
if (actualRange)
*actualRange = range.ToNSRange();
} else {
rect = NSRectFromCGRect(gfxRect.ToCGRect());
}
return rect;
}
- (NSRect) screenRectFromViewRect:(NSRect)rect {
NSRect screenRect;
int screenX, screenY;
renderWidgetHostView_->browser_impl()->GetClient()->GetRenderHandler()->
GetScreenPoint(renderWidgetHostView_->browser_impl()->GetBrowser(),
rect.origin.x, rect.origin.y, screenX, screenY);
screenRect.origin = NSMakePoint(screenX, screenY);
screenRect.size = rect.size;
return screenRect;
}
- (NSRect)firstRectForCharacterRange:(NSRange)theRange
actualRange:(NSRangePointer)actualRange {
NSRect rect = [self firstViewRectForCharacterRange:theRange
actualRange:actualRange];
// Convert into screen coordinates for return.
rect = [self screenRectFromViewRect:rect];
if (rect.origin.y >= rect.size.height)
rect.origin.y -= rect.size.height;
else
rect.origin.y = 0;
return rect;
}
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint {
// |thePoint| is in screen coordinates, but needs to be converted to WebKit
// coordinates (upper left origin). Scroll offsets will be taken care of in
// the renderer.
CefRect view_rect;
renderWidgetHostView_->browser_impl()->GetClient()->GetRenderHandler()->
GetViewRect(renderWidgetHostView_->browser_impl()->GetBrowser(),
view_rect);
thePoint.x -= view_rect.x;
thePoint.y -= view_rect.y;
thePoint.y = view_rect.height - thePoint.y;
NSUInteger index = content::TextInputClientMac::GetInstance()->
GetCharacterIndexAtPoint(renderWidgetHostView_->GetRenderWidgetHost(),
gfx::Point(thePoint.x, thePoint.y));
return index;
}
- (void)HandleKeyEventBeforeTextInputClient:(NSEvent*)keyEvent {
DCHECK([keyEvent type] == NSKeyDown);
// Don't call this method recursively.
DCHECK(!handlingKeyDown_);
oldHasMarkedText_ = hasMarkedText_;
handlingKeyDown_ = YES;
// These variables might be set when handling the keyboard event.
// Clear them here so that we can know whether they have changed afterwards.
textToBeInserted_.clear();
markedText_.clear();
underlines_.clear();
unmarkTextCalled_ = NO;
hasEditCommands_ = NO;
editCommands_.clear();
}
- (void)HandleKeyEventAfterTextInputClient:(NSEvent*)keyEvent {
handlingKeyDown_ = NO;
// Then send keypress and/or composition related events.
// If there was a marked text or the text to be inserted is longer than 1
// character, then we send the text by calling ConfirmComposition().
// Otherwise, if the text to be inserted only contains 1 character, then we
// can just send a keypress event which is fabricated by changing the type of
// the keydown event, so that we can retain all necessary informations, such
// as unmodifiedText, etc. And we need to set event.skip_in_browser to true to
// prevent the browser from handling it again.
// Note that, |textToBeInserted_| is a UTF-16 string, but it's fine to only
// handle BMP characters here, as we can always insert non-BMP characters as
// text.
if (!hasMarkedText_ && !oldHasMarkedText_ &&
textToBeInserted_.length() <= 1) {
content::NativeWebKeyboardEvent event(keyEvent);
if (textToBeInserted_.length() == 1) {
event.type = blink::WebInputEvent::Type::Char;
event.text[0] = textToBeInserted_[0];
event.text[1] = 0;
}
renderWidgetHostView_->SendKeyEvent(event);
}
BOOL textInserted = NO;
if (textToBeInserted_.length() >
((hasMarkedText_ || oldHasMarkedText_) ? 0u : 1u)) {
renderWidgetHostView_->render_widget_host()->ImeConfirmComposition(
textToBeInserted_, gfx::Range::InvalidRange(), false);
textToBeInserted_ = YES;
}
// Updates or cancels the composition. If some text has been inserted, then
// we don't need to cancel the composition explicitly.
if (hasMarkedText_ && markedText_.length()) {
// Sends the updated marked text to the renderer so it can update the
// composition node in WebKit.
// When marked text is available, |selectedRange_| will be the range being
// selected inside the marked text.
renderWidgetHostView_->render_widget_host()->ImeSetComposition(
markedText_, underlines_, selectedRange_.location,
NSMaxRange(selectedRange_));
} else if (oldHasMarkedText_ && !hasMarkedText_ && !textInserted) {
if (unmarkTextCalled_) {
renderWidgetHostView_->render_widget_host()->ImeConfirmComposition(
base::string16(), gfx::Range::InvalidRange(), false);
} else {
renderWidgetHostView_->render_widget_host()->ImeCancelComposition();
}
}
}
- (void)cancelComposition {
if (!hasMarkedText_)
return;
// Cancel the ongoing composition. [NSInputManager markedTextAbandoned:]
// doesn't call any NSTextInput functions, such as setMarkedText or
// insertText. So, we need to send an IPC message to a renderer so it can
// delete the composition node.
NSInputManager *currentInputManager = [NSInputManager currentInputManager];
[currentInputManager markedTextAbandoned:self];
hasMarkedText_ = NO;
// Should not call [self unmarkText] here, because it'll send unnecessary
// cancel composition IPC message to the renderer.
}
@end

View File

@ -0,0 +1,167 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/web_contents_view_osr.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/common/drag_data_impl.h"
#include "content/public/browser/render_widget_host.h"
CefWebContentsViewOSR::CefWebContentsViewOSR(
content::WebContents* web_contents,
content::WebContentsViewDelegate* delegate)
: web_contents_(web_contents),
view_(NULL) {
}
CefWebContentsViewOSR::~CefWebContentsViewOSR() {
}
gfx::NativeView CefWebContentsViewOSR::GetNativeView() const {
return gfx::NativeView();
}
gfx::NativeView CefWebContentsViewOSR::GetContentNativeView() const {
return gfx::NativeView();
}
gfx::NativeWindow CefWebContentsViewOSR::GetTopLevelNativeWindow() const {
return gfx::NativeWindow();
}
void CefWebContentsViewOSR::GetContainerBounds(gfx::Rect* out) const {
*out = GetViewBounds();
}
void CefWebContentsViewOSR::SizeContents(const gfx::Size& size) {
}
void CefWebContentsViewOSR::Focus() {
}
void CefWebContentsViewOSR::SetInitialFocus() {
}
void CefWebContentsViewOSR::StoreFocus() {
}
void CefWebContentsViewOSR::RestoreFocus() {
}
content::DropData* CefWebContentsViewOSR::GetDropData() const {
return NULL;
}
gfx::Rect CefWebContentsViewOSR::GetViewBounds() const {
return view_ ? view_->GetViewBounds() : gfx::Rect();
}
void CefWebContentsViewOSR::CreateView(const gfx::Size& initial_size,
gfx::NativeView context) {
}
content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
content::RenderWidgetHost* render_widget_host) {
if (render_widget_host->GetView()) {
return static_cast<content::RenderWidgetHostViewBase*>(
render_widget_host->GetView());
}
view_ = new CefRenderWidgetHostViewOSR(render_widget_host);
return view_;
}
content::RenderWidgetHostViewBase*
CefWebContentsViewOSR::CreateViewForPopupWidget(
content::RenderWidgetHost* render_widget_host) {
return new CefRenderWidgetHostViewOSR(render_widget_host);
}
void CefWebContentsViewOSR::SetPageTitle(const base::string16& title) {
}
void CefWebContentsViewOSR::RenderViewCreated(content::RenderViewHost* host) {
if (view_)
view_->InstallTransparency();
}
void CefWebContentsViewOSR::RenderViewSwappedIn(
content::RenderViewHost* host) {
}
void CefWebContentsViewOSR::SetOverscrollControllerEnabled(bool enabled) {
}
#if defined(OS_MACOSX)
void CefWebContentsViewOSR::SetAllowOverlappingViews(bool overlapping) {
}
bool CefWebContentsViewOSR::GetAllowOverlappingViews() const {
return false;
}
void CefWebContentsViewOSR::SetOverlayView(
content::WebContentsView* overlay,
const gfx::Point& offset) {
}
void CefWebContentsViewOSR::RemoveOverlayView() {
}
bool CefWebContentsViewOSR::IsEventTracking() const {
return false;
}
void CefWebContentsViewOSR::CloseTabAfterEventTracking() {
}
#endif // defined(OS_MACOSX)
void CefWebContentsViewOSR::StartDragging(
const content::DropData& drop_data,
blink::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const content::DragEventSourceInfo& event_info) {
CefRefPtr<CefBrowserHostImpl> browser;
CefRefPtr<CefRenderHandler> handler;
bool handled = false;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(view_);
if (view)
browser = view->browser_impl();
if (browser.get())
handler = browser->GetClient()->GetRenderHandler();
DCHECK(handler.get());
if (handler.get()) {
CefRefPtr<CefDragDataImpl> drag_data(new CefDragDataImpl(drop_data));
drag_data->SetReadOnly(true);
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
handled = handler->StartDragging(browser->GetBrowser(),
drag_data.get(),
static_cast<CefRenderHandler::DragOperationsMask>(allowed_ops),
event_info.event_location.x(),
event_info.event_location.y());
}
if (!handled && web_contents_)
web_contents_->SystemDragEnded();
}
void CefWebContentsViewOSR::UpdateDragCursor(
blink::WebDragOperation operation) {
CefRefPtr<CefBrowserHostImpl> browser;
CefRefPtr<CefRenderHandler> handler;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(view_);
if (view)
browser = view->browser_impl();
if (browser.get())
handler = browser->GetClient()->GetRenderHandler();
DCHECK(handler.get());
if (handler.get()) {
handler->UpdateDragCursor(browser->GetBrowser(),
static_cast<CefRenderHandler::DragOperation>(operation));
}
}

View File

@ -0,0 +1,76 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_
#define CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
namespace content {
class WebContents;
class WebContentsViewDelegate;
}
class CefRenderWidgetHostViewOSR;
// An implementation of WebContentsView for off-screen rendering.
class CefWebContentsViewOSR : public content::WebContentsView,
public content::RenderViewHostDelegateView {
public:
CefWebContentsViewOSR(content::WebContents* web_contents,
content::WebContentsViewDelegate* delegate);
virtual ~CefWebContentsViewOSR();
// WebContentsView methods.
virtual gfx::NativeView GetNativeView() const OVERRIDE;
virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
virtual void GetContainerBounds(gfx::Rect* out) const OVERRIDE;
virtual void SizeContents(const gfx::Size& size) OVERRIDE;
virtual void Focus() OVERRIDE;
virtual void SetInitialFocus() OVERRIDE;
virtual void StoreFocus() OVERRIDE;
virtual void RestoreFocus() OVERRIDE;
virtual content::DropData* GetDropData() const OVERRIDE;
virtual gfx::Rect GetViewBounds() const OVERRIDE;
virtual void CreateView(const gfx::Size& initial_size,
gfx::NativeView context) OVERRIDE;
virtual content::RenderWidgetHostViewBase* CreateViewForWidget(
content::RenderWidgetHost* render_widget_host) OVERRIDE;
virtual content::RenderWidgetHostViewBase* CreateViewForPopupWidget(
content::RenderWidgetHost* render_widget_host) OVERRIDE;
virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(content::RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(content::RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
#if defined(OS_MACOSX)
virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
virtual bool GetAllowOverlappingViews() const OVERRIDE;
virtual void SetOverlayView(content::WebContentsView* overlay,
const gfx::Point& offset) OVERRIDE;
virtual void RemoveOverlayView() OVERRIDE;
virtual bool IsEventTracking() const OVERRIDE;
virtual void CloseTabAfterEventTracking() OVERRIDE;
#endif
// RenderViewHostDelegateView methods.
virtual void StartDragging(
const content::DropData& drop_data,
blink::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const content::DragEventSourceInfo& event_info) OVERRIDE;
virtual void UpdateDragCursor(blink::WebDragOperation operation) OVERRIDE;
private:
content::WebContents* web_contents_;
CefRenderWidgetHostViewOSR* view_;
DISALLOW_COPY_AND_ASSIGN(CefWebContentsViewOSR);
};
#endif // CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_

View File

@ -173,10 +173,14 @@ void CefWindowX11::Focus() {
if (xwindow_ == None || !window_mapped_)
return;
::Window child = FindChild(xdisplay_, xwindow_);
if (child && ui::IsWindowVisible(child)) {
// Give focus to the child DesktopWindowTreeHostX11.
XSetInputFocus(xdisplay_, child, RevertToParent, CurrentTime);
if (browser_) {
::Window child = FindChild(xdisplay_, xwindow_);
if (child && ui::IsWindowVisible(child)) {
// Give focus to the child DesktopWindowTreeHostX11.
XSetInputFocus(xdisplay_, child, RevertToParent, CurrentTime);
}
} else {
XSetInputFocus(xdisplay_, xwindow_, RevertToParent, CurrentTime);
}
}
@ -233,13 +237,15 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
xev->xconfigure.width, xev->xconfigure.height);
bounds_ = bounds;
::Window child = FindChild(xdisplay_, xwindow_);
if (child) {
// Resize the child DesktopWindowTreeHostX11 to match this window.
XWindowChanges changes = {0};
changes.width = bounds.width();
changes.height = bounds.height();
XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);
if (browser_) {
::Window child = FindChild(xdisplay_, xwindow_);
if (child) {
// Resize the child DesktopWindowTreeHostX11 to match this window.
XWindowChanges changes = {0};
changes.width = bounds.width();
changes.height = bounds.height();
XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);
}
}
break;
}
@ -247,7 +253,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
// We have received a close message from the window manager.
if (browser_->destruction_state() <=
if (browser_ && browser_->destruction_state() <=
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
if (browser_->destruction_state() ==
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
@ -276,9 +282,11 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
case DestroyNotify:
xwindow_ = None;
// Force the browser to be destroyed and release the reference added
// in PlatformCreateWindow().
browser_->WindowDestroyed();
if (browser_) {
// Force the browser to be destroyed and release the reference added
// in PlatformCreateWindow().
browser_->WindowDestroyed();
}
delete this;
break;
@ -311,8 +319,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
void CefWindowX11::ContinueFocus() {
if (!focus_pending_)
return;
browser_->SetFocus(true);
if (browser_)
browser_->SetFocus(true);
focus_pending_ = false;
}

View File

@ -151,6 +151,7 @@ IPC_SYNC_MESSAGE_CONTROL0_1(
IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
IPC_STRUCT_MEMBER(int, browser_id)
IPC_STRUCT_MEMBER(bool, is_popup)
IPC_STRUCT_MEMBER(bool, is_windowless)
IPC_STRUCT_END()
// Retrieve information about a newly created browser.

View File

@ -2,55 +2,127 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include <string>
#include "libcef/browser/stream_impl.h"
#include "libcef/common/drag_data_impl.h"
#include "base/files/file_path.h"
#include "net/base/filename_util.h"
#include "net/base/net_util.h"
#define CHECK_READONLY_RETURN_VOID() \
if (read_only_) { \
NOTREACHED() << "object is read only"; \
return; \
}
CefDragDataImpl::CefDragDataImpl(const content::DropData& data)
: data_(data) {
: data_(data),
read_only_(false) {
}
CefDragDataImpl::CefDragDataImpl()
: read_only_(false) {
}
CefRefPtr<CefDragData> CefDragData::Create() {
return new CefDragDataImpl();
}
CefRefPtr<CefDragData> CefDragDataImpl::Clone() {
CefDragDataImpl* drag_data = NULL;
{
AutoLock lock_scope(this);
drag_data = new CefDragDataImpl(data_);
}
return drag_data;
}
bool CefDragDataImpl::IsReadOnly() {
AutoLock lock_scope(this);
return read_only_;
}
bool CefDragDataImpl::IsLink() {
AutoLock lock_scope(this);
return (data_.url.is_valid() && data_.file_description_filename.empty());
}
bool CefDragDataImpl::IsFragment() {
AutoLock lock_scope(this);
return (!data_.url.is_valid() && data_.file_description_filename.empty() &&
data_.filenames.empty());
}
bool CefDragDataImpl::IsFile() {
AutoLock lock_scope(this);
return (!data_.file_description_filename.empty() || !data_.filenames.empty());
}
CefString CefDragDataImpl::GetLinkURL() {
AutoLock lock_scope(this);
return data_.url.spec();
}
CefString CefDragDataImpl::GetLinkTitle() {
AutoLock lock_scope(this);
return data_.url_title;
}
CefString CefDragDataImpl::GetLinkMetadata() {
AutoLock lock_scope(this);
return data_.download_metadata;
}
CefString CefDragDataImpl::GetFragmentText() {
AutoLock lock_scope(this);
return data_.text.is_null() ? CefString() : CefString(data_.text.string());
}
CefString CefDragDataImpl::GetFragmentHtml() {
AutoLock lock_scope(this);
return data_.html.is_null() ? CefString() : CefString(data_.html.string());
}
CefString CefDragDataImpl::GetFragmentBaseURL() {
AutoLock lock_scope(this);
return data_.html_base_url.spec();
}
CefString CefDragDataImpl::GetFileName() {
return data_.file_description_filename;
AutoLock lock_scope(this);
if (data_.file_description_filename.empty())
return CefString();
base::FilePath file_name(CefString(data_.file_description_filename));
// Images without ALT text will only have a file extension so we need to
// synthesize one from the provided extension and URL.
if (file_name.BaseName().RemoveExtension().empty()) {
CefString extension = file_name.Extension();
// Retrieve the name from the URL.
CefString suggested_file_name =
net::GetSuggestedFilename(data_.url, "", "", "", "", "");
file_name = base::FilePath(suggested_file_name).ReplaceExtension(extension);
}
return file_name.value();
}
size_t CefDragDataImpl::GetFileContents(CefRefPtr<CefStreamWriter> writer) {
AutoLock lock_scope(this);
if (data_.file_contents.empty())
return 0;
char* data = const_cast<char*>(data_.file_contents.c_str());
size_t size = data_.file_contents.size();
if (!writer.get())
return size;
return writer->Write(data, 1, size);
}
bool CefDragDataImpl::GetFileNames(std::vector<CefString>& names) {
AutoLock lock_scope(this);
if (data_.filenames.empty())
return false;
@ -61,3 +133,62 @@ bool CefDragDataImpl::GetFileNames(std::vector<CefString>& names) {
return true;
}
void CefDragDataImpl::SetLinkURL(const CefString& url) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.url = GURL(url.ToString());
}
void CefDragDataImpl::SetLinkTitle(const CefString& title) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.url_title = title.ToString16();
}
void CefDragDataImpl::SetLinkMetadata(const CefString& data) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.download_metadata = data.ToString16();
}
void CefDragDataImpl::SetFragmentText(const CefString& text) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.text = base::NullableString16(text.ToString16(), false);
}
void CefDragDataImpl::SetFragmentHtml(const CefString& fragment) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.html = base::NullableString16(fragment.ToString16(), false);
}
void CefDragDataImpl::SetFragmentBaseURL(const CefString& fragment) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.html_base_url = GURL(fragment.ToString());
}
void CefDragDataImpl::ResetFileContents() {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.file_contents.erase();
data_.file_description_filename.erase();
}
void CefDragDataImpl::AddFile(const CefString& path,
const CefString& display_name) {
AutoLock lock_scope(this);
CHECK_READONLY_RETURN_VOID();
data_.filenames.push_back(ui::FileInfo(base::FilePath(path),
base::FilePath(display_name)));
}
void CefDragDataImpl::SetReadOnly(bool read_only) {
AutoLock lock_scope(this);
if (read_only_ == read_only)
return;
read_only_ = read_only;
}

View File

@ -14,7 +14,10 @@
// Implementation of CefDragData.
class CefDragDataImpl : public CefDragData {
public:
CefDragDataImpl();
explicit CefDragDataImpl(const content::DropData& data);
virtual CefRefPtr<CefDragData> Clone();
virtual bool IsReadOnly();
virtual bool IsLink();
virtual bool IsFragment();
@ -26,12 +29,33 @@ class CefDragDataImpl : public CefDragData {
virtual CefString GetFragmentHtml();
virtual CefString GetFragmentBaseURL();
virtual CefString GetFileName();
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer);
virtual bool GetFileNames(std::vector<CefString>& names);
virtual void SetLinkURL(const CefString& url);
virtual void SetLinkTitle(const CefString& title);
virtual void SetLinkMetadata(const CefString& data);
virtual void SetFragmentText(const CefString& text);
virtual void SetFragmentHtml(const CefString& fragment);
virtual void SetFragmentBaseURL(const CefString& fragment);
virtual void ResetFileContents();
virtual void AddFile(const CefString& path, const CefString& display_name);
// This method is not safe. Use Lock/Unlock to get mutually exclusive access.
const content::DropData& drop_data() {
return data_;
}
void SetReadOnly(bool read_only);
protected:
content::DropData data_;
// True if this object is read-only.
bool read_only_;
IMPLEMENT_REFCOUNTING(CefDragDataImpl);
IMPLEMENT_LOCKING(CefDragDataImpl);
};
#endif // CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_

View File

@ -288,6 +288,13 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
command_line->AppendSwitchASCII(switches::kContextSafetyImplementation,
base::IntToString(settings.context_safety_implementation));
}
if (settings.windowless_rendering_enabled) {
#if defined(OS_MACOSX)
// The delegated renderer is not yet enabled by default on OS X.
command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
#endif
}
}
if (content_client_.application().get()) {

View File

@ -268,10 +268,12 @@ bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process,
CefBrowserImpl::CefBrowserImpl(content::RenderView* render_view,
int browser_id,
bool is_popup)
bool is_popup,
bool is_windowless)
: content::RenderViewObserver(render_view),
browser_id_(browser_id),
is_popup_(is_popup),
is_windowless_(is_windowless),
last_focused_frame_id_(webkit_glue::kInvalidFrameId) {
response_manager_.reset(new CefResponseManager);
}

View File

@ -75,7 +75,8 @@ class CefBrowserImpl : public CefBrowser,
CefBrowserImpl(content::RenderView* render_view,
int browser_id,
bool is_popup);
bool is_popup,
bool is_windowless);
virtual ~CefBrowserImpl();
void LoadRequest(const CefMsg_LoadRequest_Params& params);
@ -95,6 +96,7 @@ class CefBrowserImpl : public CefBrowser,
int browser_id() const { return browser_id_; }
bool is_popup() const { return is_popup_; }
bool is_windowless() const { return is_windowless_; }
content::RenderView* render_view() const {
return content::RenderViewObserver::render_view();
}
@ -137,6 +139,7 @@ class CefBrowserImpl : public CefBrowser,
// same browser ID.
int browser_id_;
bool is_popup_;
bool is_windowless_;
// Id of the last frame that had focus.
int64 last_focused_frame_id_;

View File

@ -54,6 +54,7 @@ MSVC_POP_WARNING();
#include "third_party/WebKit/public/platform/WebWorkerRunLoop.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebPrerendererClient.h"
@ -434,6 +435,90 @@ void CefContentRendererClient::RenderViewCreated(
BrowserCreated(render_view, render_view->GetMainRenderFrame());
}
bool CefContentRendererClient::OverrideCreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) {
CefRefPtr<CefBrowserImpl> browser =
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
if (!browser || !browser->is_windowless())
return false;
#if defined(ENABLE_PLUGINS)
if (base::UTF16ToASCII(params.mimeType) == content::kBrowserPluginMimeType)
return false;
content::RenderFrameImpl* render_frame_impl =
static_cast<content::RenderFrameImpl*>(render_frame);
content::WebPluginInfo info;
std::string mime_type;
bool found = false;
render_frame_impl->Send(
new FrameHostMsg_GetPluginInfo(
render_frame_impl->GetRoutingID(),
params.url,
frame->top()->document().url(),
params.mimeType.utf8(),
&found,
&info,
&mime_type));
if (!found)
return false;
bool flash = LowerCaseEqualsASCII(mime_type,
"application/x-shockwave-flash");
bool silverlight = StartsWithASCII(mime_type,
"application/x-silverlight", false);
if (flash) {
// "wmode" values of "opaque" or "transparent" are allowed.
size_t size = params.attributeNames.size();
for (size_t i = 0; i < size; ++i) {
std::string name = params.attributeNames[i].utf8();
if (name == "wmode") {
std::string value = params.attributeValues[i].utf8();
if (value == "opaque" || value == "transparent")
flash = false;
break;
}
}
}
if (flash || silverlight) {
// Force Flash and Silverlight plugins to use windowless mode.
blink::WebPluginParams params_to_use = params;
params_to_use.mimeType = blink::WebString::fromUTF8(mime_type);
size_t size = params.attributeNames.size();
blink::WebVector<blink::WebString> new_names(size+1),
new_values(size+1);
for (size_t i = 0; i < size; ++i) {
new_names[i] = params.attributeNames[i];
new_values[i] = params.attributeValues[i];
}
if (flash) {
new_names[size] = "wmode";
new_values[size] = "opaque";
} else if (silverlight) {
new_names[size] = "windowless";
new_values[size] = "true";
}
params_to_use.attributeNames.swap(new_names);
params_to_use.attributeValues.swap(new_values);
*plugin = render_frame_impl->CreatePlugin(frame, info, params_to_use);
return true;
}
#endif // defined(ENABLE_PLUGINS)
return false;
}
bool CefContentRendererClient::HandleNavigation(
content::RenderFrame* render_frame,
content::DocumentState* document_state,
@ -578,8 +663,18 @@ void CefContentRendererClient::BrowserCreated(
if (GetBrowserForView(render_view))
return;
#if defined(OS_MACOSX)
// FIXME: It would be better if this API would be a callback from the
// WebKit layer, or if it would be exposed as an WebView instance method; the
// current implementation uses a static variable, and WebKit needs to be
// patched in order to make it work for each WebView instance
render_view->GetWebView()->setUseExternalPopupMenusThisInstance(
!params.is_windowless);
#endif
CefRefPtr<CefBrowserImpl> browser =
new CefBrowserImpl(render_view, params.browser_id, params.is_popup);
new CefBrowserImpl(render_view, params.browser_id, params.is_popup,
params.is_windowless);
browsers_.insert(std::make_pair(render_view, browser));
new CefPrerendererClient(render_view);

View File

@ -76,6 +76,11 @@ class CefContentRendererClient : public content::ContentRendererClient,
virtual void RenderThreadStarted() OVERRIDE;
virtual void RenderFrameCreated(content::RenderFrame* render_frame) OVERRIDE;
virtual void RenderViewCreated(content::RenderView* render_view) OVERRIDE;
virtual bool OverrideCreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) OVERRIDE;
virtual bool HandleNavigation(content::RenderFrame* render_frame,
content::DocumentState* document_state,
int opener_id,

View File

@ -12,6 +12,7 @@
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/ctocpp/client_ctocpp.h"
#include "libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h"
@ -410,6 +411,70 @@ int CEF_CALLBACK browser_host_is_mouse_cursor_change_disabled(
return _retval;
}
int CEF_CALLBACK browser_host_is_window_rendering_disabled(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefBrowserHostCppToC::Get(self)->IsWindowRenderingDisabled();
// Return type: bool
return _retval;
}
void CEF_CALLBACK browser_host_was_resized(struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->WasResized();
}
void CEF_CALLBACK browser_host_was_hidden(struct _cef_browser_host_t* self,
int hidden) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->WasHidden(
hidden?true:false);
}
void CEF_CALLBACK browser_host_notify_screen_info_changed(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->NotifyScreenInfoChanged();
}
void CEF_CALLBACK browser_host_invalidate(struct _cef_browser_host_t* self,
cef_paint_element_type_t type) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->Invalidate(
type);
}
void CEF_CALLBACK browser_host_send_key_event(struct _cef_browser_host_t* self,
const struct _cef_key_event_t* event) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -532,6 +597,164 @@ void CEF_CALLBACK browser_host_send_capture_lost_event(
CefBrowserHostCppToC::Get(self)->SendCaptureLostEvent();
}
cef_text_input_context_t CEF_CALLBACK browser_host_get_nstext_input_context(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
cef_text_input_context_t _retval = CefBrowserHostCppToC::Get(
self)->GetNSTextInputContext();
// Return type: simple
return _retval;
}
void CEF_CALLBACK browser_host_handle_key_event_before_text_input_client(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->HandleKeyEventBeforeTextInputClient(
keyEvent);
}
void CEF_CALLBACK browser_host_handle_key_event_after_text_input_client(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->HandleKeyEventAfterTextInputClient(
keyEvent);
}
void CEF_CALLBACK browser_host_drag_target_drag_enter(
struct _cef_browser_host_t* self, struct _cef_drag_data_t* drag_data,
const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: drag_data; type: refptr_same
DCHECK(drag_data);
if (!drag_data)
return;
// Verify param: event; type: struct_byref_const
DCHECK(event);
if (!event)
return;
// Translate param: event; type: struct_byref_const
CefMouseEvent eventObj;
if (event)
eventObj.Set(*event, false);
// Execute
CefBrowserHostCppToC::Get(self)->DragTargetDragEnter(
CefDragDataCppToC::Unwrap(drag_data),
eventObj,
allowed_ops);
}
void CEF_CALLBACK browser_host_drag_target_drag_over(
struct _cef_browser_host_t* self, const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: event; type: struct_byref_const
DCHECK(event);
if (!event)
return;
// Translate param: event; type: struct_byref_const
CefMouseEvent eventObj;
if (event)
eventObj.Set(*event, false);
// Execute
CefBrowserHostCppToC::Get(self)->DragTargetDragOver(
eventObj,
allowed_ops);
}
void CEF_CALLBACK browser_host_drag_target_drag_leave(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->DragTargetDragLeave();
}
void CEF_CALLBACK browser_host_drag_target_drop(
struct _cef_browser_host_t* self, const struct _cef_mouse_event_t* event) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: event; type: struct_byref_const
DCHECK(event);
if (!event)
return;
// Translate param: event; type: struct_byref_const
CefMouseEvent eventObj;
if (event)
eventObj.Set(*event, false);
// Execute
CefBrowserHostCppToC::Get(self)->DragTargetDrop(
eventObj);
}
void CEF_CALLBACK browser_host_drag_source_ended_at(
struct _cef_browser_host_t* self, int x, int y,
cef_drag_operations_mask_t op) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->DragSourceEndedAt(
x,
y,
op);
}
void CEF_CALLBACK browser_host_drag_source_system_drag_ended(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->DragSourceSystemDragEnded();
}
// CONSTRUCTOR - Do not edit by hand.
@ -559,6 +782,13 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
browser_host_set_mouse_cursor_change_disabled;
struct_.struct_.is_mouse_cursor_change_disabled =
browser_host_is_mouse_cursor_change_disabled;
struct_.struct_.is_window_rendering_disabled =
browser_host_is_window_rendering_disabled;
struct_.struct_.was_resized = browser_host_was_resized;
struct_.struct_.was_hidden = browser_host_was_hidden;
struct_.struct_.notify_screen_info_changed =
browser_host_notify_screen_info_changed;
struct_.struct_.invalidate = browser_host_invalidate;
struct_.struct_.send_key_event = browser_host_send_key_event;
struct_.struct_.send_mouse_click_event = browser_host_send_mouse_click_event;
struct_.struct_.send_mouse_move_event = browser_host_send_mouse_move_event;
@ -566,6 +796,19 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
struct_.struct_.send_focus_event = browser_host_send_focus_event;
struct_.struct_.send_capture_lost_event =
browser_host_send_capture_lost_event;
struct_.struct_.get_nstext_input_context =
browser_host_get_nstext_input_context;
struct_.struct_.handle_key_event_before_text_input_client =
browser_host_handle_key_event_before_text_input_client;
struct_.struct_.handle_key_event_after_text_input_client =
browser_host_handle_key_event_after_text_input_client;
struct_.struct_.drag_target_drag_enter = browser_host_drag_target_drag_enter;
struct_.struct_.drag_target_drag_over = browser_host_drag_target_drag_over;
struct_.struct_.drag_target_drag_leave = browser_host_drag_target_drag_leave;
struct_.struct_.drag_target_drop = browser_host_drag_target_drop;
struct_.struct_.drag_source_ended_at = browser_host_drag_source_ended_at;
struct_.struct_.drag_source_system_drag_ended =
browser_host_drag_source_system_drag_ended;
}
#ifndef NDEBUG

View File

@ -22,6 +22,7 @@
#include "libcef_dll/cpptoc/keyboard_handler_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/process_message_ctocpp.h"
@ -205,6 +206,22 @@ struct _cef_load_handler_t* CEF_CALLBACK client_get_load_handler(
return CefLoadHandlerCppToC::Wrap(_retval);
}
struct _cef_render_handler_t* CEF_CALLBACK client_get_render_handler(
struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefRenderHandler> _retval = CefClientCppToC::Get(
self)->GetRenderHandler();
// Return type: refptr_same
return CefRenderHandlerCppToC::Wrap(_retval);
}
struct _cef_request_handler_t* CEF_CALLBACK client_get_request_handler(
struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -264,6 +281,7 @@ CefClientCppToC::CefClientCppToC(CefClient* cls)
struct_.struct_.get_keyboard_handler = client_get_keyboard_handler;
struct_.struct_.get_life_span_handler = client_get_life_span_handler;
struct_.struct_.get_load_handler = client_get_load_handler;
struct_.struct_.get_render_handler = client_get_render_handler;
struct_.struct_.get_request_handler = client_get_request_handler;
struct_.struct_.on_process_message_received =
client_on_process_message_received;

View File

@ -11,11 +11,54 @@
//
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
#include "libcef_dll/cpptoc/stream_writer_cpptoc.h"
#include "libcef_dll/transfer_util.h"
// GLOBAL FUNCTIONS - Body may be edited by hand.
CEF_EXPORT cef_drag_data_t* cef_drag_data_create() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
CefRefPtr<CefDragData> _retval = CefDragData::Create();
// Return type: refptr_same
return CefDragDataCppToC::Wrap(_retval);
}
// MEMBER FUNCTIONS - Body may be edited by hand.
struct _cef_drag_data_t* CEF_CALLBACK drag_data_clone(
struct _cef_drag_data_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefDragData> _retval = CefDragDataCppToC::Get(self)->Clone();
// Return type: refptr_same
return CefDragDataCppToC::Wrap(_retval);
}
int CEF_CALLBACK drag_data_is_read_only(struct _cef_drag_data_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefDragDataCppToC::Get(self)->IsReadOnly();
// Return type: bool
return _retval;
}
int CEF_CALLBACK drag_data_is_link(struct _cef_drag_data_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -163,6 +206,23 @@ cef_string_userfree_t CEF_CALLBACK drag_data_get_file_name(
return _retval.DetachToUserFree();
}
size_t CEF_CALLBACK drag_data_get_file_contents(struct _cef_drag_data_t* self,
struct _cef_stream_writer_t* writer) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Unverified params: writer
// Execute
size_t _retval = CefDragDataCppToC::Get(self)->GetFileContents(
CefStreamWriterCppToC::Unwrap(writer));
// Return type: simple
return _retval;
}
int CEF_CALLBACK drag_data_get_file_names(struct _cef_drag_data_t* self,
cef_string_list_t names) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -191,11 +251,127 @@ int CEF_CALLBACK drag_data_get_file_names(struct _cef_drag_data_t* self,
return _retval;
}
void CEF_CALLBACK drag_data_set_link_url(struct _cef_drag_data_t* self,
const cef_string_t* url) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: url
// Execute
CefDragDataCppToC::Get(self)->SetLinkURL(
CefString(url));
}
void CEF_CALLBACK drag_data_set_link_title(struct _cef_drag_data_t* self,
const cef_string_t* title) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: title
// Execute
CefDragDataCppToC::Get(self)->SetLinkTitle(
CefString(title));
}
void CEF_CALLBACK drag_data_set_link_metadata(struct _cef_drag_data_t* self,
const cef_string_t* data) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: data
// Execute
CefDragDataCppToC::Get(self)->SetLinkMetadata(
CefString(data));
}
void CEF_CALLBACK drag_data_set_fragment_text(struct _cef_drag_data_t* self,
const cef_string_t* text) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: text
// Execute
CefDragDataCppToC::Get(self)->SetFragmentText(
CefString(text));
}
void CEF_CALLBACK drag_data_set_fragment_html(struct _cef_drag_data_t* self,
const cef_string_t* html) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: html
// Execute
CefDragDataCppToC::Get(self)->SetFragmentHtml(
CefString(html));
}
void CEF_CALLBACK drag_data_set_fragment_base_url(struct _cef_drag_data_t* self,
const cef_string_t* base_url) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: base_url
// Execute
CefDragDataCppToC::Get(self)->SetFragmentBaseURL(
CefString(base_url));
}
void CEF_CALLBACK drag_data_reset_file_contents(struct _cef_drag_data_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefDragDataCppToC::Get(self)->ResetFileContents();
}
void CEF_CALLBACK drag_data_add_file(struct _cef_drag_data_t* self,
const cef_string_t* path, const cef_string_t* display_name) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: path; type: string_byref_const
DCHECK(path);
if (!path)
return;
// Unverified params: display_name
// Execute
CefDragDataCppToC::Get(self)->AddFile(
CefString(path),
CefString(display_name));
}
// CONSTRUCTOR - Do not edit by hand.
CefDragDataCppToC::CefDragDataCppToC(CefDragData* cls)
: CefCppToC<CefDragDataCppToC, CefDragData, cef_drag_data_t>(cls) {
struct_.struct_.clone = drag_data_clone;
struct_.struct_.is_read_only = drag_data_is_read_only;
struct_.struct_.is_link = drag_data_is_link;
struct_.struct_.is_fragment = drag_data_is_fragment;
struct_.struct_.is_file = drag_data_is_file;
@ -206,7 +382,16 @@ CefDragDataCppToC::CefDragDataCppToC(CefDragData* cls)
struct_.struct_.get_fragment_html = drag_data_get_fragment_html;
struct_.struct_.get_fragment_base_url = drag_data_get_fragment_base_url;
struct_.struct_.get_file_name = drag_data_get_file_name;
struct_.struct_.get_file_contents = drag_data_get_file_contents;
struct_.struct_.get_file_names = drag_data_get_file_names;
struct_.struct_.set_link_url = drag_data_set_link_url;
struct_.struct_.set_link_title = drag_data_set_link_title;
struct_.struct_.set_link_metadata = drag_data_set_link_metadata;
struct_.struct_.set_fragment_text = drag_data_set_fragment_text;
struct_.struct_.set_fragment_html = drag_data_set_fragment_html;
struct_.struct_.set_fragment_base_url = drag_data_set_fragment_base_url;
struct_.struct_.reset_file_contents = drag_data_reset_file_contents;
struct_.struct_.add_file = drag_data_add_file;
}
#ifndef NDEBUG

View File

@ -0,0 +1,359 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK render_handler_get_root_screen_rect(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: rect; type: simple_byref
DCHECK(rect);
if (!rect)
return 0;
// Translate param: rect; type: simple_byref
CefRect rectVal = rect?*rect:CefRect();
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetRootScreenRect(
CefBrowserCToCpp::Wrap(browser),
rectVal);
// Restore param: rect; type: simple_byref
if (rect)
*rect = rectVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK render_handler_get_view_rect(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: rect; type: simple_byref
DCHECK(rect);
if (!rect)
return 0;
// Translate param: rect; type: simple_byref
CefRect rectVal = rect?*rect:CefRect();
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetViewRect(
CefBrowserCToCpp::Wrap(browser),
rectVal);
// Restore param: rect; type: simple_byref
if (rect)
*rect = rectVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK render_handler_get_screen_point(
struct _cef_render_handler_t* self, cef_browser_t* browser, int viewX,
int viewY, int* screenX, int* screenY) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: screenX; type: simple_byref
DCHECK(screenX);
if (!screenX)
return 0;
// Verify param: screenY; type: simple_byref
DCHECK(screenY);
if (!screenY)
return 0;
// Translate param: screenX; type: simple_byref
int screenXVal = screenX?*screenX:0;
// Translate param: screenY; type: simple_byref
int screenYVal = screenY?*screenY:0;
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetScreenPoint(
CefBrowserCToCpp::Wrap(browser),
viewX,
viewY,
screenXVal,
screenYVal);
// Restore param: screenX; type: simple_byref
if (screenX)
*screenX = screenXVal;
// Restore param: screenY; type: simple_byref
if (screenY)
*screenY = screenYVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK render_handler_get_screen_info(
struct _cef_render_handler_t* self, cef_browser_t* browser,
struct _cef_screen_info_t* screen_info) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: screen_info; type: struct_byref
DCHECK(screen_info);
if (!screen_info)
return 0;
// Translate param: screen_info; type: struct_byref
CefScreenInfo screen_infoObj;
if (screen_info)
screen_infoObj.AttachTo(*screen_info);
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetScreenInfo(
CefBrowserCToCpp::Wrap(browser),
screen_infoObj);
// Restore param: screen_info; type: struct_byref
if (screen_info)
screen_infoObj.DetachTo(*screen_info);
// Return type: bool
return _retval;
}
void CEF_CALLBACK render_handler_on_popup_show(
struct _cef_render_handler_t* self, cef_browser_t* browser, int show) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnPopupShow(
CefBrowserCToCpp::Wrap(browser),
show?true:false);
}
void CEF_CALLBACK render_handler_on_popup_size(
struct _cef_render_handler_t* self, cef_browser_t* browser,
const cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: rect; type: simple_byref_const
DCHECK(rect);
if (!rect)
return;
// Translate param: rect; type: simple_byref_const
CefRect rectVal = rect?*rect:CefRect();
// Execute
CefRenderHandlerCppToC::Get(self)->OnPopupSize(
CefBrowserCToCpp::Wrap(browser),
rectVal);
}
void CEF_CALLBACK render_handler_on_paint(struct _cef_render_handler_t* self,
cef_browser_t* browser, cef_paint_element_type_t type,
size_t dirtyRectsCount, cef_rect_t const* dirtyRects, const void* buffer,
int width, int height) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: dirtyRects; type: simple_vec_byref_const
DCHECK(dirtyRectsCount == 0 || dirtyRects);
if (dirtyRectsCount > 0 && !dirtyRects)
return;
// Verify param: buffer; type: simple_byaddr
DCHECK(buffer);
if (!buffer)
return;
// Translate param: dirtyRects; type: simple_vec_byref_const
std::vector<CefRect > dirtyRectsList;
if (dirtyRectsCount > 0) {
for (size_t i = 0; i < dirtyRectsCount; ++i) {
dirtyRectsList.push_back(dirtyRects[i]);
}
}
// Execute
CefRenderHandlerCppToC::Get(self)->OnPaint(
CefBrowserCToCpp::Wrap(browser),
type,
dirtyRectsList,
buffer,
width,
height);
}
void CEF_CALLBACK render_handler_on_cursor_change(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_cursor_handle_t cursor) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnCursorChange(
CefBrowserCToCpp::Wrap(browser),
cursor);
}
int CEF_CALLBACK render_handler_start_dragging(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_drag_data_t* drag_data, cef_drag_operations_mask_t allowed_ops, int x,
int y) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: drag_data; type: refptr_diff
DCHECK(drag_data);
if (!drag_data)
return 0;
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->StartDragging(
CefBrowserCToCpp::Wrap(browser),
CefDragDataCToCpp::Wrap(drag_data),
allowed_ops,
x,
y);
// Return type: bool
return _retval;
}
void CEF_CALLBACK render_handler_update_drag_cursor(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_drag_operations_mask_t operation) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->UpdateDragCursor(
CefBrowserCToCpp::Wrap(browser),
operation);
}
void CEF_CALLBACK render_handler_on_scroll_offset_changed(
struct _cef_render_handler_t* self, cef_browser_t* browser) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnScrollOffsetChanged(
CefBrowserCToCpp::Wrap(browser));
}
// CONSTRUCTOR - Do not edit by hand.
CefRenderHandlerCppToC::CefRenderHandlerCppToC(CefRenderHandler* cls)
: CefCppToC<CefRenderHandlerCppToC, CefRenderHandler, cef_render_handler_t>(
cls) {
struct_.struct_.get_root_screen_rect = render_handler_get_root_screen_rect;
struct_.struct_.get_view_rect = render_handler_get_view_rect;
struct_.struct_.get_screen_point = render_handler_get_screen_point;
struct_.struct_.get_screen_info = render_handler_get_screen_info;
struct_.struct_.on_popup_show = render_handler_on_popup_show;
struct_.struct_.on_popup_size = render_handler_on_popup_size;
struct_.struct_.on_paint = render_handler_on_paint;
struct_.struct_.on_cursor_change = render_handler_on_cursor_change;
struct_.struct_.start_dragging = render_handler_start_dragging;
struct_.struct_.update_drag_cursor = render_handler_update_drag_cursor;
struct_.struct_.on_scroll_offset_changed =
render_handler_on_scroll_offset_changed;
}
#ifndef NDEBUG
template<> long CefCppToC<CefRenderHandlerCppToC, CefRenderHandler,
cef_render_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_render_handler.h"
#include "include/capi/cef_render_handler_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefRenderHandlerCppToC
: public CefCppToC<CefRenderHandlerCppToC, CefRenderHandler,
cef_render_handler_t> {
public:
explicit CefRenderHandlerCppToC(CefRenderHandler* cls);
virtual ~CefRenderHandlerCppToC() {}
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_

View File

@ -14,6 +14,7 @@
#include "libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
#include "libcef_dll/transfer_util.h"
@ -330,6 +331,61 @@ bool CefBrowserHostCToCpp::IsMouseCursorChangeDisabled() {
return _retval?true:false;
}
bool CefBrowserHostCToCpp::IsWindowRenderingDisabled() {
if (CEF_MEMBER_MISSING(struct_, is_window_rendering_disabled))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = struct_->is_window_rendering_disabled(struct_);
// Return type: bool
return _retval?true:false;
}
void CefBrowserHostCToCpp::WasResized() {
if (CEF_MEMBER_MISSING(struct_, was_resized))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->was_resized(struct_);
}
void CefBrowserHostCToCpp::WasHidden(bool hidden) {
if (CEF_MEMBER_MISSING(struct_, was_hidden))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->was_hidden(struct_,
hidden);
}
void CefBrowserHostCToCpp::NotifyScreenInfoChanged() {
if (CEF_MEMBER_MISSING(struct_, notify_screen_info_changed))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->notify_screen_info_changed(struct_);
}
void CefBrowserHostCToCpp::Invalidate(PaintElementType type) {
if (CEF_MEMBER_MISSING(struct_, invalidate))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->invalidate(struct_,
type);
}
void CefBrowserHostCToCpp::SendKeyEvent(const CefKeyEvent& event) {
if (CEF_MEMBER_MISSING(struct_, send_key_event))
return;
@ -404,6 +460,120 @@ void CefBrowserHostCToCpp::SendCaptureLostEvent() {
struct_->send_capture_lost_event(struct_);
}
CefTextInputContext CefBrowserHostCToCpp::GetNSTextInputContext() {
if (CEF_MEMBER_MISSING(struct_, get_nstext_input_context))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_text_input_context_t _retval = struct_->get_nstext_input_context(struct_);
// Return type: simple
return _retval;
}
void CefBrowserHostCToCpp::HandleKeyEventBeforeTextInputClient(
CefEventHandle keyEvent) {
if (CEF_MEMBER_MISSING(struct_, handle_key_event_before_text_input_client))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->handle_key_event_before_text_input_client(struct_,
keyEvent);
}
void CefBrowserHostCToCpp::HandleKeyEventAfterTextInputClient(
CefEventHandle keyEvent) {
if (CEF_MEMBER_MISSING(struct_, handle_key_event_after_text_input_client))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->handle_key_event_after_text_input_client(struct_,
keyEvent);
}
void CefBrowserHostCToCpp::DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
const CefMouseEvent& event, DragOperationsMask allowed_ops) {
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_enter))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: drag_data; type: refptr_same
DCHECK(drag_data.get());
if (!drag_data.get())
return;
// Execute
struct_->drag_target_drag_enter(struct_,
CefDragDataCToCpp::Unwrap(drag_data),
&event,
allowed_ops);
}
void CefBrowserHostCToCpp::DragTargetDragOver(const CefMouseEvent& event,
DragOperationsMask allowed_ops) {
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_over))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->drag_target_drag_over(struct_,
&event,
allowed_ops);
}
void CefBrowserHostCToCpp::DragTargetDragLeave() {
if (CEF_MEMBER_MISSING(struct_, drag_target_drag_leave))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->drag_target_drag_leave(struct_);
}
void CefBrowserHostCToCpp::DragTargetDrop(const CefMouseEvent& event) {
if (CEF_MEMBER_MISSING(struct_, drag_target_drop))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->drag_target_drop(struct_,
&event);
}
void CefBrowserHostCToCpp::DragSourceEndedAt(int x, int y,
DragOperationsMask op) {
if (CEF_MEMBER_MISSING(struct_, drag_source_ended_at))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->drag_source_ended_at(struct_,
x,
y,
op);
}
void CefBrowserHostCToCpp::DragSourceSystemDragEnded() {
if (CEF_MEMBER_MISSING(struct_, drag_source_system_drag_ended))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->drag_source_system_drag_ended(struct_);
}
#ifndef NDEBUG
template<> long CefCToCpp<CefBrowserHostCToCpp, CefBrowserHost,

View File

@ -62,6 +62,11 @@ class CefBrowserHostCToCpp
virtual void CloseDevTools() OVERRIDE;
virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE;
virtual bool IsMouseCursorChangeDisabled() OVERRIDE;
virtual bool IsWindowRenderingDisabled() OVERRIDE;
virtual void WasResized() OVERRIDE;
virtual void WasHidden(bool hidden) OVERRIDE;
virtual void NotifyScreenInfoChanged() OVERRIDE;
virtual void Invalidate(PaintElementType type) OVERRIDE;
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
virtual void SendMouseClickEvent(const CefMouseEvent& event,
MouseButtonType type, bool mouseUp, int clickCount) OVERRIDE;
@ -71,6 +76,19 @@ class CefBrowserHostCToCpp
int deltaY) OVERRIDE;
virtual void SendFocusEvent(bool setFocus) OVERRIDE;
virtual void SendCaptureLostEvent() OVERRIDE;
virtual CefTextInputContext GetNSTextInputContext() OVERRIDE;
virtual void HandleKeyEventBeforeTextInputClient(
CefEventHandle keyEvent) OVERRIDE;
virtual void HandleKeyEventAfterTextInputClient(
CefEventHandle keyEvent) OVERRIDE;
virtual void DragTargetDragEnter(CefRefPtr<CefDragData> drag_data,
const CefMouseEvent& event, DragOperationsMask allowed_ops) OVERRIDE;
virtual void DragTargetDragOver(const CefMouseEvent& event,
DragOperationsMask allowed_ops) OVERRIDE;
virtual void DragTargetDragLeave() OVERRIDE;
virtual void DragTargetDrop(const CefMouseEvent& event) OVERRIDE;
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op) OVERRIDE;
virtual void DragSourceSystemDragEnded() OVERRIDE;
};
#endif // USING_CEF_SHARED

View File

@ -24,6 +24,7 @@
#include "libcef_dll/ctocpp/keyboard_handler_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
@ -174,6 +175,19 @@ CefRefPtr<CefLoadHandler> CefClientCToCpp::GetLoadHandler() {
return CefLoadHandlerCToCpp::Wrap(_retval);
}
CefRefPtr<CefRenderHandler> CefClientCToCpp::GetRenderHandler() {
if (CEF_MEMBER_MISSING(struct_, get_render_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_render_handler_t* _retval = struct_->get_render_handler(struct_);
// Return type: refptr_same
return CefRenderHandlerCToCpp::Wrap(_retval);
}
CefRefPtr<CefRequestHandler> CefClientCToCpp::GetRequestHandler() {
if (CEF_MEMBER_MISSING(struct_, get_request_handler))
return NULL;

View File

@ -43,6 +43,7 @@ class CefClientCToCpp
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE;
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE;
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE;
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,

View File

@ -11,11 +11,51 @@
//
#include "libcef_dll/ctocpp/drag_data_ctocpp.h"
#include "libcef_dll/ctocpp/stream_writer_ctocpp.h"
#include "libcef_dll/transfer_util.h"
// STATIC METHODS - Body may be edited by hand.
CefRefPtr<CefDragData> CefDragData::Create() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_drag_data_t* _retval = cef_drag_data_create();
// Return type: refptr_same
return CefDragDataCToCpp::Wrap(_retval);
}
// VIRTUAL METHODS - Body may be edited by hand.
CefRefPtr<CefDragData> CefDragDataCToCpp::Clone() {
if (CEF_MEMBER_MISSING(struct_, clone))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_drag_data_t* _retval = struct_->clone(struct_);
// Return type: refptr_same
return CefDragDataCToCpp::Wrap(_retval);
}
bool CefDragDataCToCpp::IsReadOnly() {
if (CEF_MEMBER_MISSING(struct_, is_read_only))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = struct_->is_read_only(struct_);
// Return type: bool
return _retval?true:false;
}
bool CefDragDataCToCpp::IsLink() {
if (CEF_MEMBER_MISSING(struct_, is_link))
return false;
@ -160,6 +200,22 @@ CefString CefDragDataCToCpp::GetFileName() {
return _retvalStr;
}
size_t CefDragDataCToCpp::GetFileContents(CefRefPtr<CefStreamWriter> writer) {
if (CEF_MEMBER_MISSING(struct_, get_file_contents))
return 0;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: writer
// Execute
size_t _retval = struct_->get_file_contents(struct_,
CefStreamWriterCToCpp::Unwrap(writer));
// Return type: simple
return _retval;
}
bool CefDragDataCToCpp::GetFileNames(std::vector<CefString>& names) {
if (CEF_MEMBER_MISSING(struct_, get_file_names))
return false;
@ -187,6 +243,113 @@ bool CefDragDataCToCpp::GetFileNames(std::vector<CefString>& names) {
return _retval?true:false;
}
void CefDragDataCToCpp::SetLinkURL(const CefString& url) {
if (CEF_MEMBER_MISSING(struct_, set_link_url))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: url
// Execute
struct_->set_link_url(struct_,
url.GetStruct());
}
void CefDragDataCToCpp::SetLinkTitle(const CefString& title) {
if (CEF_MEMBER_MISSING(struct_, set_link_title))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: title
// Execute
struct_->set_link_title(struct_,
title.GetStruct());
}
void CefDragDataCToCpp::SetLinkMetadata(const CefString& data) {
if (CEF_MEMBER_MISSING(struct_, set_link_metadata))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: data
// Execute
struct_->set_link_metadata(struct_,
data.GetStruct());
}
void CefDragDataCToCpp::SetFragmentText(const CefString& text) {
if (CEF_MEMBER_MISSING(struct_, set_fragment_text))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: text
// Execute
struct_->set_fragment_text(struct_,
text.GetStruct());
}
void CefDragDataCToCpp::SetFragmentHtml(const CefString& html) {
if (CEF_MEMBER_MISSING(struct_, set_fragment_html))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: html
// Execute
struct_->set_fragment_html(struct_,
html.GetStruct());
}
void CefDragDataCToCpp::SetFragmentBaseURL(const CefString& base_url) {
if (CEF_MEMBER_MISSING(struct_, set_fragment_base_url))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: base_url
// Execute
struct_->set_fragment_base_url(struct_,
base_url.GetStruct());
}
void CefDragDataCToCpp::ResetFileContents() {
if (CEF_MEMBER_MISSING(struct_, reset_file_contents))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->reset_file_contents(struct_);
}
void CefDragDataCToCpp::AddFile(const CefString& path,
const CefString& display_name) {
if (CEF_MEMBER_MISSING(struct_, add_file))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: path; type: string_byref_const
DCHECK(!path.empty());
if (path.empty())
return;
// Unverified params: display_name
// Execute
struct_->add_file(struct_,
path.GetStruct(),
display_name.GetStruct());
}
#ifndef NDEBUG
template<> long CefCToCpp<CefDragDataCToCpp, CefDragData,

View File

@ -33,6 +33,8 @@ class CefDragDataCToCpp
virtual ~CefDragDataCToCpp() {}
// CefDragData methods
virtual CefRefPtr<CefDragData> Clone() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual bool IsLink() OVERRIDE;
virtual bool IsFragment() OVERRIDE;
virtual bool IsFile() OVERRIDE;
@ -43,7 +45,17 @@ class CefDragDataCToCpp
virtual CefString GetFragmentHtml() OVERRIDE;
virtual CefString GetFragmentBaseURL() OVERRIDE;
virtual CefString GetFileName() OVERRIDE;
virtual size_t GetFileContents(CefRefPtr<CefStreamWriter> writer) OVERRIDE;
virtual bool GetFileNames(std::vector<CefString>& names) OVERRIDE;
virtual void SetLinkURL(const CefString& url) OVERRIDE;
virtual void SetLinkTitle(const CefString& title) OVERRIDE;
virtual void SetLinkMetadata(const CefString& data) OVERRIDE;
virtual void SetFragmentText(const CefString& text) OVERRIDE;
virtual void SetFragmentHtml(const CefString& html) OVERRIDE;
virtual void SetFragmentBaseURL(const CefString& base_url) OVERRIDE;
virtual void ResetFileContents() OVERRIDE;
virtual void AddFile(const CefString& path,
const CefString& display_name) OVERRIDE;
};
#endif // USING_CEF_SHARED

View File

@ -0,0 +1,275 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/drag_data_cpptoc.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
bool CefRenderHandlerCToCpp::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, get_root_screen_rect))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_root_screen_rect(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
// Return type: bool
return _retval?true:false;
}
bool CefRenderHandlerCToCpp::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, get_view_rect))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_view_rect(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
// Return type: bool
return _retval?true:false;
}
bool CefRenderHandlerCToCpp::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX, int viewY, int& screenX, int& screenY) {
if (CEF_MEMBER_MISSING(struct_, get_screen_point))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_screen_point(struct_,
CefBrowserCppToC::Wrap(browser),
viewX,
viewY,
&screenX,
&screenY);
// Return type: bool
return _retval?true:false;
}
bool CefRenderHandlerCToCpp::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) {
if (CEF_MEMBER_MISSING(struct_, get_screen_info))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_screen_info(struct_,
CefBrowserCppToC::Wrap(browser),
&screen_info);
// Return type: bool
return _retval?true:false;
}
void CefRenderHandlerCToCpp::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (CEF_MEMBER_MISSING(struct_, on_popup_show))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_popup_show(struct_,
CefBrowserCppToC::Wrap(browser),
show);
}
void CefRenderHandlerCToCpp::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, on_popup_size))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_popup_size(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
}
void CefRenderHandlerCToCpp::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type, const RectList& dirtyRects, const void* buffer,
int width, int height) {
if (CEF_MEMBER_MISSING(struct_, on_paint))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: buffer; type: simple_byaddr
DCHECK(buffer);
if (!buffer)
return;
// Translate param: dirtyRects; type: simple_vec_byref_const
const size_t dirtyRectsCount = dirtyRects.size();
cef_rect_t* dirtyRectsList = NULL;
if (dirtyRectsCount > 0) {
dirtyRectsList = new cef_rect_t[dirtyRectsCount];
DCHECK(dirtyRectsList);
if (dirtyRectsList) {
for (size_t i = 0; i < dirtyRectsCount; ++i) {
dirtyRectsList[i] = dirtyRects[i];
}
}
}
// Execute
struct_->on_paint(struct_,
CefBrowserCppToC::Wrap(browser),
type,
dirtyRectsCount,
dirtyRectsList,
buffer,
width,
height);
// Restore param:dirtyRects; type: simple_vec_byref_const
if (dirtyRectsList)
delete [] dirtyRectsList;
}
void CefRenderHandlerCToCpp::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (CEF_MEMBER_MISSING(struct_, on_cursor_change))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_cursor_change(struct_,
CefBrowserCppToC::Wrap(browser),
cursor);
}
bool CefRenderHandlerCToCpp::StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data, DragOperationsMask allowed_ops, int x,
int y) {
if (CEF_MEMBER_MISSING(struct_, start_dragging))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: drag_data; type: refptr_diff
DCHECK(drag_data.get());
if (!drag_data.get())
return false;
// Execute
int _retval = struct_->start_dragging(struct_,
CefBrowserCppToC::Wrap(browser),
CefDragDataCppToC::Wrap(drag_data),
allowed_ops,
x,
y);
// Return type: bool
return _retval?true:false;
}
void CefRenderHandlerCToCpp::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
DragOperation operation) {
if (CEF_MEMBER_MISSING(struct_, update_drag_cursor))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->update_drag_cursor(struct_,
CefBrowserCppToC::Wrap(browser),
operation);
}
void CefRenderHandlerCToCpp::OnScrollOffsetChanged(
CefRefPtr<CefBrowser> browser) {
if (CEF_MEMBER_MISSING(struct_, on_scroll_offset_changed))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_scroll_offset_changed(struct_,
CefBrowserCppToC::Wrap(browser));
}
#ifndef NDEBUG
template<> long CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,63 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_render_handler.h"
#include "include/capi/cef_render_handler_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefRenderHandlerCToCpp
: public CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t> {
public:
explicit CefRenderHandlerCToCpp(cef_render_handler_t* str)
: CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t>(str) {}
virtual ~CefRenderHandlerCToCpp() {}
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser, int viewX,
int viewY, int& screenX, int& screenY) OVERRIDE;
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList& dirtyRects, const void* buffer, int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data, DragOperationsMask allowed_ops, int x,
int y) OVERRIDE;
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
DragOperation operation) OVERRIDE;
virtual void OnScrollOffsetChanged(CefRefPtr<CefBrowser> browser) OVERRIDE;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_

View File

@ -89,6 +89,7 @@
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/read_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_process_handler_ctocpp.h"
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
#include "libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h"
@ -217,6 +218,7 @@ CEF_EXPORT void cef_shutdown() {
DCHECK_EQ(CefProcessMessageCppToC::DebugObjCt, 0);
DCHECK_EQ(CefQuotaCallbackCppToC::DebugObjCt, 0);
DCHECK_EQ(CefReadHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRenderHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRenderProcessHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRequestHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefResourceBundleHandlerCToCpp::DebugObjCt, 0);

View File

@ -53,6 +53,7 @@
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/read_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_process_handler_cpptoc.h"
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
#include "libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h"
@ -209,6 +210,7 @@ CEF_GLOBAL void CefShutdown() {
DCHECK_EQ(CefProcessMessageCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefQuotaCallbackCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefReadHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRenderHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRenderProcessHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRequestHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefResourceBundleHandlerCppToC::DebugObjCt, 0);

View File

@ -47,6 +47,11 @@ patches = [
'name': 'gyp_331',
'path': '../tools/gyp/pylib/',
},
{
# Enable popups in offscreen rendering on OS X.
'name': 'webkit_popups',
'path': '../third_party/WebKit/',
},
{
# Fix export of UnderlayOpenGLHostingWindow for 64-bit OS X builds.
# http://code.google.com/p/chromiumembedded/issues/detail?id=1051
@ -74,9 +79,18 @@ patches = [
{
# Allow customization of the background color with Aura.
# http://code.google.com/p/chromiumembedded/issues/detail?id=1161
'name': 'public_browser_1161',
#
# Allow specification of a custom WebContentsView.
# http://code.google.com/p/chromiumembedded/issues/detail?id=1257
'name': 'public_browser_1161_1257',
'path': '../content/public/browser/',
},
{
# Allow specification of a custom WebContentsView.
# http://code.google.com/p/chromiumembedded/issues/detail?id=1257
'name': 'browser_web_contents_1257',
'path': '../content/browser/web_contents/',
},
{
# Allow customization of the WebView background color.
# http://code.google.com/p/chromiumembedded/issues/detail?id=1161

View File

@ -0,0 +1,78 @@
Index: web_contents_impl.cc
===================================================================
--- web_contents_impl.cc (revision 275973)
+++ web_contents_impl.cc (working copy)
@@ -1059,22 +1059,29 @@
params.browser_context, params.site_instance, params.routing_id,
params.main_frame_routing_id);
- WebContentsViewDelegate* delegate =
- GetContentClient()->browser()->GetWebContentsViewDelegate(this);
+ if (params.view && params.delegate_view) {
+ view_.reset(params.view);
+ render_view_host_delegate_view_ = params.delegate_view;
+ }
- if (browser_plugin_guest_) {
- scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
+ if (!view_) {
+ WebContentsViewDelegate* delegate =
+ GetContentClient()->browser()->GetWebContentsViewDelegate(this);
- WebContentsViewGuest* rv = new WebContentsViewGuest(
- this, browser_plugin_guest_.get(), platform_view.Pass(),
- render_view_host_delegate_view_);
- render_view_host_delegate_view_ = rv;
- view_.reset(rv);
- } else {
- // Regular WebContentsView.
- view_.reset(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
+ if (browser_plugin_guest_) {
+ scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
+ this, delegate, &render_view_host_delegate_view_));
+
+ WebContentsViewGuest* rv = new WebContentsViewGuest(
+ this, browser_plugin_guest_.get(), platform_view.Pass(),
+ render_view_host_delegate_view_);
+ render_view_host_delegate_view_ = rv;
+ view_.reset(rv);
+ } else {
+ // Regular WebContentsView.
+ view_.reset(CreateWebContentsView(
+ this, delegate, &render_view_host_delegate_view_));
+ }
}
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
@@ -1381,6 +1388,9 @@
static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
+ content::WebContentsView* view = NULL;
+ content::RenderViewHostDelegateView* delegate_view = NULL;
+
if (delegate_ &&
!delegate_->ShouldCreateWebContents(this,
route_id,
@@ -1388,7 +1398,9 @@
params.frame_name,
params.target_url,
partition_id,
- session_storage_namespace)) {
+ session_storage_namespace,
+ &view,
+ &delegate_view)) {
if (route_id != MSG_ROUTING_NONE &&
!RenderViewHost::FromID(render_process_id, route_id)) {
// If the embedder didn't create a WebContents for this route, we need to
@@ -1408,6 +1420,8 @@
create_params.main_frame_routing_id = main_frame_route_id;
create_params.opener = this;
create_params.opener_suppressed = params.opener_suppressed;
+ create_params.view = view;
+ create_params.delegate_view = delegate_view;
if (params.disposition == NEW_BACKGROUND_TAB)
create_params.initially_hidden = true;

View File

@ -1,37 +0,0 @@
Index: content_browser_client.cc
===================================================================
--- content_browser_client.cc (revision 275973)
+++ content_browser_client.cc (working copy)
@@ -252,6 +252,10 @@
return true;
}
+SkColor ContentBrowserClient::GetBaseBackgroundColor(RenderViewHost* rvh) {
+ return SK_ColorWHITE;
+}
+
base::FilePath ContentBrowserClient::GetDefaultDownloadDirectory() {
return base::FilePath();
}
Index: content_browser_client.h
===================================================================
--- content_browser_client.h (revision 275973)
+++ content_browser_client.h (working copy)
@@ -23,6 +23,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/base/window_open_disposition.h"
#include "webkit/browser/fileapi/file_system_context.h"
@@ -533,6 +534,9 @@
// Clears browser cookies.
virtual void ClearCookies(RenderViewHost* rvh) {}
+ // Returns the base background color.
+ virtual SkColor GetBaseBackgroundColor(RenderViewHost* rvh);
+
// Returns the default download directory.
// This can be called on any thread.
virtual base::FilePath GetDefaultDownloadDirectory();

View File

@ -0,0 +1,132 @@
Index: content_browser_client.cc
===================================================================
--- content_browser_client.cc (revision 275973)
+++ content_browser_client.cc (working copy)
@@ -252,6 +252,10 @@
return true;
}
+SkColor ContentBrowserClient::GetBaseBackgroundColor(RenderViewHost* rvh) {
+ return SK_ColorWHITE;
+}
+
base::FilePath ContentBrowserClient::GetDefaultDownloadDirectory() {
return base::FilePath();
}
Index: content_browser_client.h
===================================================================
--- content_browser_client.h (revision 275973)
+++ content_browser_client.h (working copy)
@@ -23,6 +23,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/base/window_open_disposition.h"
#include "webkit/browser/fileapi/file_system_context.h"
@@ -533,6 +534,9 @@
// Clears browser cookies.
virtual void ClearCookies(RenderViewHost* rvh) {}
+ // Returns the base background color.
+ virtual SkColor GetBaseBackgroundColor(RenderViewHost* rvh);
+
// Returns the default download directory.
// This can be called on any thread.
virtual base::FilePath GetDefaultDownloadDirectory();
Index: web_contents.cc
===================================================================
--- web_contents.cc (revision 275973)
+++ web_contents.cc (working copy)
@@ -17,7 +17,9 @@
main_frame_routing_id(MSG_ROUTING_NONE),
initially_hidden(false),
guest_instance_id(0),
- context(NULL) {}
+ context(NULL),
+ view(NULL),
+ delegate_view(NULL) {}
WebContents::CreateParams::CreateParams(
BrowserContext* context, SiteInstance* site)
@@ -29,7 +31,9 @@
main_frame_routing_id(MSG_ROUTING_NONE),
initially_hidden(false),
guest_instance_id(0),
- context(NULL) {}
+ context(NULL),
+ view(NULL),
+ delegate_view(NULL) {}
WebContents::CreateParams::~CreateParams() {
}
Index: web_contents.h
===================================================================
--- web_contents.h (revision 275973)
+++ web_contents.h (working copy)
@@ -50,9 +50,11 @@
class RenderFrameHost;
class RenderProcessHost;
class RenderViewHost;
+class RenderViewHostDelegateView;
class RenderWidgetHostView;
class SiteInstance;
class WebContentsDelegate;
+class WebContentsView;
struct CustomContextMenuContext;
struct DropData;
struct RendererPreferences;
@@ -120,6 +122,10 @@
// Used to specify the location context which display the new view should
// belong. This can be NULL if not needed.
gfx::NativeView context;
+
+ // Optionally specify the view and delegate view.
+ content::WebContentsView* view;
+ content::RenderViewHostDelegateView* delegate_view;
};
// Creates a new WebContents.
Index: web_contents_delegate.cc
===================================================================
--- web_contents_delegate.cc (revision 275973)
+++ web_contents_delegate.cc (working copy)
@@ -136,7 +136,9 @@
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
- SessionStorageNamespace* session_storage_namespace) {
+ SessionStorageNamespace* session_storage_namespace,
+ content::WebContentsView** view,
+ content::RenderViewHostDelegateView** delegate_view) {
return true;
}
Index: web_contents_delegate.h
===================================================================
--- web_contents_delegate.h (revision 275973)
+++ web_contents_delegate.h (working copy)
@@ -36,9 +36,11 @@
class JavaScriptDialogManager;
class PageState;
class RenderViewHost;
+class RenderViewHostDelegateView;
class SessionStorageNamespace;
class WebContents;
class WebContentsImpl;
+class WebContentsView;
struct ColorSuggestion;
struct ContextMenuParams;
struct DropData;
@@ -312,7 +314,9 @@
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
- SessionStorageNamespace* session_storage_namespace);
+ SessionStorageNamespace* session_storage_namespace,
+ content::WebContentsView** view,
+ content::RenderViewHostDelegateView** delegate_view);
// Notifies the delegate about the creation of a new WebContents. This
// typically happens when popups are created.

View File

@ -11,6 +11,20 @@ Index: desktop_aura/desktop_screen_win.cc
aura::WindowTreeHost* host = window->GetHost();
return host ? host->GetAcceleratedWidget() : NULL;
}
Index: desktop_aura/desktop_screen_x11.cc
===================================================================
--- desktop_aura/desktop_screen_x11.cc (revision 275973)
+++ desktop_aura/desktop_screen_x11.cc (working copy)
@@ -220,6 +220,9 @@
gfx::Display DesktopScreenX11::GetDisplayNearestWindow(
gfx::NativeView window) const {
+ if (!window)
+ return GetPrimaryDisplay();
+
// Getting screen bounds here safely is hard.
//
// You'd think we'd be able to just call window->GetBoundsInScreen(), but we
Index: desktop_aura/desktop_window_tree_host_win.cc
===================================================================
--- desktop_aura/desktop_window_tree_host_win.cc (revision 275973)

View File

@ -0,0 +1,76 @@
Index: public/web/WebView.h
===================================================================
--- public/web/WebView.h (revision 175829)
+++ public/web/WebView.h (working copy)
@@ -416,6 +416,7 @@
// Sets whether select popup menus should be rendered by the browser.
BLINK_EXPORT static void setUseExternalPopupMenus(bool);
+ virtual void setUseExternalPopupMenusThisInstance(bool) = 0;
// Hides any popup (suggestions, selects...) that might be showing.
virtual void hidePopups() = 0;
Index: Source/web/ChromeClientImpl.cpp
===================================================================
--- Source/web/ChromeClientImpl.cpp (revision 175829)
+++ Source/web/ChromeClientImpl.cpp (working copy)
@@ -729,7 +729,7 @@
PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(LocalFrame& frame, PopupMenuClient* client) const
{
- if (WebViewImpl::useExternalPopupMenus())
+ if (m_webView->useExternalPopupMenus())
return adoptRef(new ExternalPopupMenu(frame, client, *m_webView));
return adoptRef(new PopupMenuChromium(frame, client));
Index: Source/web/WebViewImpl.cpp
===================================================================
--- Source/web/WebViewImpl.cpp (revision 175829)
+++ Source/web/WebViewImpl.cpp (working copy)
@@ -365,6 +365,7 @@
, m_fakePageScaleAnimationPageScaleFactor(0)
, m_fakePageScaleAnimationUseAnchor(false)
, m_contextMenuAllowed(false)
+ , m_shouldUseExternalPopupMenus(shouldUseExternalPopupMenus)
, m_doingDragAndDrop(false)
, m_ignoreInputEvents(false)
, m_compositorDeviceScaleFactorOverride(0)
@@ -3628,9 +3629,14 @@
updateLayerTreeViewport();
}
+void WebViewImpl::setUseExternalPopupMenusThisInstance(bool useExternalPopupMenus)
+{
+ m_shouldUseExternalPopupMenus = useExternalPopupMenus;
+}
+
bool WebViewImpl::useExternalPopupMenus()
{
- return shouldUseExternalPopupMenus;
+ return m_shouldUseExternalPopupMenus;
}
void WebViewImpl::startDragging(LocalFrame* frame,
Index: Source/web/WebViewImpl.h
===================================================================
--- Source/web/WebViewImpl.h (revision 175829)
+++ Source/web/WebViewImpl.h (working copy)
@@ -352,7 +352,8 @@
// Returns true if popup menus should be rendered by the browser, false if
// they should be rendered by WebKit (which is the default).
- static bool useExternalPopupMenus();
+ void setUseExternalPopupMenusThisInstance(bool);
+ bool useExternalPopupMenus();
bool contextMenuAllowed() const
{
@@ -628,6 +629,8 @@
bool m_contextMenuAllowed;
+ bool m_shouldUseExternalPopupMenus;
+
bool m_doingDragAndDrop;
bool m_ignoreInputEvents;

View File

@ -0,0 +1,95 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/bytes_write_handler.h"
#include <cstdio>
#include <cstdlib>
#include "cefclient/util.h"
BytesWriteHandler::BytesWriteHandler(size_t grow)
: grow_(grow),
datasize_(grow),
offset_(0) {
ASSERT(grow > 0); // NOLINT(readability/check)
data_ = malloc(grow);
ASSERT(data_ != NULL);
}
BytesWriteHandler::~BytesWriteHandler() {
AutoLock lock_scope(this);
if (data_)
free(data_);
}
size_t BytesWriteHandler::Write(const void* ptr, size_t size, size_t n) {
AutoLock lock_scope(this);
size_t rv;
if (offset_ + static_cast<int64>(size * n) >= datasize_ &&
Grow(size * n) == 0) {
rv = 0;
} else {
memcpy(reinterpret_cast<char*>(data_) + offset_, ptr, size * n);
offset_ += size * n;
rv = n;
}
return rv;
}
int BytesWriteHandler::Seek(int64 offset, int whence) {
int rv = -1L;
AutoLock lock_scope(this);
switch (whence) {
case SEEK_CUR:
if (offset_ + offset > datasize_ || offset_ + offset < 0)
break;
offset_ += offset;
rv = 0;
break;
case SEEK_END: {
int64 offset_abs = std::abs(offset);
if (offset_abs > datasize_)
break;
offset_ = datasize_ - offset_abs;
rv = 0;
break;
}
case SEEK_SET:
if (offset > datasize_ || offset < 0)
break;
offset_ = offset;
rv = 0;
break;
}
return rv;
}
int64 BytesWriteHandler::Tell() {
AutoLock lock_scope(this);
return offset_;
}
int BytesWriteHandler::Flush() {
return 0;
}
size_t BytesWriteHandler::Grow(size_t size) {
AutoLock lock_scope(this);
size_t rv;
size_t s = (size > grow_ ? size : grow_);
void* tmp = realloc(data_, datasize_ + s);
ASSERT(tmp != NULL);
if (tmp) {
data_ = tmp;
datasize_ += s;
rv = datasize_;
} else {
rv = 0;
}
return rv;
}

View File

@ -0,0 +1,37 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_
#define CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_
#pragma once
#include "include/cef_stream.h"
class BytesWriteHandler : public CefWriteHandler {
public:
explicit BytesWriteHandler(size_t grow);
virtual ~BytesWriteHandler();
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE;
virtual int Seek(int64 offset, int whence) OVERRIDE;
virtual int64 Tell() OVERRIDE;
virtual int Flush() OVERRIDE;
virtual bool MayBlock() OVERRIDE { return false; }
void* GetData() { return data_; }
int64 GetDataSize() { return offset_; }
protected:
size_t Grow(size_t size);
size_t grow_;
void* data_;
int64 datasize_;
int64 offset_;
IMPLEMENT_REFCOUNTING(BytesWriteHandler);
IMPLEMENT_LOCKING(BytesWriteHandler);
};
#endif // CEF_TESTS_CEFCLIENT_BYTES_WRITE_HANDLER_H_

View File

@ -62,6 +62,28 @@ void AppGetSettings(CefSettings& settings) {
CefString(&settings.cache_path) =
g_command_line->GetSwitchValue(cefclient::kCachePath);
if (g_command_line->HasSwitch(cefclient::kOffScreenRenderingEnabled))
settings.windowless_rendering_enabled = true;
}
void AppGetBrowserSettings(CefBrowserSettings& settings) {
ASSERT(g_command_line.get());
if (!g_command_line.get())
return;
if (g_command_line->HasSwitch(cefclient::kOffScreenFrameRate)) {
settings.windowless_frame_rate = atoi(g_command_line->
GetSwitchValue(cefclient::kOffScreenFrameRate).ToString().c_str());
}
}
bool AppIsOffScreenRenderingEnabled() {
ASSERT(g_command_line.get());
if (!g_command_line.get())
return false;
return g_command_line->HasSwitch(cefclient::kOffScreenRenderingEnabled);
}
void RunGetSourceTest(CefRefPtr<CefBrowser> browser) {

View File

@ -32,6 +32,11 @@ CefRefPtr<CefCommandLine> AppGetCommandLine();
// Returns the application settings based on command line arguments.
void AppGetSettings(CefSettings& settings);
void AppGetBrowserSettings(CefBrowserSettings& settings);
// Returns true if off-screen rendering is enabled via the command line
// argument.
bool AppIsOffScreenRenderingEnabled();
// Quit the application message loop.
void AppQuitMessageLoop();

View File

@ -33,6 +33,7 @@ IDS_DIALOGS BINARY "res\\dialogs.html"
IDS_DOMACCESS BINARY "res\\domaccess.html"
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
IDS_LOGO BINARY "res\\logo.png"
IDS_OSRTEST BINARY "res\\osr_test.html"
IDS_OTHER_TESTS BINARY "res\\other_tests.html"
IDS_PERFORMANCE BINARY "res\\performance.html"
IDS_PERFORMANCE2 BINARY "res\\performance2.html"

View File

@ -2,13 +2,10 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
// This value is defined in build/common.gypi and must be undefined here
// in order for gtkglext to compile.
#undef GTK_DISABLE_SINGLE_INCLUDES
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <X11/Xlib.h>
#undef Success // Definition conflicts with cef_message_router.h
@ -22,10 +19,12 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_runnable.h"
#include "cefclient/cefclient_osr_widget_gtk.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
#include "cefclient/scheme_test.h"
#include "cefclient/string_util.h"
#include "cefclient/util.h"
// The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler;
@ -37,6 +36,15 @@ char szWorkingDir[512]; // The current working directory
// Height of the buttons at the top of the GTK window.
int g_toolbar_height = 0;
class MainBrowserProvider : public OSRBrowserProvider {
virtual CefRefPtr<CefBrowser> GetBrowser() {
if (g_handler.get())
return g_handler->GetBrowser();
return NULL;
}
} g_main_browser_provider;
void destroy(GtkWidget* widget, gpointer data) {
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
}
@ -69,7 +77,7 @@ void VboxSizeAllocated(GtkWidget *widget,
void *data) {
if (g_handler) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser) {
if (browser && !browser->GetHost()->IsWindowRenderingDisabled()) {
// Size the browser window to match the GTK widget.
::Display* xdisplay = cef_get_xdisplay();
::Window xwindow = browser->GetHost()->GetWindowHandle();
@ -93,9 +101,14 @@ gboolean WindowFocusIn(GtkWidget* widget,
if (g_handler && event->in) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser) {
// Give focus to the browser window.
browser->GetHost()->SetFocus(true);
return TRUE;
if (browser->GetHost()->IsWindowRenderingDisabled()) {
// Give focus to the off-screen browser.
browser->GetHost()->SendFocusEvent(true);
} else {
// Give focus to the browser window.
browser->GetHost()->SetFocus(true);
return TRUE;
}
}
}
@ -303,6 +316,11 @@ GtkWidget* CreateMenuBar() {
} // namespace
int main(int argc, char* argv[]) {
// Create a copy of |argv| on Linux because Chromium mangles the value
// internally (see issue #620).
ScopedArgArray scoped_arg_array(argc, argv);
char** argv_copy = scoped_arg_array.array();
CefMainArgs main_args(argc, argv);
CefRefPtr<ClientApp> app(new ClientApp);
@ -315,7 +333,7 @@ int main(int argc, char* argv[]) {
return -1;
// Parse command line arguments.
AppInitCommandLine(argc, argv);
AppInitCommandLine(argc, argv_copy);
CefSettings settings;
@ -327,7 +345,10 @@ int main(int argc, char* argv[]) {
// The Chromium sandbox requires that there only be a single thread during
// initialization. Therefore initialize GTK after CEF.
gtk_init(&argc, &argv);
gtk_init(&argc, &argv_copy);
// Perform gtkglext initialization required by the OSR example.
gtk_gl_init(&argc, &argv_copy);
// Register the scheme handler.
scheme_test::InitTest();
@ -397,16 +418,38 @@ int main(int argc, char* argv[]) {
g_handler->SetButtonHwnds(GTK_WIDGET(back), GTK_WIDGET(forward),
GTK_WIDGET(reload), GTK_WIDGET(stop));
// Show the GTK window.
gtk_widget_show_all(GTK_WIDGET(window));
CefWindowInfo window_info;
CefBrowserSettings browserSettings;
// The GTK window must be visible before we can retrieve the XID.
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
window_info.SetAsChild(xwindow,
CefRect(0, g_toolbar_height, 800, 600 - g_toolbar_height));
// Populate the browser settings based on command line arguments.
AppGetBrowserSettings(browserSettings);
if (AppIsOffScreenRenderingEnabled()) {
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
bool transparent =
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
// Create the GTKGL surface.
CefRefPtr<OSRWindow> osr_window =
OSRWindow::Create(&g_main_browser_provider, transparent, vbox);
// Show the GTK window.
gtk_widget_show_all(GTK_WIDGET(window));
// The GTK window must be visible before we can retrieve the XID.
::Window xwindow =
GDK_WINDOW_XID(gtk_widget_get_window(osr_window->GetWindowHandle()));
window_info.SetAsWindowless(xwindow, transparent);
g_handler->SetOSRHandler(osr_window.get());
} else {
// Show the GTK window.
gtk_widget_show_all(GTK_WIDGET(window));
// The GTK window must be visible before we can retrieve the XID.
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
window_info.SetAsChild(xwindow,
CefRect(0, g_toolbar_height, 800, 600 - g_toolbar_height));
}
// Create the browser window.
CefBrowserHost::CreateBrowserSync(

View File

@ -11,6 +11,7 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_runnable.h"
#include "cefclient/cefclient_osr_widget_mac.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
#include "cefclient/resource_util.h"
@ -20,6 +21,15 @@
// The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler;
class MainBrowserProvider : public OSRBrowserProvider {
virtual CefRefPtr<CefBrowser> GetBrowser() {
if (g_handler.get())
return g_handler->GetBrowser();
return NULL;
}
} g_main_browser_provider;
char szWorkingDir[512]; // The current working directory
// Sizes for URL bar layout
@ -206,8 +216,12 @@ const int kWindowHeight = 600;
- (void)windowDidBecomeKey:(NSNotification*)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetFocus(true);
if (browser.get()) {
if (AppIsOffScreenRenderingEnabled())
browser->GetHost()->SendFocusEvent(true);
else
browser->GetHost()->SetFocus(true);
}
}
}
@ -215,8 +229,12 @@ const int kWindowHeight = 600;
- (void)windowDidResignKey:(NSNotification*)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetFocus(false);
if (browser.get()) {
if (AppIsOffScreenRenderingEnabled())
browser->GetHost()->SendFocusEvent(false);
else
browser->GetHost()->SetFocus(false);
}
}
}
@ -436,8 +454,23 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
CefWindowInfo window_info;
CefBrowserSettings settings;
// Initialize window info to the defaults for a child window.
window_info.SetAsChild(contentView, 0, 0, kWindowWidth, kWindowHeight);
// Populate the browser settings based on command line arguments.
AppGetBrowserSettings(settings);
if (AppIsOffScreenRenderingEnabled()) {
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
bool transparent =
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
CefRefPtr<OSRWindow> osr_window =
OSRWindow::Create(&g_main_browser_provider, transparent, contentView,
CefRect(0, 0, kWindowWidth, kWindowHeight));
window_info.SetAsWindowless(osr_window->GetWindowHandle(), transparent);
g_handler->SetOSRHandler(osr_window->GetRenderHandler().get());
} else {
// Initialize window info to the defaults for a child window.
window_info.SetAsChild(contentView, 0, 0, kWindowWidth, kWindowHeight);
}
CefBrowserHost::CreateBrowser(window_info, g_handler.get(),
g_handler->GetStartupURL(), settings, NULL);

View File

@ -0,0 +1,649 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/cefclient_osr_dragdrop_win.h"
#include <shellapi.h>
#include <shlobj.h>
#include <windowsx.h>
#include <algorithm>
#include <string>
#include "include/cef_runnable.h"
#include "cefclient/bytes_write_handler.h"
#include "cefclient/cefclient_osr_widget_win.h"
#include "cefclient/resource.h"
#include "cefclient/util.h"
namespace {
DWORD DragOperationToDropEffect(CefRenderHandler::DragOperation allowed_ops) {
DWORD effect = DROPEFFECT_NONE;
if (allowed_ops & DRAG_OPERATION_COPY)
effect |= DROPEFFECT_COPY;
if (allowed_ops & DRAG_OPERATION_LINK)
effect |= DROPEFFECT_LINK;
if (allowed_ops & DRAG_OPERATION_MOVE)
effect |= DROPEFFECT_MOVE;
return effect;
}
CefRenderHandler::DragOperationsMask DropEffectToDragOperation(DWORD effect) {
DWORD operation = DRAG_OPERATION_NONE;
if (effect & DROPEFFECT_COPY)
operation |= DRAG_OPERATION_COPY;
if (effect & DROPEFFECT_LINK)
operation |= DRAG_OPERATION_LINK;
if (effect & DROPEFFECT_MOVE)
operation |= DRAG_OPERATION_MOVE;
return static_cast<CefRenderHandler::DragOperationsMask>(operation);
}
CefMouseEvent ToMouseEvent(POINTL p, DWORD key_state, HWND hWnd) {
CefMouseEvent ev;
POINT screen_point = { p.x, p.y };
ScreenToClient(hWnd, &screen_point);
ev.x = screen_point.x;
ev.y = screen_point.y;
ev.modifiers = OSRWindow::GetCefMouseModifiers(key_state);
return ev;
}
void GetStorageForBytes(STGMEDIUM* storage, const void* data, size_t bytes) {
HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes));
if (handle) {
memcpy(handle, data, bytes);
}
storage->hGlobal = handle;
storage->tymed = TYMED_HGLOBAL;
storage->pUnkForRelease = NULL;
}
template <typename T>
void GetStorageForString(STGMEDIUM* stgmed, const std::basic_string<T>& data) {
GetStorageForBytes(stgmed, data.c_str(),
(data.size() + 1) * sizeof(std::basic_string<T>::value_type));
}
void GetStorageForFileDescriptor(STGMEDIUM* storage,
const std::wstring& file_name) {
ASSERT(!file_name.empty());
HANDLE hdata = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
FILEGROUPDESCRIPTOR* descriptor =
reinterpret_cast<FILEGROUPDESCRIPTOR*>(hdata);
descriptor->cItems = 1;
descriptor->fgd[0].dwFlags = FD_LINKUI;
wcsncpy_s(descriptor->fgd[0].cFileName, MAX_PATH, file_name.c_str(),
std::min(file_name.size(), static_cast<size_t>(MAX_PATH - 1u)));
storage->tymed = TYMED_HGLOBAL;
storage->hGlobal = hdata;
storage->pUnkForRelease = NULL;
}
// Helper method for converting from text/html to MS CF_HTML.
// Documentation for the CF_HTML format is available at
// http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx
std::string HtmlToCFHtml(const std::string& html, const std::string& base_url) {
if (html.empty())
return std::string();
#define MAX_DIGITS 10
#define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits)
#define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u"
#define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS)
static const char* header = "Version:0.9\r\n"
"StartHTML:" NUMBER_FORMAT "\r\n"
"EndHTML:" NUMBER_FORMAT "\r\n"
"StartFragment:" NUMBER_FORMAT "\r\n"
"EndFragment:" NUMBER_FORMAT "\r\n";
static const char* source_url_prefix = "SourceURL:";
static const char* start_markup = "<html>\r\n<body>\r\n<!--StartFragment-->";
static const char* end_markup = "<!--EndFragment-->\r\n</body>\r\n</html>";
// Calculate offsets
size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 +
MAX_DIGITS * 4;
if (!base_url.empty()) {
start_html_offset += strlen(source_url_prefix) + base_url.length()
+ 2; // Add 2 for \r\n.
}
size_t start_fragment_offset = start_html_offset + strlen(start_markup);
size_t end_fragment_offset = start_fragment_offset + html.length();
size_t end_html_offset = end_fragment_offset + strlen(end_markup);
char raw_result[1024];
_snprintf(raw_result, sizeof(1024),
header,
start_html_offset,
end_html_offset,
start_fragment_offset,
end_fragment_offset);
std::string result = raw_result;
if (!base_url.empty()) {
result.append(source_url_prefix);
result.append(base_url);
result.append("\r\n");
}
result.append(start_markup);
result.append(html);
result.append(end_markup);
#undef MAX_DIGITS
#undef MAKE_NUMBER_FORMAT_1
#undef MAKE_NUMBER_FORMAT_2
#undef NUMBER_FORMAT
return result;
}
void CFHtmlExtractMetadata(const std::string& cf_html,
std::string* base_url,
size_t* html_start,
size_t* fragment_start,
size_t* fragment_end) {
// Obtain base_url if present.
if (base_url) {
static std::string src_url_str("SourceURL:");
size_t line_start = cf_html.find(src_url_str);
if (line_start != std::string::npos) {
size_t src_end = cf_html.find("\n", line_start);
size_t src_start = line_start + src_url_str.length();
if (src_end != std::string::npos && src_start != std::string::npos) {
*base_url = cf_html.substr(src_start, src_end - src_start);
}
}
}
// Find the markup between "<!--StartFragment-->" and "<!--EndFragment-->".
// If the comments cannot be found, like copying from OpenOffice Writer,
// we simply fall back to using StartFragment/EndFragment bytecount values
// to determine the fragment indexes.
std::string cf_html_lower = cf_html;
size_t markup_start = cf_html_lower.find("<html", 0);
if (html_start) {
*html_start = markup_start;
}
size_t tag_start = cf_html.find("<!--StartFragment", markup_start);
if (tag_start == std::string::npos) {
static std::string start_fragment_str("StartFragment:");
size_t start_fragment_start = cf_html.find(start_fragment_str);
if (start_fragment_start != std::string::npos) {
*fragment_start = static_cast<size_t>(atoi(cf_html.c_str() +
start_fragment_start + start_fragment_str.length()));
}
static std::string end_fragment_str("EndFragment:");
size_t end_fragment_start = cf_html.find(end_fragment_str);
if (end_fragment_start != std::string::npos) {
*fragment_end = static_cast<size_t>(atoi(cf_html.c_str() +
end_fragment_start + end_fragment_str.length()));
}
} else {
*fragment_start = cf_html.find('>', tag_start) + 1;
size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos);
*fragment_end = cf_html.rfind('<', tag_end);
}
}
void CFHtmlToHtml(const std::string& cf_html,
std::string* html,
std::string* base_url) {
size_t frag_start = std::string::npos;
size_t frag_end = std::string::npos;
CFHtmlExtractMetadata(cf_html, base_url, NULL, &frag_start, &frag_end);
if (html && frag_start != std::string::npos &&
frag_end != std::string::npos) {
*html = cf_html.substr(frag_start, frag_end - frag_start);
}
}
const DWORD moz_url_format = ::RegisterClipboardFormat(L"text/x-moz-url");
const DWORD html_format = ::RegisterClipboardFormat(L"HTML Format");
const DWORD file_desc_format =
::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
const DWORD file_contents_format =
::RegisterClipboardFormat(CFSTR_FILECONTENTS);
bool DragDataToDataObject(CefRefPtr<CefDragData> drag_data,
IDataObject** data_object) {
const int kMaxDataObjects = 10;
FORMATETC fmtetcs[kMaxDataObjects];
STGMEDIUM stgmeds[kMaxDataObjects];
FORMATETC fmtetc = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
int curr_index = 0;
CefString text = drag_data->GetFragmentText();
if (!text.empty()) {
fmtetc.cfFormat = CF_UNICODETEXT;
fmtetcs[curr_index] = fmtetc;
GetStorageForString(&stgmeds[curr_index], text.ToWString());
curr_index++;
}
if (drag_data->IsLink() && !drag_data->GetLinkURL().empty()) {
std::wstring x_moz_url_str = drag_data->GetLinkURL().ToWString();
x_moz_url_str += '\n';
x_moz_url_str += drag_data->GetLinkTitle().ToWString();
fmtetc.cfFormat = moz_url_format;
fmtetcs[curr_index] = fmtetc;
GetStorageForString(&stgmeds[curr_index], x_moz_url_str);
curr_index++;
}
CefString html = drag_data->GetFragmentHtml();
if (!html.empty()) {
CefString base_url = drag_data->GetFragmentBaseURL();
std::string cfhtml = HtmlToCFHtml(html.ToString(), base_url.ToString());
fmtetc.cfFormat = html_format;
fmtetcs[curr_index] = fmtetc;
GetStorageForString(&stgmeds[curr_index], cfhtml);
curr_index++;
}
size_t bufferSize = drag_data->GetFileContents(NULL);
if (bufferSize) {
CefRefPtr<BytesWriteHandler> handler = new BytesWriteHandler(bufferSize);
CefRefPtr<CefStreamWriter> writer =
CefStreamWriter::CreateForHandler(handler.get());
drag_data->GetFileContents(writer);
ASSERT(handler->GetDataSize() == static_cast<int64>(bufferSize));
CefString fileName = drag_data->GetFileName();
GetStorageForFileDescriptor(&stgmeds[curr_index], fileName.ToWString());
fmtetc.cfFormat = file_desc_format;
fmtetcs[curr_index] = fmtetc;
curr_index++;
GetStorageForBytes(&stgmeds[curr_index], handler->GetData(),
handler->GetDataSize());
fmtetc.cfFormat = file_contents_format;
fmtetcs[curr_index] = fmtetc;
curr_index++;
}
ASSERT(curr_index < kMaxDataObjects);
CComPtr<IDataObject> obj =
DataObjectWin::Create(fmtetcs, stgmeds, curr_index);
(*data_object) = obj.Detach();
return true;
}
CefRefPtr<CefDragData> DataObjectToDragData(IDataObject* data_object) {
CefRefPtr<CefDragData> drag_data = CefDragData::Create();
IEnumFORMATETC* enumFormats = NULL;
HRESULT res = data_object->EnumFormatEtc(DATADIR_GET, &enumFormats);
if (res != S_OK)
return drag_data;
enumFormats->Reset();
const int kCelt = 10;
ULONG celtFetched;
do {
celtFetched = kCelt;
FORMATETC rgelt[kCelt];
res = enumFormats->Next(kCelt, rgelt, &celtFetched);
for (unsigned i = 0; i < celtFetched; i++) {
CLIPFORMAT format = rgelt[i].cfFormat;
if (!(format == CF_UNICODETEXT ||
format == CF_TEXT ||
format == moz_url_format ||
format == html_format ||
format == CF_HDROP)
|| rgelt[i].tymed != TYMED_HGLOBAL)
continue;
STGMEDIUM medium;
if (data_object->GetData(&rgelt[i], &medium) == S_OK) {
if (!medium.hGlobal) {
ReleaseStgMedium(&medium);
continue;
}
void* hGlobal = GlobalLock(medium.hGlobal);
if (!hGlobal) {
ReleaseStgMedium(&medium);
continue;
}
if (format == CF_UNICODETEXT) {
CefString text;
text.FromWString((std::wstring::value_type*)hGlobal);
drag_data->SetFragmentText(text);
} else if (format == CF_TEXT) {
CefString text;
text.FromString((std::string::value_type*)hGlobal);
drag_data->SetFragmentText(text);
} else if (format == moz_url_format) {
std::wstring html((std::wstring::value_type*)hGlobal);
size_t pos = html.rfind('\n');
CefString url(html.substr(0, pos));
CefString title(html.substr(pos + 1));
drag_data->SetLinkURL(url);
drag_data->SetLinkTitle(title);
} else if (format == html_format) {
std::string cf_html((std::string::value_type*)hGlobal);
std::string base_url;
std::string html;
CFHtmlToHtml(cf_html, &html, &base_url);
drag_data->SetFragmentHtml(html);
drag_data->SetFragmentBaseURL(base_url);
}
if (format == CF_HDROP) {
HDROP hdrop = (HDROP)hGlobal;
const int kMaxFilenameLen = 4096;
const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0);
for (unsigned int i = 0; i < num_files; ++i) {
wchar_t filename[kMaxFilenameLen];
if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen))
continue;
WCHAR* name = wcsrchr(filename, '\\');
drag_data->AddFile(filename, (name ? name + 1 : filename));
}
}
if (medium.hGlobal)
GlobalUnlock(medium.hGlobal);
if (format == CF_HDROP)
DragFinish((HDROP)hGlobal);
else
ReleaseStgMedium(&medium);
}
}
} while (res == S_OK);
enumFormats->Release();
return drag_data;
}
} // namespace
CComPtr<DropTargetWin> DropTargetWin::Create(DragEvents* callback, HWND hWnd) {
return CComPtr<DropTargetWin>(new DropTargetWin(callback, hWnd));
}
HRESULT DropTargetWin::DragEnter(IDataObject* data_object,
DWORD key_state,
POINTL cursor_position,
DWORD* effect) {
if (!callback_)
return E_UNEXPECTED;
CefRefPtr<CefDragData> drag_data = current_drag_data_;
if (!drag_data) {
drag_data = DataObjectToDragData(data_object);
}
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
mask = callback_->OnDragEnter(drag_data, ev, mask);
*effect = DragOperationToDropEffect(mask);
return S_OK;
}
CefBrowserHost::DragOperationsMask DropTargetWin::StartDragging(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) {
CComPtr<IDataObject> dataObject;
DWORD resEffect = DROPEFFECT_NONE;
if (DragDataToDataObject(drag_data, &dataObject)) {
CComPtr<IDropSource> dropSource = DropSourceWin::Create();
DWORD effect = DragOperationToDropEffect(allowed_ops);
current_drag_data_ = drag_data->Clone();
current_drag_data_->ResetFileContents();
HRESULT res = DoDragDrop(dataObject, dropSource, effect, &resEffect);
if (res != DRAGDROP_S_DROP)
resEffect = DROPEFFECT_NONE;
current_drag_data_ = NULL;
}
return DropEffectToDragOperation(resEffect);
}
HRESULT DropTargetWin::DragOver(DWORD key_state,
POINTL cursor_position,
DWORD* effect) {
if (!callback_)
return E_UNEXPECTED;
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
mask = callback_->OnDragOver(ev, mask);
*effect = DragOperationToDropEffect(mask);
return S_OK;
}
HRESULT DropTargetWin::DragLeave() {
if (!callback_)
return E_UNEXPECTED;
callback_->OnDragLeave();
return S_OK;
}
HRESULT DropTargetWin::Drop(IDataObject* data_object,
DWORD key_state,
POINTL cursor_position,
DWORD* effect) {
if (!callback_)
return E_UNEXPECTED;
CefMouseEvent ev = ToMouseEvent(cursor_position, key_state, hWnd_);
CefBrowserHost::DragOperationsMask mask = DropEffectToDragOperation(*effect);
mask = callback_->OnDrop(ev, mask);
*effect = DragOperationToDropEffect(mask);
return S_OK;
}
CComPtr<DropSourceWin> DropSourceWin::Create() {
return CComPtr<DropSourceWin>(new DropSourceWin());
}
HRESULT DropSourceWin::GiveFeedback(DWORD dwEffect) {
return DRAGDROP_S_USEDEFAULTCURSORS;
}
HRESULT DropSourceWin::QueryContinueDrag(BOOL fEscapePressed,
DWORD grfKeyState) {
if (fEscapePressed) {
return DRAGDROP_S_CANCEL;
}
if (!(grfKeyState & MK_LBUTTON)) {
return DRAGDROP_S_DROP;
}
return S_OK;
}
HRESULT DragEnumFormatEtc::CreateEnumFormatEtc(UINT cfmt,
FORMATETC* afmt,
IEnumFORMATETC** ppEnumFormatEtc) {
if (cfmt == 0 || afmt == 0 || ppEnumFormatEtc == 0)
return E_INVALIDARG;
*ppEnumFormatEtc = new DragEnumFormatEtc(afmt, cfmt);
return (*ppEnumFormatEtc) ? S_OK : E_OUTOFMEMORY;
}
HRESULT DragEnumFormatEtc::Next(ULONG celt,
FORMATETC* pFormatEtc,
ULONG* pceltFetched) {
ULONG copied = 0;
// copy the FORMATETC structures into the caller's buffer
while (m_nIndex < m_nNumFormats && copied < celt) {
DeepCopyFormatEtc(&pFormatEtc[copied], &m_pFormatEtc[m_nIndex]);
copied++;
m_nIndex++;
}
// store result
if (pceltFetched != 0)
*pceltFetched = copied;
// did we copy all that was requested?
return (copied == celt) ? S_OK : S_FALSE;
}
HRESULT DragEnumFormatEtc::Skip(ULONG celt) {
m_nIndex += celt;
return (m_nIndex <= m_nNumFormats) ? S_OK : S_FALSE;
}
HRESULT DragEnumFormatEtc::Reset(void) {
m_nIndex = 0;
return S_OK;
}
HRESULT DragEnumFormatEtc::Clone(IEnumFORMATETC** ppEnumFormatEtc) {
HRESULT hResult;
// make a duplicate enumerator
hResult = CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
if (hResult == S_OK) {
// manually set the index state
reinterpret_cast<DragEnumFormatEtc*>(*ppEnumFormatEtc)->m_nIndex = m_nIndex;
}
return hResult;
}
DragEnumFormatEtc::DragEnumFormatEtc(FORMATETC* pFormatEtc, int nNumFormats) {
AddRef();
m_nIndex = 0;
m_nNumFormats = nNumFormats;
m_pFormatEtc = new FORMATETC[nNumFormats];
// make a new copy of each FORMATETC structure
for (int i = 0; i < nNumFormats; i++) {
DeepCopyFormatEtc(&m_pFormatEtc[i], &pFormatEtc[i]);
}
}
DragEnumFormatEtc::~DragEnumFormatEtc() {
// first free any DVTARGETDEVICE structures
for (ULONG i = 0; i < m_nNumFormats; i++) {
if (m_pFormatEtc[i].ptd)
CoTaskMemFree(m_pFormatEtc[i].ptd);
}
// now free the main array
delete[] m_pFormatEtc;
}
void DragEnumFormatEtc::DeepCopyFormatEtc(FORMATETC* dest, FORMATETC* source) {
// copy the source FORMATETC into dest
*dest = *source;
if (source->ptd) {
// allocate memory for the DVTARGETDEVICE if necessary
dest->ptd = reinterpret_cast<DVTARGETDEVICE*>(
CoTaskMemAlloc(sizeof(DVTARGETDEVICE)));
// copy the contents of the source DVTARGETDEVICE into dest->ptd
*(dest->ptd) = *(source->ptd);
}
}
CComPtr<DataObjectWin> DataObjectWin::Create(FORMATETC* fmtetc,
STGMEDIUM* stgmed,
int count) {
return CComPtr<DataObjectWin>(new DataObjectWin(fmtetc, stgmed, count));
}
HRESULT DataObjectWin::GetDataHere(FORMATETC* pFormatEtc, STGMEDIUM* pmedium) {
return E_NOTIMPL;
}
HRESULT DataObjectWin::QueryGetData(FORMATETC* pFormatEtc) {
return (LookupFormatEtc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
}
HRESULT DataObjectWin::GetCanonicalFormatEtc(FORMATETC* pFormatEct,
FORMATETC* pFormatEtcOut) {
pFormatEtcOut->ptd = NULL;
return E_NOTIMPL;
}
HRESULT DataObjectWin::SetData(FORMATETC* pFormatEtc,
STGMEDIUM* pMedium,
BOOL fRelease) {
return E_NOTIMPL;
}
HRESULT DataObjectWin::DAdvise(FORMATETC* pFormatEtc,
DWORD advf,
IAdviseSink*,
DWORD*) {
return E_NOTIMPL;
}
HRESULT DataObjectWin::DUnadvise(DWORD dwConnection) {
return E_NOTIMPL;
}
HRESULT DataObjectWin::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise) {
return E_NOTIMPL;
}
HRESULT DataObjectWin::EnumFormatEtc(DWORD dwDirection,
IEnumFORMATETC** ppEnumFormatEtc) {
return DragEnumFormatEtc::CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc,
ppEnumFormatEtc);
}
HRESULT DataObjectWin::GetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium) {
int idx;
// try to match the specified FORMATETC with one of our supported formats
if ((idx = LookupFormatEtc(pFormatEtc)) == -1)
return DV_E_FORMATETC;
// found a match - transfer data into supplied storage medium
pMedium->tymed = m_pFormatEtc[idx].tymed;
pMedium->pUnkForRelease = 0;
// copy the data into the caller's storage medium
switch (m_pFormatEtc[idx].tymed) {
case TYMED_HGLOBAL:
pMedium->hGlobal = DupGlobalMem(m_pStgMedium[idx].hGlobal);
break;
default:
return DV_E_FORMATETC;
}
return S_OK;
}
HGLOBAL DataObjectWin::DupGlobalMem(HGLOBAL hMem) {
DWORD len = GlobalSize(hMem);
PVOID source = GlobalLock(hMem);
PVOID dest = GlobalAlloc(GMEM_FIXED, len);
memcpy(dest, source, len);
GlobalUnlock(hMem);
return dest;
}
int DataObjectWin::LookupFormatEtc(FORMATETC* pFormatEtc) {
// check each of our formats in turn to see if one matches
for (int i = 0; i < m_nNumFormats; i++) {
if ((m_pFormatEtc[i].tymed & pFormatEtc->tymed) &&
m_pFormatEtc[i].cfFormat == pFormatEtc->cfFormat &&
m_pFormatEtc[i].dwAspect == pFormatEtc->dwAspect) {
// return index of stored format
return i;
}
}
// error, format not found
return -1;
}
DataObjectWin::DataObjectWin(FORMATETC* fmtetc, STGMEDIUM* stgmed, int count)
: ref_count_(0) {
m_nNumFormats = count;
m_pFormatEtc = new FORMATETC[count];
m_pStgMedium = new STGMEDIUM[count];
for (int i = 0; i < count; i++) {
m_pFormatEtc[i] = fmtetc[i];
m_pStgMedium[i] = stgmed[i];
}
}

View File

@ -0,0 +1,178 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_
#pragma once
#include <atlcomcli.h>
#include <objidl.h>
#include <stdio.h>
#include "cefclient/dragdrop_events.h"
#define DEFAULT_QUERY_INTERFACE(__Class) \
HRESULT __stdcall QueryInterface(const IID& iid, void** object) { \
*object = NULL; \
if (IsEqualIID(iid, IID_IUnknown)) { \
IUnknown* obj = this; \
*object = obj; \
} else if (IsEqualIID(iid, IID_ ## __Class)) { \
__Class* obj = this; \
*object = obj; \
} else { \
return E_NOINTERFACE; \
} \
AddRef(); \
return S_OK; \
}
#define IUNKNOWN_IMPLEMENTATION \
ULONG __stdcall AddRef() { \
return ++ref_count_; \
} \
ULONG __stdcall Release() { \
if (--ref_count_ == 0) { \
delete this; \
return 0U; \
} \
return ref_count_; \
} \
protected: \
ULONG ref_count_;
class DropTargetWin : public IDropTarget {
public:
static CComPtr<DropTargetWin> Create(DragEvents* callback, HWND hWnd);
CefBrowserHost::DragOperationsMask StartDragging(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y);
// IDropTarget implementation:
HRESULT __stdcall DragEnter(IDataObject* data_object,
DWORD key_state,
POINTL cursor_position,
DWORD* effect);
HRESULT __stdcall DragOver(DWORD key_state,
POINTL cursor_position,
DWORD* effect);
HRESULT __stdcall DragLeave();
HRESULT __stdcall Drop(IDataObject* data_object,
DWORD key_state,
POINTL cursor_position,
DWORD* effect);
DEFAULT_QUERY_INTERFACE(IDropTarget)
IUNKNOWN_IMPLEMENTATION()
protected:
explicit DropTargetWin(DragEvents* callback, HWND hWnd) :
ref_count_(0),
callback_(callback),
hWnd_(hWnd) {}
virtual ~DropTargetWin() {}
private:
DragEvents* callback_;
HWND hWnd_;
CefRefPtr<CefDragData> current_drag_data_;
};
class DropSourceWin : public IDropSource {
public:
static CComPtr<DropSourceWin> Create();
// IDropSource implementation:
HRESULT __stdcall GiveFeedback(DWORD dwEffect);
HRESULT __stdcall QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
DEFAULT_QUERY_INTERFACE(IDropSource)
IUNKNOWN_IMPLEMENTATION()
protected:
explicit DropSourceWin() : ref_count_(0) {}
virtual ~DropSourceWin() {}
};
class DragEnumFormatEtc : public IEnumFORMATETC {
public:
static HRESULT CreateEnumFormatEtc(UINT cfmt,
FORMATETC* afmt,
IEnumFORMATETC** ppEnumFormatEtc);
//
// IEnumFormatEtc members
//
HRESULT __stdcall Next(ULONG celt,
FORMATETC * pFormatEtc,
ULONG * pceltFetched);
HRESULT __stdcall Skip(ULONG celt);
HRESULT __stdcall Reset(void);
HRESULT __stdcall Clone(IEnumFORMATETC ** ppEnumFormatEtc);
//
// Construction / Destruction
//
DragEnumFormatEtc(FORMATETC *pFormatEtc, int nNumFormats);
~DragEnumFormatEtc();
static void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source);
DEFAULT_QUERY_INTERFACE(IEnumFORMATETC)
IUNKNOWN_IMPLEMENTATION()
private:
ULONG m_nIndex; // current enumerator index
ULONG m_nNumFormats; // number of FORMATETC members
FORMATETC* m_pFormatEtc; // array of FORMATETC objects
};
class DataObjectWin : public IDataObject {
public:
static CComPtr<DataObjectWin> Create(FORMATETC* fmtetc,
STGMEDIUM* stgmed,
int count);
// IDataObject memberS
HRESULT __stdcall GetDataHere(FORMATETC* pFormatEtc, STGMEDIUM *pmedium);
HRESULT __stdcall QueryGetData(FORMATETC* pFormatEtc);
HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC* pFormatEct,
FORMATETC* pFormatEtcOut);
HRESULT __stdcall SetData(FORMATETC* pFormatEtc,
STGMEDIUM* pMedium,
BOOL fRelease);
HRESULT __stdcall DAdvise(FORMATETC* pFormatEtc,
DWORD advf,
IAdviseSink*,
DWORD*);
HRESULT __stdcall DUnadvise(DWORD dwConnection);
HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise);
HRESULT __stdcall EnumFormatEtc(DWORD dwDirection,
IEnumFORMATETC **ppEnumFormatEtc);
HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium);
DEFAULT_QUERY_INTERFACE(IDataObject)
IUNKNOWN_IMPLEMENTATION()
protected:
int m_nNumFormats;
FORMATETC* m_pFormatEtc;
STGMEDIUM* m_pStgMedium;
static HGLOBAL DupGlobalMem(HGLOBAL hMem);
int LookupFormatEtc(FORMATETC *pFormatEtc);
explicit DataObjectWin(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_DRAGDROP_WIN_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/client_handler.h"
#include "cefclient/osrenderer.h"
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public ClientHandler::RenderHandler {
public:
// Create a new OSRWindow instance. |browser_provider| must outlive this
// object.
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent,
ClientWindowHandle parentView);
static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
ClientWindowHandle GetWindowHandle() const {
return glarea_;
}
CefRefPtr<CefBrowserHost> GetBrowserHost() const {
if (browser_provider_->GetBrowser())
return browser_provider_->GetBrowser()->GetHost();
return NULL;
}
// ClientHandler::RenderHandler methods
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
void Invalidate();
bool IsOverPopupWidget(int x, int y) const;
int GetPopupXOffset() const;
int GetPopupYOffset() const;
void ApplyPopupOffset(int& x, int& y) const;
private:
OSRWindow(OSRBrowserProvider* browser_provider,
bool transparent,
ClientWindowHandle parentView);
virtual ~OSRWindow();
void Render();
void EnableGL();
void DisableGL();
ClientOSRenderer renderer_;
OSRBrowserProvider* browser_provider_;
ClientWindowHandle glarea_;
bool gl_enabled_;
bool painting_popup_;
bool render_task_pending_;
IMPLEMENT_REFCOUNTING(OSRWindow);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_

View File

@ -0,0 +1,147 @@
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_
#include "include/cef_client.h"
#include "cefclient/client_handler.h"
class ClientOSRenderer;
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
// The client OpenGL view.
@interface ClientOpenGLView
: NSOpenGLView <NSDraggingSource, NSDraggingDestination> {
@public
NSTrackingArea* tracking_area_;
OSRBrowserProvider* browser_provider_;
ClientOSRenderer* renderer_;
NSPoint last_mouse_pos_;
NSPoint cur_mouse_pos_;
bool rotating_;
bool was_last_mouse_down_on_view_;
// Drag and drop
CefRefPtr<CefDragData> current_drag_data_;
NSDragOperation current_drag_op_;
NSDragOperation current_allowed_ops_;
NSPasteboard* pasteboard_;
CFStringRef fileUTI_;
// Event monitor for scroll wheel end event.
id endWheelMonitor_;
}
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency;
- (NSPoint)getClickPointForEvent:(NSEvent*)event;
- (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event;
- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event;
- (int)getModifiersForEvent:(NSEvent*)event;
- (BOOL)isKeyUpEvent:(NSEvent*)event;
- (BOOL)isKeyPadEvent:(NSEvent*)event;
- (CefRefPtr<CefBrowser>)getBrowser;
- (BOOL)startDragging:(CefRefPtr<CefDragData>)drag_data
allowed_ops:(NSDragOperation)ops point:(NSPoint)p;
@end
// Handler for off-screen rendering windows.
class ClientOSRHandler : public ClientHandler::RenderHandler {
public:
explicit ClientOSRHandler(ClientOpenGLView* view,
OSRBrowserProvider* browser_provider);
virtual ~ClientOSRHandler();
void Disconnect();
// ClientHandler::RenderHandler
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
virtual void UpdateDragCursor(
CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation)OVERRIDE;
CefWindowHandle view() { return view_; }
private:
void SetLoading(bool isLoading);
ClientOpenGLView* view_;
bool painting_popup_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientOSRHandler);
};
class OSRWindow {
public:
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView,
const CefRect& frame);
CefRefPtr<ClientHandler::RenderHandler> GetRenderHandler() {
return render_client.get();
}
CefWindowHandle GetWindowHandle() { return view_; }
private:
OSRWindow(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView,
const CefRect& frame);
~OSRWindow();
CefRefPtr<ClientOSRHandler> render_client;
CefWindowHandle view_;
IMPLEMENT_REFCOUNTING(OSRWindow);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,709 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/cefclient_osr_widget_win.h"
#include <windowsx.h>
#include "include/cef_runnable.h"
#include "cefclient/resource.h"
#include "cefclient/util.h"
// static
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
bool transparent) {
ASSERT(browser_provider);
if (!browser_provider)
return NULL;
return new OSRWindow(browser_provider, transparent);
}
// static
CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get());
}
bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
HINSTANCE hInst, LPCTSTR className) {
ASSERT(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL);
RegisterOSRClass(hInst, className);
hWnd_ = ::CreateWindow(className, 0,
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
hWndParent, 0, hInst, 0);
if (!hWnd_)
return false;
SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
// Reference released in OnDestroyed().
AddRef();
drop_target_ = DropTargetWin::Create(this, hWnd_);
HRESULT register_res = RegisterDragDrop(hWnd_, drop_target_);
ASSERT(register_res == S_OK);
return true;
}
void OSRWindow::DestroyWidget() {
if (IsWindow(hWnd_))
DestroyWindow(hWnd_);
}
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
RevokeDragDrop(hWnd_);
drop_target_ = NULL;
DisableGL();
::DestroyWindow(hWnd_);
}
bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
RECT window_rect = {0};
HWND root_window = GetAncestor(hWnd_, GA_ROOT);
if (::GetWindowRect(root_window, &window_rect)) {
rect = CefRect(window_rect.left,
window_rect.top,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top);
return true;
}
return false;
}
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
RECT clientRect;
if (!::GetClientRect(hWnd_, &clientRect))
return false;
rect.x = rect.y = 0;
rect.width = clientRect.right;
rect.height = clientRect.bottom;
return true;
}
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
if (!::IsWindow(hWnd_))
return false;
// Convert the point from view coordinates to actual screen coordinates.
POINT screen_pt = {viewX, viewY};
ClientToScreen(hWnd_, &screen_pt);
screenX = screen_pt.x;
screenY = screen_pt.y;
return true;
}
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!show) {
renderer_.ClearPopupRects();
browser->GetHost()->Invalidate(PET_VIEW);
}
renderer_.OnPopupShow(browser, show);
}
void OSRWindow::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
renderer_.OnPopupSize(browser, rect);
}
void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) {
if (painting_popup_) {
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
return;
}
if (!hDC_)
EnableGL();
wglMakeCurrent(hDC_, hRC_);
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
painting_popup_ = true;
browser->GetHost()->Invalidate(PET_POPUP);
painting_popup_ = false;
}
renderer_.Render();
SwapBuffers(hDC_);
}
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (!::IsWindow(hWnd_))
return;
// Change the plugin window's cursor.
SetClassLongPtr(hWnd_, GCLP_HCURSOR,
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
SetCursor(cursor);
}
bool OSRWindow::StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) {
if (!drop_target_)
return false;
current_drag_op_ = DRAG_OPERATION_NONE;
CefBrowserHost::DragOperationsMask result =
drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y);
current_drag_op_ = DRAG_OPERATION_NONE;
POINT pt = {};
GetCursorPos(&pt);
ScreenToClient(hWnd_, &pt);
browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result);
browser->GetHost()->DragSourceSystemDragEnded();
return true;
}
void OSRWindow::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) {
current_drag_op_ = operation;
}
void OSRWindow::Invalidate() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Invalidate));
return;
}
// Don't post another task if the previous task is still pending.
if (render_task_pending_)
return;
render_task_pending_ = true;
// Render at 30fps.
static const int kRenderDelay = 1000 / 30;
CefPostDelayedTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Render),
kRenderDelay);
}
CefBrowserHost::DragOperationsMask
OSRWindow::OnDragEnter(CefRefPtr<CefDragData> drag_data,
CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) {
browser_provider_->GetBrowser()->GetHost()->DragTargetDragEnter(
drag_data, ev, effect);
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
return current_drag_op_;
}
CefBrowserHost::DragOperationsMask OSRWindow::OnDragOver(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) {
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
return current_drag_op_;
}
void OSRWindow::OnDragLeave() {
browser_provider_->GetBrowser()->GetHost()->DragTargetDragLeave();
}
CefBrowserHost::DragOperationsMask
OSRWindow::OnDrop(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) {
browser_provider_->GetBrowser()->GetHost()->DragTargetDragOver(ev, effect);
browser_provider_->GetBrowser()->GetHost()->DragTargetDrop(ev);
return current_drag_op_;
}
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
: renderer_(transparent),
browser_provider_(browser_provider),
hWnd_(NULL),
hDC_(NULL),
hRC_(NULL),
painting_popup_(false),
render_task_pending_(false),
current_drag_op_(DRAG_OPERATION_NONE) {
}
OSRWindow::~OSRWindow() {
DestroyWidget();
}
void OSRWindow::Render() {
ASSERT(CefCurrentlyOn(TID_UI));
if (render_task_pending_)
render_task_pending_ = false;
if (!hDC_)
EnableGL();
wglMakeCurrent(hDC_, hRC_);
renderer_.Render();
SwapBuffers(hDC_);
}
void OSRWindow::EnableGL() {
ASSERT(CefCurrentlyOn(TID_UI));
PIXELFORMATDESCRIPTOR pfd;
int format;
// Get the device context.
hDC_ = GetDC(hWnd_);
// Set the pixel format for the DC.
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat(hDC_, &pfd);
SetPixelFormat(hDC_, format, &pfd);
// Create and enable the render context.
hRC_ = wglCreateContext(hDC_);
wglMakeCurrent(hDC_, hRC_);
renderer_.Initialize();
}
void OSRWindow::DisableGL() {
ASSERT(CefCurrentlyOn(TID_UI));
if (!hDC_)
return;
renderer_.Cleanup();
if (IsWindow(hWnd_)) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC_);
ReleaseDC(hWnd_, hDC_);
}
hDC_ = NULL;
hRC_ = NULL;
}
void OSRWindow::OnDestroyed() {
SetWindowLongPtr(hWnd_, GWLP_USERDATA, 0L);
hWnd_ = NULL;
Release();
}
ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = &OSRWindow::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = className;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
bool OSRWindow::isKeyDown(WPARAM wparam) {
return (GetKeyState(wparam) & 0x8000) != 0;
}
int OSRWindow::GetCefMouseModifiers(WPARAM wparam) {
int modifiers = 0;
if (wparam & MK_CONTROL)
modifiers |= EVENTFLAG_CONTROL_DOWN;
if (wparam & MK_SHIFT)
modifiers |= EVENTFLAG_SHIFT_DOWN;
if (isKeyDown(VK_MENU))
modifiers |= EVENTFLAG_ALT_DOWN;
if (wparam & MK_LBUTTON)
modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON;
if (wparam & MK_MBUTTON)
modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if (wparam & MK_RBUTTON)
modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON;
// Low bit set from GetKeyState indicates "toggled".
if (::GetKeyState(VK_NUMLOCK) & 1)
modifiers |= EVENTFLAG_NUM_LOCK_ON;
if (::GetKeyState(VK_CAPITAL) & 1)
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
return modifiers;
}
int OSRWindow::GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam) {
int modifiers = 0;
if (isKeyDown(VK_SHIFT))
modifiers |= EVENTFLAG_SHIFT_DOWN;
if (isKeyDown(VK_CONTROL))
modifiers |= EVENTFLAG_CONTROL_DOWN;
if (isKeyDown(VK_MENU))
modifiers |= EVENTFLAG_ALT_DOWN;
// Low bit set from GetKeyState indicates "toggled".
if (::GetKeyState(VK_NUMLOCK) & 1)
modifiers |= EVENTFLAG_NUM_LOCK_ON;
if (::GetKeyState(VK_CAPITAL) & 1)
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
switch (wparam) {
case VK_RETURN:
if ((lparam >> 16) & KF_EXTENDED)
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_INSERT:
case VK_DELETE:
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
if (!((lparam >> 16) & KF_EXTENDED))
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_NUMLOCK:
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
case VK_DIVIDE:
case VK_MULTIPLY:
case VK_SUBTRACT:
case VK_ADD:
case VK_DECIMAL:
case VK_CLEAR:
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_SHIFT:
if (isKeyDown(VK_LSHIFT))
modifiers |= EVENTFLAG_IS_LEFT;
else if (isKeyDown(VK_RSHIFT))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_CONTROL:
if (isKeyDown(VK_LCONTROL))
modifiers |= EVENTFLAG_IS_LEFT;
else if (isKeyDown(VK_RCONTROL))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_MENU:
if (isKeyDown(VK_LMENU))
modifiers |= EVENTFLAG_IS_LEFT;
else if (isKeyDown(VK_RMENU))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_LWIN:
modifiers |= EVENTFLAG_IS_LEFT;
break;
case VK_RWIN:
modifiers |= EVENTFLAG_IS_RIGHT;
break;
}
return modifiers;
}
bool OSRWindow::IsOverPopupWidget(int x, int y) const {
const CefRect& rc = renderer_.popup_rect();
int popup_right = rc.x + rc.width;
int popup_bottom = rc.y + rc.height;
return (x >= rc.x) && (x < popup_right) &&
(y >= rc.y) && (y < popup_bottom);
}
int OSRWindow::GetPopupXOffset() const {
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
}
int OSRWindow::GetPopupYOffset() const {
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
}
void OSRWindow::ApplyPopupOffset(int& x, int& y) const {
if (IsOverPopupWidget(x, y)) {
x += GetPopupXOffset();
y += GetPopupYOffset();
}
}
// Plugin window procedure.
// static
LRESULT CALLBACK OSRWindow::WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam) {
static POINT lastMousePos, curMousePos;
static bool mouseRotation = false;
static bool mouseTracking = false;
static int lastClickX = 0;
static int lastClickY = 0;
static CefBrowserHost::MouseButtonType lastClickButton = MBT_LEFT;
static int gLastClickCount = 0;
static double gLastClickTime = 0;
static bool gLastMouseDownOnView = false;
OSRWindow* window =
reinterpret_cast<OSRWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
CefRefPtr<CefBrowserHost> browser;
if (window && window->browser_provider_->GetBrowser().get())
browser = window->browser_provider_->GetBrowser()->GetHost();
LONG currentTime = 0;
bool cancelPreviousClick = false;
if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE ||
message == WM_MOUSELEAVE) {
currentTime = GetMessageTime();
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
cancelPreviousClick =
(abs(lastClickX - x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
|| (abs(lastClickY - y) > (GetSystemMetrics(SM_CYDOUBLECLK) / 2))
|| ((currentTime - gLastClickTime) > GetDoubleClickTime());
if (cancelPreviousClick &&
(message == WM_MOUSEMOVE || message == WM_MOUSELEAVE)) {
gLastClickCount = 0;
lastClickX = 0;
lastClickY = 0;
gLastClickTime = 0;
}
}
switch (message) {
case WM_DESTROY:
if (window)
window->OnDestroyed();
return 0;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN: {
SetCapture(hWnd);
SetFocus(hWnd);
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
if (wParam & MK_SHIFT) {
// Start rotation effect.
lastMousePos.x = curMousePos.x = x;
lastMousePos.y = curMousePos.y = y;
mouseRotation = true;
} else {
CefBrowserHost::MouseButtonType btnType =
(message == WM_LBUTTONDOWN ? MBT_LEFT : (
message == WM_RBUTTONDOWN ? MBT_RIGHT : MBT_MIDDLE));
if (!cancelPreviousClick && (btnType == lastClickButton)) {
++gLastClickCount;
} else {
gLastClickCount = 1;
lastClickX = x;
lastClickY = y;
}
gLastClickTime = currentTime;
lastClickButton = btnType;
if (browser.get()) {
CefMouseEvent mouse_event;
mouse_event.x = x;
mouse_event.y = y;
gLastMouseDownOnView = !window->IsOverPopupWidget(x, y);
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = GetCefMouseModifiers(wParam);
browser->SendMouseClickEvent(mouse_event, btnType, false,
gLastClickCount);
}
}
break;
}
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
if (GetCapture() == hWnd)
ReleaseCapture();
if (mouseRotation) {
// End rotation effect.
mouseRotation = false;
window->renderer_.SetSpin(0, 0);
window->Invalidate();
} else {
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
CefBrowserHost::MouseButtonType btnType =
(message == WM_LBUTTONUP ? MBT_LEFT : (
message == WM_RBUTTONUP ? MBT_RIGHT : MBT_MIDDLE));
if (browser.get()) {
CefMouseEvent mouse_event;
mouse_event.x = x;
mouse_event.y = y;
if (gLastMouseDownOnView &&
window->IsOverPopupWidget(x, y) &&
(window->GetPopupXOffset() || window->GetPopupYOffset())) {
break;
}
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = GetCefMouseModifiers(wParam);
browser->SendMouseClickEvent(mouse_event, btnType, true,
gLastClickCount);
}
}
break;
case WM_MOUSEMOVE: {
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
if (mouseRotation) {
// Apply rotation effect.
curMousePos.x = x;
curMousePos.y = y;
window->renderer_.IncrementSpin((curMousePos.x - lastMousePos.x),
(curMousePos.y - lastMousePos.y));
lastMousePos.x = curMousePos.x;
lastMousePos.y = curMousePos.y;
window->Invalidate();
} else {
if (!mouseTracking) {
// Start tracking mouse leave. Required for the WM_MOUSELEAVE event to
// be generated.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
mouseTracking = true;
}
if (browser.get()) {
CefMouseEvent mouse_event;
mouse_event.x = x;
mouse_event.y = y;
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = GetCefMouseModifiers(wParam);
browser->SendMouseMoveEvent(mouse_event, false);
}
}
break;
}
case WM_MOUSELEAVE:
if (mouseTracking) {
// Stop tracking mouse leave.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE & TME_CANCEL;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
mouseTracking = false;
}
if (browser.get()) {
CefMouseEvent mouse_event;
mouse_event.x = 0;
mouse_event.y = 0;
mouse_event.modifiers = GetCefMouseModifiers(wParam);
browser->SendMouseMoveEvent(mouse_event, true);
}
break;
case WM_MOUSEWHEEL:
if (browser.get()) {
POINT screen_point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
HWND scrolled_wnd = ::WindowFromPoint(screen_point);
if (scrolled_wnd != hWnd) {
break;
}
ScreenToClient(hWnd, &screen_point);
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
CefMouseEvent mouse_event;
mouse_event.x = screen_point.x;
mouse_event.y = screen_point.y;
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = GetCefMouseModifiers(wParam);
browser->SendMouseWheelEvent(mouse_event,
isKeyDown(VK_SHIFT) ? delta : 0,
!isKeyDown(VK_SHIFT) ? delta : 0);
}
break;
case WM_SIZE:
if (browser.get())
browser->WasResized();
break;
case WM_SETFOCUS:
case WM_KILLFOCUS:
if (browser.get())
browser->SendFocusEvent(message == WM_SETFOCUS);
break;
case WM_CAPTURECHANGED:
case WM_CANCELMODE:
if (!mouseRotation) {
if (browser.get())
browser->SendCaptureLostEvent();
}
break;
case WM_SYSCHAR:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR: {
CefKeyEvent event;
event.windows_key_code = wParam;
event.native_key_code = lParam;
event.is_system_key = message == WM_SYSCHAR ||
message == WM_SYSKEYDOWN ||
message == WM_SYSKEYUP;
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
event.type = KEYEVENT_RAWKEYDOWN;
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
event.type = KEYEVENT_KEYUP;
else
event.type = KEYEVENT_CHAR;
event.modifiers = GetCefKeyboardModifiers(wParam, lParam);
if (browser.get())
browser->SendKeyEvent(event);
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
RECT rc;
BeginPaint(hWnd, &ps);
rc = ps.rcPaint;
EndPaint(hWnd, &ps);
if (browser.get())
browser->Invalidate(PET_VIEW);
return 0;
}
case WM_ERASEBKGND:
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}

View File

@ -0,0 +1,126 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/cefclient_osr_dragdrop_win.h"
#include "cefclient/client_handler.h"
#include "cefclient/osrenderer.h"
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public ClientHandler::RenderHandler,
public DragEvents {
public:
// Create a new OSRWindow instance. |browser_provider| must outlive this
// object.
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent);
static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
// Create the underlying window.
bool CreateWidget(HWND hWndParent, const RECT& rect,
HINSTANCE hInst, LPCTSTR className);
// Destroy the underlying window.
void DestroyWidget();
HWND hwnd() const {
return hWnd_;
}
// ClientHandler::RenderHandler methods
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
virtual void UpdateDragCursor(
CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) OVERRIDE;
// DragEvents methods
virtual CefBrowserHost::DragOperationsMask OnDragEnter(
CefRefPtr<CefDragData> drag_data,
CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
virtual CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
virtual void OnDragLeave() OVERRIDE;
virtual CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) OVERRIDE;
void Invalidate();
static int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
static int GetCefMouseModifiers(WPARAM wparam);
private:
OSRWindow(OSRBrowserProvider* browser_provider, bool transparent);
virtual ~OSRWindow();
void Render();
void EnableGL();
void DisableGL();
void OnDestroyed();
static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam);
static bool isKeyDown(WPARAM wparam);
bool IsOverPopupWidget(int x, int y) const;
int GetPopupXOffset() const;
int GetPopupYOffset() const;
void ApplyPopupOffset(int& x, int& y) const;
ClientOSRenderer renderer_;
OSRBrowserProvider* browser_provider_;
HWND hWnd_;
HDC hDC_;
HGLRC hRC_;
CComPtr<DropTargetWin> drop_target_;
CefRenderHandler::DragOperation current_drag_op_;
bool painting_popup_;
bool render_task_pending_;
IMPLEMENT_REFCOUNTING(OSRWindow);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_

View File

@ -14,6 +14,7 @@
#include "include/cef_frame.h"
#include "include/cef_runnable.h"
#include "include/cef_sandbox_win.h"
#include "cefclient/cefclient_osr_widget_win.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
#include "cefclient/resource.h"
@ -60,6 +61,15 @@ LRESULT CALLBACK MessageWndProc(HWND, UINT, WPARAM, LPARAM);
// The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler;
class MainBrowserProvider : public OSRBrowserProvider {
virtual CefRefPtr<CefBrowser> GetBrowser() {
if (g_handler.get())
return g_handler->GetBrowser();
return NULL;
}
} g_main_browser_provider;
// Program entry point function.
int APIENTRY wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
@ -376,8 +386,23 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
CefWindowInfo info;
CefBrowserSettings settings;
// Initialize window info to the defaults for a child window.
info.SetAsChild(hWnd, rect);
// Populate the browser settings based on command line arguments.
AppGetBrowserSettings(settings);
if (AppIsOffScreenRenderingEnabled()) {
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
bool transparent =
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
CefRefPtr<OSRWindow> osr_window =
OSRWindow::Create(&g_main_browser_provider, transparent);
osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
info.SetAsWindowless(osr_window->hwnd(), transparent);
g_handler->SetOSRHandler(osr_window.get());
} else {
// Initialize window info to the defaults for a child window.
info.SetAsChild(hWnd, rect);
}
// Creat the new child browser window
CefBrowserHost::CreateBrowser(info, g_handler.get(),
@ -517,8 +542,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
case WM_SETFOCUS:
if (g_handler.get() && g_handler->GetBrowser()) {
// Give focus to the browser.
g_handler->GetBrowser()->GetHost()->SetFocus(true);
if (AppIsOffScreenRenderingEnabled()) {
// Give focus to the OSR window.
CefRefPtr<OSRWindow> osr_window =
static_cast<OSRWindow*>(g_handler->GetOSRHandler().get());
if (osr_window)
::SetFocus(osr_window->hwnd());
} else {
// Give focus to the browser.
g_handler->GetBrowser()->GetHost()->SetFocus(true);
}
}
return 0;

View File

@ -240,7 +240,7 @@ void ClientHandler::OnDownloadUpdated(
bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) {
CefDragHandler::DragOperationsMask mask) {
REQUIRE_UI_THREAD();
// Forbid dragging of link URLs.
@ -279,6 +279,22 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
return false;
}
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings,
bool* no_javascript_access) {
if (browser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return true;
}
return false;
}
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD();
@ -341,6 +357,11 @@ void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
if (m_BrowserId == browser->GetIdentifier()) {
// Free the browser pointer so that the browser can be destroyed
m_Browser = NULL;
if (m_OSRHandler.get()) {
m_OSRHandler->OnBeforeClose(browser);
m_OSRHandler = NULL;
}
} else if (browser->IsPopup()) {
// Remove from the browser popup list.
BrowserList::iterator bit = m_PopupBrowsers.begin();
@ -491,6 +512,84 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
}
}
bool ClientHandler::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetRootScreenRect(browser, rect);
}
bool ClientHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetViewRect(browser, rect);
}
bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
}
bool ClientHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetScreenInfo(browser, screen_info);
}
void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!m_OSRHandler.get())
return;
return m_OSRHandler->OnPopupShow(browser, show);
}
void ClientHandler::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (!m_OSRHandler.get())
return;
return m_OSRHandler->OnPopupSize(browser, rect);
}
void ClientHandler::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) {
if (!m_OSRHandler.get())
return;
m_OSRHandler->OnPaint(browser, type, dirtyRects, buffer, width, height);
}
void ClientHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (!m_OSRHandler.get())
return;
m_OSRHandler->OnCursorChange(browser, cursor);
}
bool ClientHandler::StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->StartDragging(browser, drag_data, allowed_ops, x, y);
}
void ClientHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) {
if (!m_OSRHandler.get())
return;
m_OSRHandler->UpdateDragCursor(browser, operation);
}
void ClientHandler::SetMainHwnd(ClientWindowHandle hwnd) {
AutoLock lock_scope(this);
m_MainHwnd = hwnd;

View File

@ -36,8 +36,15 @@ class ClientHandler : public CefClient,
public CefKeyboardHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRenderHandler,
public CefRequestHandler {
public:
// Interface implemented to handle off-screen rendering.
class RenderHandler : public CefRenderHandler {
public:
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) =0;
};
typedef std::set<CefMessageRouterBrowserSide::Handler*> MessageHandlerSet;
ClientHandler();
@ -68,6 +75,9 @@ class ClientHandler : public CefClient,
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
return this;
}
@ -112,7 +122,7 @@ class ClientHandler : public CefClient,
// CefDragHandler methods
virtual bool OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) OVERRIDE;
CefDragHandler::DragOperationsMask mask) OVERRIDE;
// CefGeolocationHandler methods
virtual void OnRequestGeolocationPermission(
@ -128,6 +138,15 @@ class ClientHandler : public CefClient,
bool* is_keyboard_shortcut) OVERRIDE;
// CefLifeSpanHandler methods
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings,
bool* no_javascript_access) OVERRIDE;
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
@ -162,9 +181,44 @@ class ClientHandler : public CefClient,
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) OVERRIDE;
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
virtual bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
virtual void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation)
OVERRIDE;
void SetMainHwnd(ClientWindowHandle hwnd);
ClientWindowHandle GetMainHwnd() { return m_MainHwnd; }
void SetEditHwnd(ClientWindowHandle hwnd);
void SetOSRHandler(CefRefPtr<RenderHandler> handler) {
m_OSRHandler = handler;
}
CefRefPtr<RenderHandler> GetOSRHandler() { return m_OSRHandler; }
void SetButtonHwnds(ClientWindowHandle backHwnd,
ClientWindowHandle forwardHwnd,
ClientWindowHandle reloadHwnd,
@ -252,6 +306,8 @@ class ClientHandler : public CefClient,
ClientWindowHandle m_StopHwnd;
ClientWindowHandle m_ReloadHwnd;
CefRefPtr<RenderHandler> m_OSRHandler;
// Support for logging.
std::string m_LogFile;

View File

@ -21,6 +21,9 @@ namespace cefclient {
const char kMultiThreadedMessageLoop[] = "multi-threaded-message-loop";
const char kCachePath[] = "cache-path";
const char kUrl[] = "url";
const char kOffScreenRenderingEnabled[] = "off-screen-rendering-enabled";
const char kOffScreenFrameRate[] = "off-screen-frame-rate";
const char kTransparentPaintingEnabled[] = "transparent-painting-enabled";
const char kMouseCursorChangeDisabled[] = "mouse-cursor-change-disabled";
} // namespace cefclient

View File

@ -13,6 +13,9 @@ namespace cefclient {
extern const char kMultiThreadedMessageLoop[];
extern const char kCachePath[];
extern const char kUrl[];
extern const char kOffScreenRenderingEnabled[];
extern const char kOffScreenFrameRate[];
extern const char kTransparentPaintingEnabled[];
extern const char kMouseCursorChangeDisabled[];
} // namespace cefclient

View File

@ -0,0 +1,24 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_
#define CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/client_handler.h"
class DragEvents {
public:
virtual CefBrowserHost::DragOperationsMask OnDragEnter(
CefRefPtr<CefDragData> drag_data,
CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) = 0;
virtual CefBrowserHost::DragOperationsMask OnDragOver(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) = 0;
virtual void OnDragLeave() = 0;
virtual CefBrowserHost::DragOperationsMask OnDrop(CefMouseEvent ev,
CefBrowserHost::DragOperationsMask effect) = 0;
};
#endif // CEF_TESTS_CEFCLIENT_DRAGDROP_EVENTS_H_

View File

@ -0,0 +1,277 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
#include "cefclient/osrenderer.h"
#if defined(OS_WIN)
#include <gl/gl.h>
#include <gl/glu.h>
#elif defined(OS_MACOSX)
#include <OpenGL/gl.h>
#elif defined(OS_LINUX)
#include <GL/gl.h>
#include <GL/glu.h>
#else
#error Platform is not supported.
#endif
#include "cefclient/util.h"
#ifndef GL_BGR
#define GL_BGR 0x80E0
#endif
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#endif
ClientOSRenderer::ClientOSRenderer(bool transparent)
: transparent_(transparent),
initialized_(false),
texture_id_(0),
view_width_(0),
view_height_(0),
spin_x_(0),
spin_y_(0) {
}
ClientOSRenderer::~ClientOSRenderer() {
Cleanup();
}
void ClientOSRenderer::Initialize() {
if (initialized_)
return;
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Necessary for non-power-of-2 textures to render correctly.
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Create the texture.
glGenTextures(1, &texture_id_);
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
initialized_ = true;
}
void ClientOSRenderer::Cleanup() {
if (texture_id_ != 0)
glDeleteTextures(1, &texture_id_);
}
void ClientOSRenderer::Render() {
if (view_width_ == 0 || view_height_ == 0)
return;
ASSERT(initialized_);
struct {
float tu, tv;
float x, y, z;
} static vertices[] = {
{0.0f, 1.0f, -1.0f, -1.0f, 0.0f},
{1.0f, 1.0f, 1.0f, -1.0f, 0.0f},
{1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 1.0f, 0.0f}
};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Match GL units to screen coordinates.
glViewport(0, 0, view_width_, view_height_);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 0, view_width_, view_height_, 0.1, 100.0);
// Draw the background gradient.
glPushAttrib(GL_ALL_ATTRIB_BITS);
glBegin(GL_QUADS);
glColor4f(1.0, 0.0, 0.0, 1.0); // red
glVertex2f(-1.0, -1.0);
glVertex2f(1.0, -1.0);
glColor4f(0.0, 0.0, 1.0, 1.0); // blue
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
glPopAttrib();
// Rotate the view based on the mouse spin.
if (spin_x_ != 0)
glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f);
if (spin_y_ != 0)
glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f);
if (transparent_) {
// Alpha blending style. Texture values have premultiplied alpha.
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Enable alpha blending.
glEnable(GL_BLEND);
}
// Enable 2D textures.
glEnable(GL_TEXTURE_2D);
// Draw the facets with the texture.
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
glInterleavedArrays(GL_T2F_V3F, 0, vertices);
glDrawArrays(GL_QUADS, 0, 4);
// Disable 2D textures.
glDisable(GL_TEXTURE_2D);
if (transparent_) {
// Disable alpha blending.
glDisable(GL_BLEND);
}
}
void ClientOSRenderer::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!show) {
// Clear the popup rectangle.
ClearPopupRects();
}
}
void ClientOSRenderer::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (rect.width <= 0 || rect.height <= 0)
return;
original_popup_rect_ = rect;
popup_rect_ = GetPopupRectInWebView(original_popup_rect_);
}
CefRect ClientOSRenderer::GetPopupRectInWebView(const CefRect& original_rect) {
CefRect rc(original_rect);
// if x or y are negative, move them to 0.
if (rc.x < 0)
rc.x = 0;
if (rc.y < 0)
rc.y = 0;
// if popup goes outside the view, try to reposition origin
if (rc.x + rc.width > view_width_)
rc.x = view_width_ - rc.width;
if (rc.y + rc.height > view_height_)
rc.y = view_height_ - rc.height;
// if x or y became negative, move them to 0 again.
if (rc.x < 0)
rc.x = 0;
if (rc.y < 0)
rc.y = 0;
return rc;
}
void ClientOSRenderer::ClearPopupRects() {
popup_rect_.Set(0, 0, 0, 0);
original_popup_rect_.Set(0, 0, 0, 0);
}
void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer, int width, int height) {
if (!initialized_)
Initialize();
if (transparent_) {
// Enable alpha blending.
glEnable(GL_BLEND);
}
// Enable 2D textures.
glEnable(GL_TEXTURE_2D);
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
if (type == PET_VIEW) {
int old_width = view_width_;
int old_height = view_height_;
view_width_ = width;
view_height_ = height;
glPixelStorei(GL_UNPACK_ROW_LENGTH, view_width_);
if (old_width != view_width_ || old_height != view_height_) {
// Update/resize the whole texture.
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width_, view_height_, 0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
} else {
// Update just the dirty rectangles.
CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();
for (; i != dirtyRects.end(); ++i) {
const CefRect& rect = *i;
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y);
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,
rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
buffer);
}
}
} else if (type == PET_POPUP && popup_rect_.width > 0 &&
popup_rect_.height > 0) {
int skip_pixels = 0, x = popup_rect_.x;
int skip_rows = 0, y = popup_rect_.y;
int w = width;
int h = height;
// Adjust the popup to fit inside the view.
if (x < 0) {
skip_pixels = -x;
x = 0;
}
if (y < 0) {
skip_rows = -y;
y = 0;
}
if (x + w > view_width_)
w -= x + w - view_width_;
if (y + h > view_height_)
h -= y + h - view_height_;
// Update the popup rectangle.
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
}
// Disable 2D textures.
glDisable(GL_TEXTURE_2D);
if (transparent_) {
// Disable alpha blending.
glDisable(GL_BLEND);
}
}
void ClientOSRenderer::SetSpin(float spinX, float spinY) {
spin_x_ = spinX;
spin_y_ = spinY;
}
void ClientOSRenderer::IncrementSpin(float spinDX, float spinDY) {
spin_x_ -= spinDX;
spin_y_ -= spinDY;
}

View File

@ -0,0 +1,65 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_OSRENDERER_H_
#define CEF_TESTS_CEFCLIENT_OSRENDERER_H_
#pragma once
#include "include/cef_browser.h"
#include "include/cef_render_handler.h"
class ClientOSRenderer {
public:
// The context must outlive this object.
explicit ClientOSRenderer(bool transparent);
virtual ~ClientOSRenderer();
// Initialize the OpenGL environment.
void Initialize();
// Clean up the OpenGL environment.
void Cleanup();
// Render to the screen.
void Render();
// Forwarded from CefRenderHandler callbacks.
void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show);
void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect);
void OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer, int width, int height);
// Apply spin.
void SetSpin(float spinX, float spinY);
void IncrementSpin(float spinDX, float spinDY);
bool IsTransparent() { return transparent_; }
int GetViewWidth() { return view_width_; }
int GetViewHeight() { return view_height_; }
const CefRect& popup_rect() const { return popup_rect_; }
const CefRect& original_popup_rect() const { return original_popup_rect_; }
CefRect GetPopupRectInWebView(const CefRect& original_rect);
void ClearPopupRects();
private:
bool transparent_;
bool initialized_;
unsigned int texture_id_;
int view_width_;
int view_height_;
CefRect popup_rect_;
CefRect original_popup_rect_;
float spin_x_;
float spin_y_;
};
#endif // CEF_TESTS_CEFCLIENT_OSRENDERER_H_

View File

@ -0,0 +1,109 @@
<html>
<head><title>OSR Test</title></head>
<style>
.red_hover:hover {color:red;}
#li { width: 530px; }
body {background:rgba(255, 0, 0, 0.5); }
input {-webkit-appearance: none; }
#LI11select {width: 75px;}
.dropdiv {
width:50px;
height:50px;
border:1px solid #aaaaaa;
float: left;
}
#dragdiv {
width: 30px;
height: 30px;
background-color: green;
margin: 10px;
}
#draghere {
position: relative;
z-index: -1;
top: 7px;
left: 7px;
opacity: 0.4;
}
</style>
<script>
function getElement(id) { return document.getElementById(id); }
function makeH1Red() { getElement('LI00').style.color='red'; }
function makeH1Black() { getElement('LI00').style.color='black'; }
function navigate() { location.href='?k='+getElement('editbox').value; }
function load() { var select = document.getElementById('LI11select');
for (var i = 1; i < 21; i++)
select.options.add(new Option('Option ' + i, i));
}
function onEventTest(event) {
var param = 'osr' + event.type;
if (event.type == "click")
param += event.button;
// Results in a call to the OnQuery method in os_rendering_unittest.cc.
if (window.testQuery)
window.testQuery({request: param});
}
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev) {
var data=ev.dataTransfer.getData("Text");
ev.target.innerHTML = '';
var dragged = document.getElementById(data);
dragged.setAttribute('draggable', 'false');
ev.target.appendChild(dragged);
if (window.testQuery)
window.testQuery({request: "osrdrop"});
}
</script>
<body onfocus='onEventTest(event)' onblur='onEventTest(event)' onload='load();'>
<h1 id='LI00' onclick="onEventTest(event)">
OSR Testing h1 - Focus and blur
<select id='LI11select'>
<option value='0'>Default</option>
</select>
this page and will get this red black
</h1>
<ol>
<li id='LI01'>OnPaint should be called each time a page loads</li>
<li id='LI02' style='cursor:pointer;'><span>Move mouse
to require an OnCursorChange call</span></li>
<li id='LI03' onmousemove="onEventTest(event)"><span>Hover will color this with
red. Will trigger OnPaint once on enter and once on leave</span></li>
<li id='LI04'>Right clicking will show contextual menu and will request
GetScreenPoint</li>
<li id='LI05'>IsWindowRenderingDisabled should be true</li>
<li id='LI06'>WasResized should trigger full repaint if size changes.
</li>
<li id='LI07'>Invalidate should trigger OnPaint once</li>
<li id='LI08'>Click and write here with SendKeyEvent to trigger repaints:
<input id='editbox' type='text' value='' size="5"></li>
<li id='LI09'>Click here with SendMouseClickEvent to navigate:
<input id='btnnavigate' type='button' onclick='navigate()'
value='Click here to navigate' id='editbox' /></li>
<li id='LI10' title='EXPECTED_TOOLTIP'>Mouse over this element will
trigger show a tooltip</li>
</ol>
<div class="dropdiv" id="dropdiv" ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="draghere">Drag here</span>
</div>
<div class="dropdiv">
<div id="dragdiv" draggable="true" ondragstart="drag(event)"></div>
</div>
<br />
<br />
<br />
<br />
<br />
<br />
</body>
</html>

View File

@ -46,12 +46,13 @@
#define IDS_LOCALSTORAGE 1003
#define IDS_LOGO 1004
#define IDS_LOGOBALL 1005
#define IDS_OTHER_TESTS 1006
#define IDS_PERFORMANCE 1007
#define IDS_TRANSPARENCY 1008
#define IDS_WINDOW 1009
#define IDS_XMLHTTPREQUEST 1010
#define IDS_PERFORMANCE2 1011
#define IDS_OSRTEST 1006
#define IDS_OTHER_TESTS 1007
#define IDS_PERFORMANCE 1008
#define IDS_TRANSPARENCY 1009
#define IDS_WINDOW 1010
#define IDS_XMLHTTPREQUEST 1011
#define IDS_PERFORMANCE2 1012
// Avoid files associated with MacOS
#define _X86_

View File

@ -38,6 +38,7 @@ int GetResourceId(const char* resource_name) {
{"domaccess.html", IDS_DOMACCESS},
{"localstorage.html", IDS_LOCALSTORAGE},
{"logo.png", IDS_LOGO},
{"osr_test.html", IDS_OSRTEST},
{"other_tests.html", IDS_OTHER_TESTS},
{"performance.html", IDS_PERFORMANCE},
{"performance2.html", IDS_PERFORMANCE2},

View File

@ -62,4 +62,32 @@ class ScopedArgArray {
std::vector<std::string> values_;
};
// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
//
// One caveat is that arraysize() doesn't accept any array of an
// anonymous type or a type defined inside a function. In these rare
// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is
// due to a limitation in C++'s template system. The limitation might
// eventually be removed, but it hasn't happened yet.
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
// That gcc wants both of these prototypes seems mysterious. VC, for
// its part, can't decide which to use (another mystery). Matching of
// template overloads: the final frontier.
#ifndef _MSC_VER
template <typename T, size_t N>
char (&ArraySizeHelper(const T (&array)[N]))[N];
#endif
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
#endif // CEF_TESTS_CEFCLIENT_UTIL_H_

Some files were not shown because too many files have changed in this diff Show More