mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Mac: Add off-screen rendering support (issue #518).
- Build with the 10.7 SDK (set GYP_DEFINES='mac_sdk=10.7') to include Retina support in the cefclient OSR example. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1226 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
25
cef.gyp
25
cef.gyp
@ -86,7 +86,7 @@
|
|||||||
'-lshlwapi.lib',
|
'-lshlwapi.lib',
|
||||||
'-lrpcrt4.lib',
|
'-lrpcrt4.lib',
|
||||||
'-lopengl32.lib',
|
'-lopengl32.lib',
|
||||||
'-lglu32.lib',
|
'-lglu32.lib',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'sources': [
|
'sources': [
|
||||||
@ -199,6 +199,7 @@
|
|||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
||||||
|
'$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'sources': [
|
'sources': [
|
||||||
@ -237,6 +238,7 @@
|
|||||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||||
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
||||||
'<(DEPTH)/third_party/icu/icu.gyp:icuuc',
|
'<(DEPTH)/third_party/icu/icu.gyp:icuuc',
|
||||||
|
'<(DEPTH)/ui/ui.gyp:ui',
|
||||||
'cef_pak',
|
'cef_pak',
|
||||||
'libcef',
|
'libcef',
|
||||||
'libcef_dll_wrapper',
|
'libcef_dll_wrapper',
|
||||||
@ -258,6 +260,7 @@
|
|||||||
'tests/unittests/navigation_unittest.cc',
|
'tests/unittests/navigation_unittest.cc',
|
||||||
'tests/unittests/process_message_unittest.cc',
|
'tests/unittests/process_message_unittest.cc',
|
||||||
'tests/unittests/request_unittest.cc',
|
'tests/unittests/request_unittest.cc',
|
||||||
|
'tests/cefclient/resource_util.h',
|
||||||
'tests/unittests/run_all_unittests.cc',
|
'tests/unittests/run_all_unittests.cc',
|
||||||
'tests/unittests/scheme_handler_unittest.cc',
|
'tests/unittests/scheme_handler_unittest.cc',
|
||||||
'tests/unittests/stream_unittest.cc',
|
'tests/unittests/stream_unittest.cc',
|
||||||
@ -280,6 +283,7 @@
|
|||||||
'tests/unittests/zip_reader_unittest.cc',
|
'tests/unittests/zip_reader_unittest.cc',
|
||||||
],
|
],
|
||||||
'mac_bundle_resources': [
|
'mac_bundle_resources': [
|
||||||
|
'tests/cefclient/res/osr_test.html',
|
||||||
'tests/unittests/mac/unittests.icns',
|
'tests/unittests/mac/unittests.icns',
|
||||||
'tests/unittests/mac/English.lproj/InfoPlist.strings',
|
'tests/unittests/mac/English.lproj/InfoPlist.strings',
|
||||||
'tests/unittests/mac/English.lproj/MainMenu.xib',
|
'tests/unittests/mac/English.lproj/MainMenu.xib',
|
||||||
@ -299,10 +303,16 @@
|
|||||||
},
|
},
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'.',
|
'.',
|
||||||
|
# Necessary to allow resouce_util_* implementation files in cefclient to
|
||||||
|
# include 'cefclient/*' files, without the tests/ fragment
|
||||||
|
'./tests'
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
[ 'OS=="win"', {
|
[ 'OS=="win"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'tests/cefclient/cefclient.rc',
|
||||||
|
'tests/cefclient/res/osr_test.html',
|
||||||
|
'tests/cefclient/resource_util_win.cpp',
|
||||||
'tests/unittests/os_rendering_unittest.cc',
|
'tests/unittests/os_rendering_unittest.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
@ -410,6 +420,11 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'tests/cefclient/resource_util_mac.mm',
|
||||||
|
'tests/cefclient/resource_util_posix.cpp',
|
||||||
|
'tests/unittests/os_rendering_unittest.cc',
|
||||||
|
'tests/unittests/os_rendering_unittest_mac.h',
|
||||||
|
'tests/unittests/os_rendering_unittest_mac.mm',
|
||||||
'tests/unittests/run_all_unittests_mac.mm',
|
'tests/unittests/run_all_unittests_mac.mm',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
@ -995,8 +1010,8 @@
|
|||||||
'libcef/browser/javascript_dialog_win.cc',
|
'libcef/browser/javascript_dialog_win.cc',
|
||||||
'libcef/browser/menu_creator_runner_win.cc',
|
'libcef/browser/menu_creator_runner_win.cc',
|
||||||
'libcef/browser/menu_creator_runner_win.h',
|
'libcef/browser/menu_creator_runner_win.h',
|
||||||
'libcef/browser/render_widget_host_view_osr.h',
|
|
||||||
'libcef/browser/render_widget_host_view_osr.cc',
|
'libcef/browser/render_widget_host_view_osr.cc',
|
||||||
|
'libcef/browser/render_widget_host_view_osr.h',
|
||||||
'libcef/browser/web_contents_view_osr.cc',
|
'libcef/browser/web_contents_view_osr.cc',
|
||||||
'libcef/browser/web_contents_view_osr.h',
|
'libcef/browser/web_contents_view_osr.h',
|
||||||
# Include sources for context menu implementation.
|
# Include sources for context menu implementation.
|
||||||
@ -1016,11 +1031,17 @@
|
|||||||
'<@(includes_mac)',
|
'<@(includes_mac)',
|
||||||
'libcef/browser/application_mac.h',
|
'libcef/browser/application_mac.h',
|
||||||
'libcef/browser/application_mac.mm',
|
'libcef/browser/application_mac.mm',
|
||||||
|
'libcef/browser/backing_store_osr.cc',
|
||||||
|
'libcef/browser/backing_store_osr.h',
|
||||||
'libcef/browser/browser_host_impl_mac.mm',
|
'libcef/browser/browser_host_impl_mac.mm',
|
||||||
'libcef/browser/browser_main_mac.mm',
|
'libcef/browser/browser_main_mac.mm',
|
||||||
'libcef/browser/javascript_dialog_mac.mm',
|
'libcef/browser/javascript_dialog_mac.mm',
|
||||||
'libcef/browser/menu_creator_runner_mac.h',
|
'libcef/browser/menu_creator_runner_mac.h',
|
||||||
'libcef/browser/menu_creator_runner_mac.mm',
|
'libcef/browser/menu_creator_runner_mac.mm',
|
||||||
|
'libcef/browser/render_widget_host_view_osr.cc',
|
||||||
|
'libcef/browser/render_widget_host_view_osr.h',
|
||||||
|
'libcef/browser/web_contents_view_osr.cc',
|
||||||
|
'libcef/browser/web_contents_view_osr.h',
|
||||||
# Include sources for context menu implementation.
|
# Include sources for context menu implementation.
|
||||||
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.mm',
|
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.mm',
|
||||||
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.h',
|
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.h',
|
||||||
|
@ -134,13 +134,18 @@
|
|||||||
'tests/cefclient/osrenderer.cpp',
|
'tests/cefclient/osrenderer.cpp',
|
||||||
'tests/cefclient/resource.h',
|
'tests/cefclient/resource.h',
|
||||||
'tests/cefclient/res/cefclient.ico',
|
'tests/cefclient/res/cefclient.ico',
|
||||||
|
'tests/cefclient/res/osr_test.html',
|
||||||
'tests/cefclient/res/small.ico',
|
'tests/cefclient/res/small.ico',
|
||||||
'tests/cefclient/resource_util_win.cpp',
|
'tests/cefclient/resource_util_win.cpp',
|
||||||
'tests/cefclient/window_test_win.cpp',
|
'tests/cefclient/window_test_win.cpp',
|
||||||
],
|
],
|
||||||
'cefclient_sources_mac': [
|
'cefclient_sources_mac': [
|
||||||
'tests/cefclient/cefclient_mac.mm',
|
'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/client_handler_mac.mm',
|
||||||
|
'tests/cefclient/osrenderer.h',
|
||||||
|
'tests/cefclient/osrenderer.cpp',
|
||||||
'tests/cefclient/resource_util_mac.mm',
|
'tests/cefclient/resource_util_mac.mm',
|
||||||
'tests/cefclient/resource_util_posix.cpp',
|
'tests/cefclient/resource_util_posix.cpp',
|
||||||
'tests/cefclient/window_test_mac.mm',
|
'tests/cefclient/window_test_mac.mm',
|
||||||
@ -184,6 +189,7 @@
|
|||||||
'tests/cefclient/mac/English.lproj/InfoPlist.strings',
|
'tests/cefclient/mac/English.lproj/InfoPlist.strings',
|
||||||
'tests/cefclient/mac/English.lproj/MainMenu.xib',
|
'tests/cefclient/mac/English.lproj/MainMenu.xib',
|
||||||
'tests/cefclient/mac/Info.plist',
|
'tests/cefclient/mac/Info.plist',
|
||||||
|
'tests/cefclient/res/osr_test.html',
|
||||||
'<@(cefclient_bundle_resources_common)',
|
'<@(cefclient_bundle_resources_common)',
|
||||||
],
|
],
|
||||||
'cefclient_sources_linux': [
|
'cefclient_sources_linux': [
|
||||||
|
@ -346,6 +346,17 @@ typedef struct _cef_browser_host_t {
|
|||||||
///
|
///
|
||||||
void (CEF_CALLBACK *was_hidden)(struct _cef_browser_host_t* self, int hidden);
|
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 |dirtyRect| region of the view. The browser will call
|
// Invalidate the |dirtyRect| region of the view. The browser will call
|
||||||
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
|
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
|
||||||
|
@ -77,6 +77,18 @@ typedef struct _cef_render_handler_t {
|
|||||||
struct _cef_browser_t* browser, int viewX, int viewY, int* screenX,
|
struct _cef_browser_t* browser, int viewX, int viewY, int* screenX,
|
||||||
int* screenY);
|
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
|
// 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).
|
// should be shown if |show| is true (1) and hidden if |show| is false (0).
|
||||||
|
@ -388,6 +388,17 @@ class CefBrowserHost : public virtual CefBase {
|
|||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void WasHidden(bool hidden) =0;
|
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 |dirtyRect| region of the view. The browser will call
|
// Invalidate the |dirtyRect| region of the view. The browser will call
|
||||||
// CefRenderHandler::OnPaint asynchronously with the updated regions. This
|
// CefRenderHandler::OnPaint asynchronously with the updated regions. This
|
||||||
|
@ -78,6 +78,19 @@ class CefRenderHandler : public virtual CefBase {
|
|||||||
int& screenX,
|
int& screenX,
|
||||||
int& screenY) { return false; }
|
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
|
// 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.
|
// should be shown if |show| is true and hidden if |show| is false.
|
||||||
|
@ -120,6 +120,8 @@ struct CefWindowInfoTraits {
|
|||||||
target->width = src->width;
|
target->width = src->width;
|
||||||
target->height = src->height;
|
target->height = src->height;
|
||||||
target->hidden = src->hidden;
|
target->hidden = src->hidden;
|
||||||
|
target->transparent_painting = src->transparent_painting;
|
||||||
|
target->window_rendering_disabled = src->window_rendering_disabled;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,6 +143,15 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
|
|||||||
this->height = height;
|
this->height = height;
|
||||||
hidden = false;
|
hidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetTransparentPainting(bool transparentPainting) {
|
||||||
|
transparent_painting = transparentPainting;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAsOffScreen(NSView* view) {
|
||||||
|
window_rendering_disabled = true;
|
||||||
|
parent_view = view;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OS_MACOSX
|
#endif // OS_MACOSX
|
||||||
|
@ -966,6 +966,62 @@ enum cef_jsdialog_type_t {
|
|||||||
JSDIALOGTYPE_PROMPT,
|
JSDIALOGTYPE_PROMPT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
// Screen information used when window rendering is disabled. This structure is
|
||||||
|
// passed as a parameter to CefRenderHandler::GetScreenInfo and should be filled
|
||||||
|
// in by the client.
|
||||||
|
///
|
||||||
|
typedef struct _cef_screen_info_t {
|
||||||
|
///
|
||||||
|
// Device scale factor. Specifies the ratio between physical and logical
|
||||||
|
// pixels.
|
||||||
|
///
|
||||||
|
float device_scale_factor;
|
||||||
|
|
||||||
|
///
|
||||||
|
// The screen depth in bits per pixel.
|
||||||
|
///
|
||||||
|
int depth;
|
||||||
|
|
||||||
|
///
|
||||||
|
// The bits per color component. This assumes that the colors are balanced
|
||||||
|
// equally.
|
||||||
|
///
|
||||||
|
int depth_per_component;
|
||||||
|
|
||||||
|
///
|
||||||
|
// This can be true for black and white printers.
|
||||||
|
///
|
||||||
|
bool is_monochrome;
|
||||||
|
|
||||||
|
///
|
||||||
|
// This is set from the rcMonitor member of MONITORINFOEX, to whit:
|
||||||
|
// "A RECT structure that specifies the display monitor rectangle,
|
||||||
|
// expressed in virtual-screen coordinates. Note that if the monitor
|
||||||
|
// is not the primary display monitor, some of the rectangle's
|
||||||
|
// coordinates may be negative values."
|
||||||
|
//
|
||||||
|
// The |rect| and |available_rect| properties are used to determine the
|
||||||
|
// available surface for rendering popup views.
|
||||||
|
///
|
||||||
|
cef_rect_t rect;
|
||||||
|
|
||||||
|
///
|
||||||
|
// This is set from the rcWork member of MONITORINFOEX, to whit:
|
||||||
|
// "A RECT structure that specifies the work area rectangle of the
|
||||||
|
// display monitor that can be used by applications, expressed in
|
||||||
|
// virtual-screen coordinates. Windows uses this rectangle to
|
||||||
|
// maximize an application on the monitor. The rest of the area in
|
||||||
|
// rcMonitor contains system windows such as the task bar and side
|
||||||
|
// bars. Note that if the monitor is not the primary display monitor,
|
||||||
|
// some of the rectangle's coordinates may be negative values".
|
||||||
|
//
|
||||||
|
// The |rect| and |available_rect| properties are used to determine the
|
||||||
|
// available surface for rendering popup views.
|
||||||
|
///
|
||||||
|
cef_rect_t available_rect;
|
||||||
|
} cef_screen_info_t;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Supported menu IDs. Non-English translations can be provided for the
|
// Supported menu IDs. Non-English translations can be provided for the
|
||||||
// IDS_MENU_* strings in CefResourceBundleHandler::GetLocalizedString().
|
// IDS_MENU_* strings in CefResourceBundleHandler::GetLocalizedString().
|
||||||
|
@ -83,6 +83,14 @@ typedef struct _cef_window_info_t {
|
|||||||
// NSView pointer for the parent view.
|
// NSView pointer for the parent view.
|
||||||
cef_window_handle_t parent_view;
|
cef_window_handle_t parent_view;
|
||||||
|
|
||||||
|
// If window rendering is disabled no browser window will be created. Set
|
||||||
|
// |parent_view| to the window that will act as the parent for popup menus,
|
||||||
|
// dialog boxes, etc.
|
||||||
|
bool window_rendering_disabled;
|
||||||
|
|
||||||
|
// Set to true to enable transparent painting.
|
||||||
|
bool transparent_painting;
|
||||||
|
|
||||||
// NSView pointer for the new browser view.
|
// NSView pointer for the new browser view.
|
||||||
cef_window_handle_t view;
|
cef_window_handle_t view;
|
||||||
} cef_window_info_t;
|
} cef_window_info_t;
|
||||||
|
@ -174,6 +174,60 @@ inline bool operator!=(const CefRect& a, const CefRect& b) {
|
|||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CefScreenInfoTraits {
|
||||||
|
typedef cef_screen_info_t struct_type;
|
||||||
|
|
||||||
|
static inline void init(struct_type* s) {}
|
||||||
|
|
||||||
|
static inline void clear(struct_type* s) {}
|
||||||
|
|
||||||
|
static inline void set(const struct_type* src, struct_type* target,
|
||||||
|
bool copy) {
|
||||||
|
target->device_scale_factor = src->device_scale_factor;
|
||||||
|
target->depth = src->depth;
|
||||||
|
target->depth_per_component = src->depth_per_component;
|
||||||
|
target->is_monochrome = src->is_monochrome;
|
||||||
|
target->rect = src->rect;
|
||||||
|
target->available_rect = src->available_rect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
// Class representing the virtual screen information for use when window rendering
|
||||||
|
// is disabled.
|
||||||
|
///
|
||||||
|
class CefScreenInfo : public CefStructBase<CefScreenInfoTraits> {
|
||||||
|
public:
|
||||||
|
typedef CefStructBase<CefScreenInfoTraits> parent;
|
||||||
|
|
||||||
|
CefScreenInfo() : parent() {}
|
||||||
|
CefScreenInfo(const cef_screen_info_t& r) : parent(r) {} // NOLINT(runtime/explicit)
|
||||||
|
CefScreenInfo(const CefScreenInfo& r) : parent(r) {} // NOLINT(runtime/explicit)
|
||||||
|
CefScreenInfo(float device_scale_factor,
|
||||||
|
int depth,
|
||||||
|
int depth_per_component,
|
||||||
|
bool is_monochrome,
|
||||||
|
const CefRect& rect,
|
||||||
|
const CefRect& available_rect) : parent() {
|
||||||
|
Set(device_scale_factor, depth, depth_per_component,
|
||||||
|
is_monochrome, rect, available_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(float device_scale_factor,
|
||||||
|
int depth,
|
||||||
|
int depth_per_component,
|
||||||
|
bool is_monochrome,
|
||||||
|
const CefRect& rect,
|
||||||
|
const CefRect& available_rect) {
|
||||||
|
this->device_scale_factor = device_scale_factor;
|
||||||
|
this->depth = depth;
|
||||||
|
this->depth_per_component = depth_per_component;
|
||||||
|
this->is_monochrome = is_monochrome;
|
||||||
|
this->rect = rect;
|
||||||
|
this->available_rect = available_rect;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct CefKeyEventTraits {
|
struct CefKeyEventTraits {
|
||||||
typedef cef_key_event_t struct_type;
|
typedef cef_key_event_t struct_type;
|
||||||
|
|
||||||
|
@ -4,16 +4,76 @@
|
|||||||
|
|
||||||
#include "libcef/browser/backing_store_osr.h"
|
#include "libcef/browser/backing_store_osr.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "content/browser/renderer_host/dip_util.h"
|
||||||
#include "content/public/browser/render_process_host.h"
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
#include "content/public/browser/render_widget_host.h"
|
||||||
#include "ui/gfx/rect.h"
|
#include "ui/gfx/rect.h"
|
||||||
|
#include "ui/gfx/rect_conversions.h"
|
||||||
|
#include "ui/gfx/size_conversions.h"
|
||||||
|
#include "ui/gfx/vector2d_conversions.h"
|
||||||
#include "ui/surface/transport_dib.h"
|
#include "ui/surface/transport_dib.h"
|
||||||
|
|
||||||
|
// Assume that somewhere along the line, someone will do width * height * 4
|
||||||
|
// with signed numbers. If the maximum value is 2**31, then 2**31 / 4 =
|
||||||
|
// 2**29 and floor(sqrt(2**29)) = 23170.
|
||||||
|
|
||||||
|
// Max height and width for layers
|
||||||
|
static const int kMaxVideoLayerSize = 23170;
|
||||||
|
|
||||||
BackingStoreOSR::BackingStoreOSR(content::RenderWidgetHost* widget,
|
BackingStoreOSR::BackingStoreOSR(content::RenderWidgetHost* widget,
|
||||||
const gfx::Size& size)
|
const gfx::Size& size,
|
||||||
|
float scale_factor)
|
||||||
: content::BackingStore(widget, size),
|
: content::BackingStore(widget, size),
|
||||||
device_(SkBitmap::kARGB_8888_Config, size.width(), size.height(), true),
|
device_scale_factor_(scale_factor) {
|
||||||
canvas_(&device_) {
|
gfx::Size pixel_size = gfx::ToFlooredSize(
|
||||||
canvas_.drawColor(SK_ColorWHITE);
|
gfx::ScaleSize(size, device_scale_factor_));
|
||||||
|
device_.reset(new SkDevice(SkBitmap::kARGB_8888_Config,
|
||||||
|
pixel_size.width(),
|
||||||
|
pixel_size.height(),
|
||||||
|
true));
|
||||||
|
canvas_.reset(new SkCanvas(device_.get()));
|
||||||
|
|
||||||
|
canvas_->drawColor(SK_ColorWHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackingStoreOSR::ScaleFactorChanged(float scale_factor) {
|
||||||
|
if (scale_factor == device_scale_factor_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfx::Size old_pixel_size = gfx::ToFlooredSize(
|
||||||
|
gfx::ScaleSize(size(), device_scale_factor_));
|
||||||
|
device_scale_factor_ = scale_factor;
|
||||||
|
|
||||||
|
gfx::Size pixel_size = gfx::ToFlooredSize(
|
||||||
|
gfx::ScaleSize(size(), device_scale_factor_));
|
||||||
|
|
||||||
|
scoped_ptr<SkDevice> new_device(new SkDevice(SkBitmap::kARGB_8888_Config,
|
||||||
|
pixel_size.width(),
|
||||||
|
pixel_size.height(),
|
||||||
|
true));
|
||||||
|
|
||||||
|
scoped_ptr<SkCanvas> new_canvas(new SkCanvas(new_device.get()));
|
||||||
|
|
||||||
|
// Copy old contents; a low-res flash is better than a black flash.
|
||||||
|
SkPaint copy_paint;
|
||||||
|
copy_paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||||
|
SkIRect src_rect = SkIRect::MakeWH(old_pixel_size.width(),
|
||||||
|
old_pixel_size.height());
|
||||||
|
SkRect dst_rect = SkRect::MakeWH(pixel_size.width(), pixel_size.height());
|
||||||
|
new_canvas.get()->drawBitmapRect(device_->accessBitmap(false), &src_rect,
|
||||||
|
dst_rect, ©_paint);
|
||||||
|
|
||||||
|
canvas_.swap(new_canvas);
|
||||||
|
device_.swap(new_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BackingStoreOSR::MemorySize() {
|
||||||
|
// NOTE: The computation may be different when the canvas is a subrectangle of
|
||||||
|
// a larger bitmap.
|
||||||
|
return gfx::ToFlooredSize(
|
||||||
|
gfx::ScaleSize(size(), device_scale_factor_)).GetArea() * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackingStoreOSR::PaintToBackingStore(
|
void BackingStoreOSR::PaintToBackingStore(
|
||||||
@ -25,36 +85,58 @@ void BackingStoreOSR::PaintToBackingStore(
|
|||||||
const base::Closure& completion_callback,
|
const base::Closure& completion_callback,
|
||||||
bool* scheduled_completion_callback) {
|
bool* scheduled_completion_callback) {
|
||||||
*scheduled_completion_callback = false;
|
*scheduled_completion_callback = false;
|
||||||
|
if (bitmap_rect.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfx::Rect pixel_bitmap_rect = gfx::ToEnclosedRect(
|
||||||
|
gfx::ScaleRect(bitmap_rect, scale_factor));
|
||||||
|
|
||||||
|
const int width = pixel_bitmap_rect.width();
|
||||||
|
const int height = pixel_bitmap_rect.height();
|
||||||
|
|
||||||
|
if (width <= 0 || width > kMaxVideoLayerSize ||
|
||||||
|
height <= 0 || height > kMaxVideoLayerSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TransportDIB* dib = process->GetTransportDIB(bitmap);
|
TransportDIB* dib = process->GetTransportDIB(bitmap);
|
||||||
if (!dib)
|
if (!dib)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SkBitmap src_bitmap;
|
SkBitmap src_bitmap;
|
||||||
src_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
|
src_bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
|
||||||
bitmap_rect.width(),
|
|
||||||
bitmap_rect.height());
|
|
||||||
src_bitmap.setPixels(dib->memory());
|
src_bitmap.setPixels(dib->memory());
|
||||||
|
|
||||||
SkPaint copy_paint;
|
SkPaint copy_paint;
|
||||||
copy_paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
copy_paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||||
|
|
||||||
for (size_t i = 0; i < copy_rects.size(); i++) {
|
for (size_t i = 0; i < copy_rects.size(); i++) {
|
||||||
SkIRect src_rect = SkIRect::MakeXYWH(copy_rects[i].x() - bitmap_rect.x(),
|
const gfx::Rect pixel_copy_rect = gfx::ToEnclosingRect(
|
||||||
copy_rects[i].y() - bitmap_rect.y(),
|
gfx::ScaleRect(copy_rects[i], scale_factor));
|
||||||
copy_rects[i].width(),
|
SkIRect src_rect =
|
||||||
copy_rects[i].height());
|
SkIRect::MakeXYWH(pixel_copy_rect.x() - pixel_bitmap_rect.x(),
|
||||||
SkRect paint_rect = SkRect::MakeXYWH(copy_rects[i].x(),
|
pixel_copy_rect.y() - pixel_bitmap_rect.y(),
|
||||||
copy_rects[i].y(),
|
pixel_copy_rect.width(),
|
||||||
copy_rects[i].width(),
|
pixel_copy_rect.height());
|
||||||
copy_rects[i].height());
|
|
||||||
canvas_.drawBitmapRect(src_bitmap, &src_rect, paint_rect, ©_paint);
|
const gfx::Rect pixel_copy_dst_rect = gfx::ToEnclosingRect(
|
||||||
|
gfx::ScaleRect(copy_rects[i], device_scale_factor_));
|
||||||
|
SkRect paint_rect = SkRect::MakeXYWH(pixel_copy_dst_rect.x(),
|
||||||
|
pixel_copy_dst_rect.y(),
|
||||||
|
pixel_copy_dst_rect.width(),
|
||||||
|
pixel_copy_dst_rect.height());
|
||||||
|
canvas_->drawBitmapRect(src_bitmap, &src_rect, paint_rect, ©_paint);
|
||||||
}
|
}
|
||||||
src_bitmap.setPixels(0);
|
src_bitmap.setPixels(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
||||||
skia::PlatformBitmap* output) {
|
skia::PlatformBitmap* output) {
|
||||||
if (!output->Allocate(rect.width(), rect.height(), true))
|
const int width =
|
||||||
|
std::min(size().width(), rect.width()) * device_scale_factor_;
|
||||||
|
const int height =
|
||||||
|
std::min(size().height(), rect.height()) * device_scale_factor_;
|
||||||
|
if (!output->Allocate(width, height, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SkPaint copy_paint;
|
SkPaint copy_paint;
|
||||||
@ -62,21 +144,30 @@ bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
|||||||
|
|
||||||
SkCanvas canvas(output->GetBitmap());
|
SkCanvas canvas(output->GetBitmap());
|
||||||
canvas.drawColor(SK_ColorWHITE);
|
canvas.drawColor(SK_ColorWHITE);
|
||||||
canvas.drawBitmap(device_.accessBitmap(false), 0, 0, ©_paint);
|
canvas.drawBitmap(device_->accessBitmap(false), 0, 0, ©_paint);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackingStoreOSR::ScrollBackingStore(const gfx::Vector2d& delta,
|
void BackingStoreOSR::ScrollBackingStore(const gfx::Vector2d& delta,
|
||||||
const gfx::Rect& clip_rect,
|
const gfx::Rect& clip_rect,
|
||||||
const gfx::Size& view_size) {
|
const gfx::Size& view_size) {
|
||||||
SkIRect subset_rect = SkIRect::MakeXYWH(clip_rect.x(),
|
gfx::Rect pixel_rect = gfx::ToEnclosingRect(
|
||||||
clip_rect.y(),
|
gfx::ScaleRect(clip_rect, device_scale_factor_));
|
||||||
clip_rect.width(),
|
gfx::Vector2d pixel_delta = gfx::ToFlooredVector2d(
|
||||||
clip_rect.height());
|
gfx::ScaleVector2d(delta, device_scale_factor_));
|
||||||
device_.accessBitmap(true).scrollRect(&subset_rect, delta.x(), delta.y());
|
|
||||||
|
int x = std::min(pixel_rect.x(), pixel_rect.x() - pixel_delta.x());
|
||||||
|
int y = std::min(pixel_rect.y(), pixel_rect.y() - pixel_delta.y());
|
||||||
|
int w = pixel_rect.width() + abs(pixel_delta.x());
|
||||||
|
int h = pixel_rect.height() + abs(pixel_delta.y());
|
||||||
|
SkIRect rect = SkIRect::MakeXYWH(x, y, w, h);
|
||||||
|
|
||||||
|
device_->accessBitmap(true).scrollRect(&rect,
|
||||||
|
pixel_delta.x(),
|
||||||
|
pixel_delta.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* BackingStoreOSR::getPixels() const {
|
const void* BackingStoreOSR::getPixels() const {
|
||||||
return const_cast<BackingStoreOSR*>(this)->device_.
|
return const_cast<BackingStoreOSR*>(this)->device_->
|
||||||
accessBitmap(false).getPixels();
|
accessBitmap(false).getPixels();
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ class BackingStoreOSR : public content::BackingStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BackingStore implementation.
|
// BackingStore implementation.
|
||||||
|
virtual size_t MemorySize() OVERRIDE;
|
||||||
virtual void PaintToBackingStore(
|
virtual void PaintToBackingStore(
|
||||||
content::RenderProcessHost* process,
|
content::RenderProcessHost* process,
|
||||||
TransportDIB::Id bitmap,
|
TransportDIB::Id bitmap,
|
||||||
@ -33,17 +34,22 @@ class BackingStoreOSR : public content::BackingStore {
|
|||||||
const gfx::Rect& clip_rect,
|
const gfx::Rect& clip_rect,
|
||||||
const gfx::Size& view_size) OVERRIDE;
|
const gfx::Size& view_size) OVERRIDE;
|
||||||
|
|
||||||
|
void ScaleFactorChanged(float scale_factor);
|
||||||
|
|
||||||
const void* getPixels() const;
|
const void* getPixels() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Can be instantiated only within CefRenderWidgetHostViewOSR.
|
// Can be instantiated only within CefRenderWidgetHostViewOSR.
|
||||||
friend class CefRenderWidgetHostViewOSR;
|
friend class CefRenderWidgetHostViewOSR;
|
||||||
|
|
||||||
explicit BackingStoreOSR(content::RenderWidgetHost* widget,
|
explicit BackingStoreOSR(content::RenderWidgetHost* widget,
|
||||||
const gfx::Size& size);
|
const gfx::Size& size, float scale_factor);
|
||||||
virtual ~BackingStoreOSR() {}
|
virtual ~BackingStoreOSR() {}
|
||||||
|
|
||||||
SkDevice device_;
|
scoped_ptr<SkDevice> device_;
|
||||||
SkCanvas canvas_;
|
scoped_ptr<SkCanvas> canvas_;
|
||||||
|
|
||||||
|
float device_scale_factor_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BackingStoreOSR);
|
DISALLOW_COPY_AND_ASSIGN(BackingStoreOSR);
|
||||||
};
|
};
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
#include "content/public/common/file_chooser_params.h"
|
#include "content/public/common/file_chooser_params.h"
|
||||||
#include "ui/shell_dialogs/selected_file_info.h"
|
#include "ui/shell_dialogs/selected_file_info.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
#include "libcef/browser/render_widget_host_view_osr.h"
|
#include "libcef/browser/render_widget_host_view_osr.h"
|
||||||
#include "libcef/browser/web_contents_view_osr.h"
|
#include "libcef/browser/web_contents_view_osr.h"
|
||||||
#endif
|
#endif
|
||||||
@ -300,6 +300,9 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
|||||||
|
|
||||||
scoped_refptr<CefBrowserInfo> info =
|
scoped_refptr<CefBrowserInfo> info =
|
||||||
CefContentBrowserClient::Get()->CreateBrowserInfo();
|
CefContentBrowserClient::Get()->CreateBrowserInfo();
|
||||||
|
|
||||||
|
info->set_window_rendering_disabled(
|
||||||
|
CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo));
|
||||||
DCHECK(!info->is_popup());
|
DCHECK(!info->is_popup());
|
||||||
CefRefPtr<CefBrowserHostImpl> browser =
|
CefRefPtr<CefBrowserHostImpl> browser =
|
||||||
CefBrowserHostImpl::Create(windowInfo, new_settings, client, NULL, info,
|
CefBrowserHostImpl::Create(windowInfo, new_settings, client, NULL, info,
|
||||||
@ -346,7 +349,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
|||||||
|
|
||||||
// TODO(port): Implement this method to work on other platforms as part of
|
// TODO(port): Implement this method to work on other platforms as part of
|
||||||
// off-screen rendering support.
|
// off-screen rendering support.
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
if (browser->IsWindowRenderingDisabled()) {
|
if (browser->IsWindowRenderingDisabled()) {
|
||||||
CefRenderWidgetHostViewOSR* view =
|
CefRenderWidgetHostViewOSR* view =
|
||||||
static_cast<CefRenderWidgetHostViewOSR*>(
|
static_cast<CefRenderWidgetHostViewOSR*>(
|
||||||
@ -354,7 +357,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
|||||||
if (view)
|
if (view)
|
||||||
view->set_browser_impl(browser);
|
view->set_browser_impl(browser);
|
||||||
}
|
}
|
||||||
#endif // OS_WIN
|
#endif // defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
|
|
||||||
if (client.get()) {
|
if (client.get()) {
|
||||||
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
|
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
|
||||||
@ -667,6 +670,38 @@ void CefBrowserHostImpl::WasHidden(bool hidden) {
|
|||||||
widget->WasShown();
|
widget->WasShown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserHostImpl::NotifyScreenInfoChanged() {
|
||||||
|
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::Bind(&CefBrowserHostImpl::NotifyScreenInfoChanged, this));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsWindowRenderingDisabled()) {
|
||||||
|
NOTREACHED() << "Window rendering is not disabled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!web_contents())
|
||||||
|
return;
|
||||||
|
|
||||||
|
content::RenderWidgetHostView* view =
|
||||||
|
web_contents()->GetRenderViewHost()->GetView();
|
||||||
|
if (!view)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
|
CefRenderWidgetHostViewOSR* orview =
|
||||||
|
static_cast<CefRenderWidgetHostViewOSR*>(view);
|
||||||
|
|
||||||
|
orview->OnScreenInfoChanged();
|
||||||
|
#else
|
||||||
|
// TODO(port): Implement this method to work on other platforms as part of
|
||||||
|
// off-screen rendering support.
|
||||||
|
NOTREACHED();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
|
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
|
||||||
PaintElementType type) {
|
PaintElementType type) {
|
||||||
if (!IsWindowRenderingDisabled()) {
|
if (!IsWindowRenderingDisabled()) {
|
||||||
@ -683,7 +718,7 @@ void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
|
|||||||
if (!web_contents())
|
if (!web_contents())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
content::RenderWidgetHostView* view =
|
content::RenderWidgetHostView* view =
|
||||||
web_contents()->GetRenderViewHost()->GetView();
|
web_contents()->GetRenderViewHost()->GetView();
|
||||||
CefRenderWidgetHostViewOSR* orview =
|
CefRenderWidgetHostViewOSR* orview =
|
||||||
@ -716,7 +751,7 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
|
|||||||
if (widget)
|
if (widget)
|
||||||
widget->ForwardKeyboardEvent(web_event);
|
widget->ForwardKeyboardEvent(web_event);
|
||||||
} else {
|
} else {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
if (!web_contents())
|
if (!web_contents())
|
||||||
return;
|
return;
|
||||||
content::RenderWidgetHostView* view =
|
content::RenderWidgetHostView* view =
|
||||||
@ -780,7 +815,7 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
|
|||||||
if (widget)
|
if (widget)
|
||||||
widget->ForwardWheelEvent(web_event);
|
widget->ForwardWheelEvent(web_event);
|
||||||
} else {
|
} else {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
if (!web_contents())
|
if (!web_contents())
|
||||||
return;
|
return;
|
||||||
content::RenderWidgetHostView* view =
|
content::RenderWidgetHostView* view =
|
||||||
@ -834,7 +869,7 @@ void CefBrowserHostImpl::SendMouseEvent(const WebKit::WebMouseEvent& event) {
|
|||||||
if (widget)
|
if (widget)
|
||||||
widget->ForwardMouseEvent(event);
|
widget->ForwardMouseEvent(event);
|
||||||
} else {
|
} else {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
if (!web_contents())
|
if (!web_contents())
|
||||||
return;
|
return;
|
||||||
content::RenderWidgetHostView* view =
|
content::RenderWidgetHostView* view =
|
||||||
|
@ -130,6 +130,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||||||
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
||||||
virtual void WasResized() OVERRIDE;
|
virtual void WasResized() OVERRIDE;
|
||||||
virtual void WasHidden(bool hidden) OVERRIDE;
|
virtual void WasHidden(bool hidden) OVERRIDE;
|
||||||
|
virtual void NotifyScreenInfoChanged() OVERRIDE;
|
||||||
virtual void Invalidate(const CefRect& dirtyRect,
|
virtual void Invalidate(const CefRect& dirtyRect,
|
||||||
PaintElementType type) OVERRIDE;
|
PaintElementType type) OVERRIDE;
|
||||||
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
||||||
@ -430,6 +431,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
|||||||
int deltaX, int deltaY);
|
int deltaX, int deltaY);
|
||||||
void PlatformTranslateMouseEvent(WebKit::WebMouseEvent& web_event,
|
void PlatformTranslateMouseEvent(WebKit::WebMouseEvent& web_event,
|
||||||
const CefMouseEvent& mouse_event);
|
const CefMouseEvent& mouse_event);
|
||||||
|
|
||||||
int TranslateModifiers(uint32 cefKeyStates);
|
int TranslateModifiers(uint32 cefKeyStates);
|
||||||
void SendMouseEvent(const WebKit::WebMouseEvent& web_event);
|
void SendMouseEvent(const WebKit::WebMouseEvent& web_event);
|
||||||
|
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
#include "content/public/common/file_chooser_params.h"
|
#include "content/public/common/file_chooser_params.h"
|
||||||
#include "grit/ui_strings.h"
|
#include "grit/ui_strings.h"
|
||||||
#include "net/base/mime_util.h"
|
#include "net/base/mime_util.h"
|
||||||
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
|
||||||
|
#include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h"
|
||||||
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
|
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
|
||||||
|
#include "ui/base/keycodes/keyboard_codes_posix.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
#include "ui/gfx/rect.h"
|
#include "ui/gfx/rect.h"
|
||||||
|
|
||||||
|
|
||||||
// Wrapper NSView for the native view. Necessary to destroy the browser when
|
// Wrapper NSView for the native view. Necessary to destroy the browser when
|
||||||
// the view is deleted.
|
// the view is deleted.
|
||||||
@interface CefBrowserHostView : NSView {
|
@interface CefBrowserHostView : NSView {
|
||||||
@ -142,7 +144,7 @@ void RunOpenFileDialog(const content::FileChooserParams& params,
|
|||||||
NSView* view,
|
NSView* view,
|
||||||
std::vector<base::FilePath>* files) {
|
std::vector<base::FilePath>* files) {
|
||||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||||
|
|
||||||
string16 title;
|
string16 title;
|
||||||
if (!params.title.empty()) {
|
if (!params.title.empty()) {
|
||||||
title = params.title;
|
title = params.title;
|
||||||
@ -201,7 +203,7 @@ bool RunSaveFileDialog(const content::FileChooserParams& params,
|
|||||||
NSView* view,
|
NSView* view,
|
||||||
base::FilePath* file) {
|
base::FilePath* file) {
|
||||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||||
|
|
||||||
string16 title;
|
string16 title;
|
||||||
if (!params.title.empty())
|
if (!params.title.empty())
|
||||||
title = params.title;
|
title = params.title;
|
||||||
@ -338,7 +340,9 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
|
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
|
||||||
return window_info_.view;
|
return IsWindowRenderingDisabled() ?
|
||||||
|
window_info_.parent_view :
|
||||||
|
window_info_.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
|
void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
|
||||||
@ -372,49 +376,214 @@ void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
|
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
return info.window_rendering_disabled ? true : false;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
static NSTimeInterval currentEventTimestamp() {
|
||||||
|
NSEvent* currentEvent = [NSApp currentEvent];
|
||||||
|
if (currentEvent)
|
||||||
|
return [currentEvent timestamp];
|
||||||
|
else {
|
||||||
|
// FIXME(API): In case there is no current event, the timestamp could be
|
||||||
|
// obtained by getting the time since the application started. This involves
|
||||||
|
// taking some more static functions from Chromium code.
|
||||||
|
// Another option is to have the timestamp as a field in CefEvent structures
|
||||||
|
// and let the client provide it.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CefBrowserHostImpl::IsTransparent() {
|
bool CefBrowserHostImpl::IsTransparent() {
|
||||||
return false;
|
return window_info_.transparent_painting != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSUInteger NativeModifiers(int cef_modifiers) {
|
||||||
|
NSUInteger native_modifiers = 0;
|
||||||
|
if (cef_modifiers & EVENTFLAG_SHIFT_DOWN)
|
||||||
|
native_modifiers |= NSShiftKeyMask;
|
||||||
|
if (cef_modifiers & EVENTFLAG_CONTROL_DOWN)
|
||||||
|
native_modifiers |= NSControlKeyMask;
|
||||||
|
if (cef_modifiers & EVENTFLAG_ALT_DOWN)
|
||||||
|
native_modifiers |= NSAlternateKeyMask;
|
||||||
|
if (cef_modifiers & EVENTFLAG_COMMAND_DOWN)
|
||||||
|
native_modifiers |= NSCommandKeyMask;
|
||||||
|
if (cef_modifiers & EVENTFLAG_CAPS_LOCK_ON)
|
||||||
|
native_modifiers |= NSAlphaShiftKeyMask;
|
||||||
|
if (cef_modifiers & EVENTFLAG_NUM_LOCK_ON)
|
||||||
|
native_modifiers |= NSNumericPadKeyMask;
|
||||||
|
|
||||||
|
return native_modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||||
content::NativeWebKeyboardEvent& native_event,
|
content::NativeWebKeyboardEvent& native_event,
|
||||||
const CefKeyEvent& event) {
|
const CefKeyEvent& key_event) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
// Use a synthetic NSEvent in order to obtain the windowsKeyCode member from
|
||||||
NOTIMPLEMENTED();
|
// the NativeWebKeyboardEvent constructor. This is the only member which can
|
||||||
|
// not be easily translated (without hardcoding keyCodes)
|
||||||
|
// Determining whether a modifier key is left or right seems to be done
|
||||||
|
// through the key code as well.
|
||||||
|
|
||||||
|
NSEventType event_type;
|
||||||
|
if (key_event.character == 0 && key_event.unmodified_character == 0) {
|
||||||
|
// Check if both character and unmodified_characther are empty to determine
|
||||||
|
// if this was a NSFlagsChanged event.
|
||||||
|
// A dead key will have an empty character, but a non-empty unmodified
|
||||||
|
// character
|
||||||
|
event_type = NSFlagsChanged;
|
||||||
|
} else {
|
||||||
|
switch (key_event.type) {
|
||||||
|
case KEYEVENT_RAWKEYDOWN:
|
||||||
|
case KEYEVENT_KEYDOWN:
|
||||||
|
case KEYEVENT_CHAR:
|
||||||
|
event_type = NSKeyDown;
|
||||||
|
break;
|
||||||
|
case KEYEVENT_KEYUP:
|
||||||
|
event_type = NSKeyUp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* charactersIgnoringModifiers = [[[NSString alloc]
|
||||||
|
initWithCharacters:&key_event.unmodified_character length:1]
|
||||||
|
autorelease];
|
||||||
|
NSString* characters = [[[NSString alloc]
|
||||||
|
initWithCharacters:&key_event.character length:1] autorelease];
|
||||||
|
|
||||||
|
NSEvent* synthetic_event =
|
||||||
|
[NSEvent keyEventWithType:event_type
|
||||||
|
location:NSMakePoint(0, 0)
|
||||||
|
modifierFlags:NativeModifiers(key_event.modifiers)
|
||||||
|
timestamp:currentEventTimestamp()
|
||||||
|
windowNumber:0
|
||||||
|
context:nil
|
||||||
|
characters:characters
|
||||||
|
charactersIgnoringModifiers:charactersIgnoringModifiers
|
||||||
|
isARepeat:NO
|
||||||
|
keyCode:key_event.native_key_code];
|
||||||
|
|
||||||
|
native_event = content::NativeWebKeyboardEvent(synthetic_event);
|
||||||
|
if (key_event.type == KEYEVENT_CHAR)
|
||||||
|
native_event.type = WebKit::WebInputEvent::Char;
|
||||||
|
|
||||||
|
native_event.isSystemKey = key_event.is_system_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformTranslateClickEvent(
|
void CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||||
WebKit::WebMouseEvent& ev,
|
WebKit::WebMouseEvent& result,
|
||||||
const CefMouseEvent& mouse_event,
|
const CefMouseEvent& mouse_event,
|
||||||
MouseButtonType type,
|
MouseButtonType type,
|
||||||
bool mouseUp, int clickCount) {
|
bool mouseUp, int clickCount) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
PlatformTranslateMouseEvent(result, mouse_event);
|
||||||
NOTIMPLEMENTED();
|
|
||||||
|
switch (type) {
|
||||||
|
case MBT_LEFT:
|
||||||
|
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||||
|
WebKit::WebInputEvent::MouseDown;
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonLeft;
|
||||||
|
break;
|
||||||
|
case MBT_MIDDLE:
|
||||||
|
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||||
|
WebKit::WebInputEvent::MouseDown;
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonMiddle;
|
||||||
|
break;
|
||||||
|
case MBT_RIGHT:
|
||||||
|
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||||
|
WebKit::WebInputEvent::MouseDown;
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonRight;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NOTREACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.clickCount = clickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||||
WebKit::WebMouseEvent& ev,
|
WebKit::WebMouseEvent& result,
|
||||||
const CefMouseEvent& mouse_event,
|
const CefMouseEvent& mouse_event,
|
||||||
bool mouseLeave) {
|
bool mouseLeave) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
PlatformTranslateMouseEvent(result, mouse_event);
|
||||||
NOTIMPLEMENTED();
|
|
||||||
|
if (!mouseLeave) {
|
||||||
|
result.type = WebKit::WebInputEvent::MouseMove;
|
||||||
|
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonLeft;
|
||||||
|
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonMiddle;
|
||||||
|
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonRight;
|
||||||
|
else
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||||
|
} else {
|
||||||
|
result.type = WebKit::WebInputEvent::MouseLeave;
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.clickCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||||
WebKit::WebMouseWheelEvent& ev,
|
WebKit::WebMouseWheelEvent& result,
|
||||||
const CefMouseEvent& mouse_event,
|
const CefMouseEvent& mouse_event,
|
||||||
int deltaX, int deltaY) {
|
int deltaX, int deltaY) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
result = WebKit::WebMouseWheelEvent();
|
||||||
NOTIMPLEMENTED();
|
PlatformTranslateMouseEvent(result, mouse_event);
|
||||||
|
|
||||||
|
result.type = WebKit::WebInputEvent::MouseWheel;
|
||||||
|
|
||||||
|
static const double scrollbarPixelsPerCocoaTick = 40.0;
|
||||||
|
result.deltaX = deltaX;
|
||||||
|
result.deltaY = deltaY;
|
||||||
|
result.wheelTicksX = result.deltaX / scrollbarPixelsPerCocoaTick;
|
||||||
|
result.wheelTicksY = result.deltaY / scrollbarPixelsPerCocoaTick;
|
||||||
|
result.hasPreciseScrollingDeltas = true;
|
||||||
|
|
||||||
|
// Unless the phase and momentumPhase are passed in as parameters to this
|
||||||
|
// function, there is no way to know them
|
||||||
|
result.phase = WebKit::WebMouseWheelEvent::PhaseNone;
|
||||||
|
result.momentumPhase = WebKit::WebMouseWheelEvent::PhaseNone;
|
||||||
|
|
||||||
|
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonLeft;
|
||||||
|
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonMiddle;
|
||||||
|
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonRight;
|
||||||
|
else
|
||||||
|
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
||||||
WebKit::WebMouseEvent& ev,
|
WebKit::WebMouseEvent& result,
|
||||||
const CefMouseEvent& mouse_event) {
|
const CefMouseEvent& mouse_event) {
|
||||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
// position
|
||||||
NOTIMPLEMENTED();
|
result.x = mouse_event.x;
|
||||||
|
result.y = mouse_event.y;
|
||||||
|
result.windowX = result.x;
|
||||||
|
result.windowY = result.y;
|
||||||
|
result.globalX = result.x;
|
||||||
|
result.globalY = result.y;
|
||||||
|
|
||||||
|
if (IsWindowRenderingDisabled()) {
|
||||||
|
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
|
||||||
|
result.modifiers |= TranslateModifiers(mouse_event.modifiers);
|
||||||
|
|
||||||
|
// timestamp - Mac OSX specific
|
||||||
|
result.timeStampSeconds = currentEventTimestamp();
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
|
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
|
||||||
: browser_id_(browser_id),
|
: browser_id_(browser_id),
|
||||||
is_popup_(is_popup),
|
is_popup_(is_popup),
|
||||||
|
is_window_rendering_disabled_(false),
|
||||||
render_process_id_(MSG_ROUTING_NONE),
|
render_process_id_(MSG_ROUTING_NONE),
|
||||||
render_view_id_(MSG_ROUTING_NONE) {
|
render_view_id_(MSG_ROUTING_NONE) {
|
||||||
DCHECK_GT(browser_id, 0);
|
DCHECK_GT(browser_id, 0);
|
||||||
@ -16,6 +17,10 @@ CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
|
|||||||
CefBrowserInfo::~CefBrowserInfo() {
|
CefBrowserInfo::~CefBrowserInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefBrowserInfo::set_window_rendering_disabled(bool disabled) {
|
||||||
|
is_window_rendering_disabled_ = disabled;
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserInfo::set_render_ids(
|
void CefBrowserInfo::set_render_ids(
|
||||||
int render_process_id, int render_view_id) {
|
int render_process_id, int render_view_id) {
|
||||||
base::AutoLock lock_scope(lock_);
|
base::AutoLock lock_scope(lock_);
|
||||||
|
@ -22,6 +22,11 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
|
|||||||
|
|
||||||
int browser_id() const { return browser_id_; };
|
int browser_id() const { return browser_id_; };
|
||||||
bool is_popup() const { return is_popup_; }
|
bool is_popup() const { return is_popup_; }
|
||||||
|
bool is_window_rendering_disabled() const {
|
||||||
|
return is_window_rendering_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_window_rendering_disabled(bool disabled);
|
||||||
|
|
||||||
void set_render_ids(int render_process_id, int render_view_id);
|
void set_render_ids(int render_process_id, int render_view_id);
|
||||||
|
|
||||||
@ -36,6 +41,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
|
|||||||
private:
|
private:
|
||||||
int browser_id_;
|
int browser_id_;
|
||||||
bool is_popup_;
|
bool is_popup_;
|
||||||
|
bool is_window_rendering_disabled_;
|
||||||
|
|
||||||
base::Lock lock_;
|
base::Lock lock_;
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
|
|||||||
routing_id);
|
routing_id);
|
||||||
params->browser_id = info->browser_id();
|
params->browser_id = info->browser_id();
|
||||||
params->is_popup = info->is_popup();
|
params->is_popup = info->is_popup();
|
||||||
|
params->is_window_rendering_disabled = info->is_window_rendering_disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserMessageFilter::OnCreateWindow(
|
void CefBrowserMessageFilter::OnCreateWindow(
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
#include "googleurl/src/gurl.h"
|
#include "googleurl/src/gurl.h"
|
||||||
#include "ui/base/ui_base_switches.h"
|
#include "ui/base/ui_base_switches.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
#include "libcef/browser/web_contents_view_osr.h"
|
#include "libcef/browser/web_contents_view_osr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ CefContentBrowserClient::OverrideCreateWebContentsView(
|
|||||||
*render_view_host_delegate_view = NULL;
|
*render_view_host_delegate_view = NULL;
|
||||||
// TODO(port): Implement this method to work on other platforms as part of
|
// TODO(port): Implement this method to work on other platforms as part of
|
||||||
// off-screen rendering support.
|
// off-screen rendering support.
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
CefBrowserContext* browserContext =
|
CefBrowserContext* browserContext =
|
||||||
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
|
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ CefContentBrowserClient::OverrideCreateWebContentsView(
|
|||||||
*render_view_host_delegate_view = view_or;
|
*render_view_host_delegate_view = view_or;
|
||||||
view = view_or;
|
view = view_or;
|
||||||
}
|
}
|
||||||
#endif // OS_WIN
|
#endif // defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@ bool CefMenuCreatorRunnerMac::RunContextMenu(CefMenuCreator* manager) {
|
|||||||
// [NSApp currentEvent] will return a valid event.
|
// [NSApp currentEvent] will return a valid event.
|
||||||
NSEvent* currentEvent = [NSApp currentEvent];
|
NSEvent* currentEvent = [NSApp currentEvent];
|
||||||
NSWindow* window = [parent_view window];
|
NSWindow* window = [parent_view window];
|
||||||
|
|
||||||
NSPoint position = [window mouseLocationOutsideOfEventStream];
|
NSPoint position = [window mouseLocationOutsideOfEventStream];
|
||||||
|
|
||||||
NSTimeInterval eventTime = [currentEvent timestamp];
|
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||||
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||||
location:position
|
location:position
|
||||||
@ -59,9 +61,33 @@ bool CefMenuCreatorRunnerMac::RunContextMenu(CefMenuCreator* manager) {
|
|||||||
base::mac::ScopedSendingEvent sendingEventScoper;
|
base::mac::ScopedSendingEvent sendingEventScoper;
|
||||||
|
|
||||||
// Show the menu. Blocks until the menu is dismissed.
|
// Show the menu. Blocks until the menu is dismissed.
|
||||||
[NSMenu popUpContextMenu:[menu_controller_ menu]
|
if (manager->browser()->IsWindowRenderingDisabled()) {
|
||||||
withEvent:clickEvent
|
// Showing the menu in OSR is pretty much self contained, only using
|
||||||
forView:parent_view];
|
// 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;
|
return true;
|
||||||
|
@ -19,17 +19,40 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "webkit/glue/webcursor.h"
|
#include "webkit/glue/webcursor.h"
|
||||||
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const float kDefaultScaleFactor = 1.0;
|
||||||
|
|
||||||
|
static WebKit::WebScreenInfo webScreenInfoFrom(const CefScreenInfo& src) {
|
||||||
|
WebKit::WebScreenInfo webScreenInfo;
|
||||||
|
webScreenInfo.deviceScaleFactor = src.device_scale_factor;
|
||||||
|
webScreenInfo.depth = src.depth;
|
||||||
|
webScreenInfo.depthPerComponent = src.depth_per_component;
|
||||||
|
webScreenInfo.isMonochrome = src.is_monochrome;
|
||||||
|
webScreenInfo.rect = WebKit::WebRect(src.rect.x, src.rect.y,
|
||||||
|
src.rect.width, src.rect.height);
|
||||||
|
webScreenInfo.availableRect = WebKit::WebRect(src.available_rect.x,
|
||||||
|
src.available_rect.y,
|
||||||
|
src.available_rect.width,
|
||||||
|
src.available_rect.height);
|
||||||
|
|
||||||
|
return webScreenInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// CefRenderWidgetHostViewOSR, public:
|
// CefRenderWidgetHostViewOSR, public:
|
||||||
|
|
||||||
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||||
content::RenderWidgetHost* widget)
|
content::RenderWidgetHost* widget)
|
||||||
: render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
|
: weak_factory_(this),
|
||||||
about_to_validate_and_paint_(false),
|
render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
|
||||||
parent_host_view_(NULL),
|
parent_host_view_(NULL),
|
||||||
popup_host_view_(NULL),
|
popup_host_view_(NULL),
|
||||||
weak_factory_(this) {
|
about_to_validate_and_paint_(false) {
|
||||||
DCHECK(render_widget_host_);
|
DCHECK(render_widget_host_);
|
||||||
render_widget_host_->SetView(this);
|
render_widget_host_->SetView(this);
|
||||||
|
|
||||||
@ -60,7 +83,7 @@ void CefRenderWidgetHostViewOSR::SetBounds(const gfx::Rect& rect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gfx::NativeView CefRenderWidgetHostViewOSR::GetNativeView() const {
|
gfx::NativeView CefRenderWidgetHostViewOSR::GetNativeView() const {
|
||||||
return browser_impl_.get() ? browser_impl_->GetWindowHandle() : NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::NativeViewId CefRenderWidgetHostViewOSR::GetNativeViewId() const {
|
gfx::NativeViewId CefRenderWidgetHostViewOSR::GetNativeViewId() const {
|
||||||
@ -165,6 +188,12 @@ void CefRenderWidgetHostViewOSR::UpdateCursor(const WebCursor& cursor) {
|
|||||||
HCURSOR hCursor = web_cursor.GetCursor((HINSTANCE)hModule);
|
HCURSOR hCursor = web_cursor.GetCursor((HINSTANCE)hModule);
|
||||||
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
|
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
|
||||||
browser_impl_->GetBrowser(), hCursor);
|
browser_impl_->GetBrowser(), hCursor);
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
// cursor is const, and GetNativeCursor is not
|
||||||
|
WebCursor web_cursor = cursor;
|
||||||
|
NSCursor* native_cursor = web_cursor.GetNativeCursor();
|
||||||
|
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
|
||||||
|
browser_impl_->GetBrowser(), native_cursor);
|
||||||
#else
|
#else
|
||||||
// TODO(port): Implement this method to work on other platforms as part of
|
// TODO(port): Implement this method to work on other platforms as part of
|
||||||
// off-screen rendering support.
|
// off-screen rendering support.
|
||||||
@ -215,11 +244,37 @@ void CefRenderWidgetHostViewOSR::WillWmDestroy() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CefRenderWidgetHostViewOSR::GetScreenInfo(
|
void CefRenderWidgetHostViewOSR::GetScreenInfo(WebKit::WebScreenInfo* results) {
|
||||||
WebKit::WebScreenInfo* results) {
|
if (!browser_impl_.get())
|
||||||
#if defined(OS_WIN)
|
return;
|
||||||
*results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView());
|
|
||||||
#endif
|
CefScreenInfo screen_info(
|
||||||
|
kDefaultScaleFactor, 0, 0, false, CefRect(), CefRect());
|
||||||
|
|
||||||
|
CefRefPtr<CefRenderHandler> handler =
|
||||||
|
browser_impl_->client()->GetRenderHandler();
|
||||||
|
if (!handler->GetScreenInfo(browser_impl_.get(), screen_info) ||
|
||||||
|
screen_info.rect.width == 0 ||
|
||||||
|
screen_info.rect.height == 0 ||
|
||||||
|
screen_info.available_rect.width == 0 ||
|
||||||
|
screen_info.available_rect.height == 0) {
|
||||||
|
// If a screen rectangle was not provided, try using the view rectangle
|
||||||
|
// instead. Otherwise, popup views may be drawn incorrectly, or not at all.
|
||||||
|
CefRect screenRect;
|
||||||
|
if (!handler->GetViewRect(browser_impl_.get(), screenRect)) {
|
||||||
|
NOTREACHED();
|
||||||
|
screenRect = CefRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (screen_info.rect.width == 0 && screen_info.rect.height == 0)
|
||||||
|
screen_info.rect = screenRect;
|
||||||
|
|
||||||
|
if (screen_info.available_rect.width == 0 &&
|
||||||
|
screen_info.available_rect.height == 0)
|
||||||
|
screen_info.available_rect = screenRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
*results = webScreenInfoFrom(screen_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
|
gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
|
||||||
@ -270,7 +325,7 @@ void CefRenderWidgetHostViewOSR::ScrollOffsetChanged() {
|
|||||||
content::BackingStore* CefRenderWidgetHostViewOSR::AllocBackingStore(
|
content::BackingStore* CefRenderWidgetHostViewOSR::AllocBackingStore(
|
||||||
const gfx::Size& size) {
|
const gfx::Size& size) {
|
||||||
return render_widget_host_ ?
|
return render_widget_host_ ?
|
||||||
new BackingStoreOSR(render_widget_host_, size) :
|
new BackingStoreOSR(render_widget_host_, size, GetDeviceScaleFactor()) :
|
||||||
NULL;
|
NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,3 +605,79 @@ void CefRenderWidgetHostViewOSR::SendMouseWheelEvent(
|
|||||||
return;
|
return;
|
||||||
render_widget_host_->ForwardWheelEvent(event);
|
render_widget_host_->ForwardWheelEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefRenderWidgetHostViewOSR::OnScreenInfoChanged() {
|
||||||
|
if (!render_widget_host_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BackingStoreOSR* backing_store =
|
||||||
|
BackingStoreOSR::From(render_widget_host_->GetBackingStore(true));
|
||||||
|
if (backing_store)
|
||||||
|
backing_store->ScaleFactorChanged(GetDeviceScaleFactor());
|
||||||
|
|
||||||
|
// What could be taken from UpdateScreenInfo(window_) - updates the renderer
|
||||||
|
// cached rectangles
|
||||||
|
//render_widget_host_->SendScreenRects();
|
||||||
|
|
||||||
|
render_widget_host_->NotifyScreenInfoChanged();
|
||||||
|
// We might want to change the cursor scale factor here as well - see the
|
||||||
|
// cache for the current_cursor_, as passed by UpdateCursor from the renderer
|
||||||
|
// in the rwhv_aura (current_cursor_.SetScaleFactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
float CefRenderWidgetHostViewOSR::GetDeviceScaleFactor() {
|
||||||
|
if (!browser_impl_.get())
|
||||||
|
return kDefaultScaleFactor;
|
||||||
|
|
||||||
|
CefScreenInfo screen_info(
|
||||||
|
kDefaultScaleFactor, 0, 0, false, CefRect(), CefRect());
|
||||||
|
if (!browser_impl_->GetClient()->GetRenderHandler()->GetScreenInfo(
|
||||||
|
browser_impl_->GetBrowser(), screen_info)) {
|
||||||
|
// Use the default
|
||||||
|
return kDefaultScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return screen_info.device_scale_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
void CefRenderWidgetHostViewOSR::AboutToWaitForBackingStoreMsg() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CefRenderWidgetHostViewOSR::PostProcessEventForPluginIme(
|
||||||
|
const content::NativeWebKeyboardEvent& event) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
#endif // defined(OS_MACOSX)
|
||||||
|
@ -57,6 +57,19 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
|||||||
virtual void Hide() OVERRIDE;
|
virtual void Hide() OVERRIDE;
|
||||||
virtual bool IsShowing() OVERRIDE;
|
virtual bool IsShowing() OVERRIDE;
|
||||||
virtual gfx::Rect GetViewBounds() const OVERRIDE;
|
virtual gfx::Rect GetViewBounds() const 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)
|
||||||
|
|
||||||
// RenderWidgetHostViewPort methods.
|
// RenderWidgetHostViewPort methods.
|
||||||
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
|
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
|
||||||
@ -130,6 +143,13 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
|||||||
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
|
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
virtual void AboutToWaitForBackingStoreMsg() OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool PostProcessEventForPluginIme(
|
||||||
|
const content::NativeWebKeyboardEvent& event) OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
// RenderWidgetHostViewBase methods.
|
// RenderWidgetHostViewBase methods.
|
||||||
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
|
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
|
||||||
|
|
||||||
@ -142,6 +162,9 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
|||||||
void Paint(const std::vector<gfx::Rect>& copy_rects);
|
void Paint(const std::vector<gfx::Rect>& copy_rects);
|
||||||
bool InstallTransparency();
|
bool InstallTransparency();
|
||||||
|
|
||||||
|
void OnScreenInfoChanged();
|
||||||
|
float GetDeviceScaleFactor();
|
||||||
|
|
||||||
void CancelWidget();
|
void CancelWidget();
|
||||||
void NotifyShowWidget();
|
void NotifyShowWidget();
|
||||||
void NotifyHideWidget();
|
void NotifyHideWidget();
|
||||||
|
@ -150,6 +150,7 @@ IPC_SYNC_MESSAGE_CONTROL0_1(
|
|||||||
IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
|
IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
|
||||||
IPC_STRUCT_MEMBER(int, browser_id)
|
IPC_STRUCT_MEMBER(int, browser_id)
|
||||||
IPC_STRUCT_MEMBER(bool, is_popup)
|
IPC_STRUCT_MEMBER(bool, is_popup)
|
||||||
|
IPC_STRUCT_MEMBER(bool, is_window_rendering_disabled)
|
||||||
IPC_STRUCT_END()
|
IPC_STRUCT_END()
|
||||||
|
|
||||||
// Retrieve information about a newly created browser window.
|
// Retrieve information about a newly created browser window.
|
||||||
|
@ -431,6 +431,15 @@ void CefContentRendererClient::RenderViewCreated(
|
|||||||
¶ms));
|
¶ms));
|
||||||
DCHECK_GT(params.browser_id, 0);
|
DCHECK_GT(params.browser_id, 0);
|
||||||
|
|
||||||
|
#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_window_rendering_disabled);
|
||||||
|
#endif
|
||||||
|
|
||||||
CefRefPtr<CefBrowserImpl> browser =
|
CefRefPtr<CefBrowserImpl> browser =
|
||||||
new CefBrowserImpl(render_view, params.browser_id, params.is_popup);
|
new CefBrowserImpl(render_view, params.browser_id, params.is_popup);
|
||||||
browsers_.insert(std::make_pair(render_view, browser));
|
browsers_.insert(std::make_pair(render_view, browser));
|
||||||
|
@ -348,6 +348,18 @@ void CEF_CALLBACK browser_host_was_hidden(struct _cef_browser_host_t* self,
|
|||||||
hidden?true:false);
|
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,
|
void CEF_CALLBACK browser_host_invalidate(struct _cef_browser_host_t* self,
|
||||||
const cef_rect_t* dirtyRect, enum cef_paint_element_type_t type) {
|
const cef_rect_t* dirtyRect, enum cef_paint_element_type_t type) {
|
||||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
@ -518,6 +530,8 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
|
|||||||
browser_host_is_window_rendering_disabled;
|
browser_host_is_window_rendering_disabled;
|
||||||
struct_.struct_.was_resized = browser_host_was_resized;
|
struct_.struct_.was_resized = browser_host_was_resized;
|
||||||
struct_.struct_.was_hidden = browser_host_was_hidden;
|
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_.invalidate = browser_host_invalidate;
|
||||||
struct_.struct_.send_key_event = browser_host_send_key_event;
|
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_click_event = browser_host_send_mouse_click_event;
|
||||||
|
@ -127,6 +127,41 @@ int CEF_CALLBACK render_handler_get_screen_point(
|
|||||||
return _retval;
|
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(
|
void CEF_CALLBACK render_handler_on_popup_show(
|
||||||
struct _cef_render_handler_t* self, cef_browser_t* browser, int show) {
|
struct _cef_render_handler_t* self, cef_browser_t* browser, int show) {
|
||||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
@ -239,6 +274,7 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC(CefRenderHandler* cls)
|
|||||||
struct_.struct_.get_root_screen_rect = render_handler_get_root_screen_rect;
|
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_view_rect = render_handler_get_view_rect;
|
||||||
struct_.struct_.get_screen_point = render_handler_get_screen_point;
|
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_show = render_handler_on_popup_show;
|
||||||
struct_.struct_.on_popup_size = render_handler_on_popup_size;
|
struct_.struct_.on_popup_size = render_handler_on_popup_size;
|
||||||
struct_.struct_.on_paint = render_handler_on_paint;
|
struct_.struct_.on_paint = render_handler_on_paint;
|
||||||
|
@ -290,6 +290,16 @@ void CefBrowserHostCToCpp::WasHidden(bool hidden) {
|
|||||||
hidden);
|
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(const CefRect& dirtyRect,
|
void CefBrowserHostCToCpp::Invalidate(const CefRect& dirtyRect,
|
||||||
PaintElementType type) {
|
PaintElementType type) {
|
||||||
if (CEF_MEMBER_MISSING(struct_, invalidate))
|
if (CEF_MEMBER_MISSING(struct_, invalidate))
|
||||||
|
@ -57,6 +57,7 @@ class CefBrowserHostCToCpp
|
|||||||
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
||||||
virtual void WasResized() OVERRIDE;
|
virtual void WasResized() OVERRIDE;
|
||||||
virtual void WasHidden(bool hidden) OVERRIDE;
|
virtual void WasHidden(bool hidden) OVERRIDE;
|
||||||
|
virtual void NotifyScreenInfoChanged() OVERRIDE;
|
||||||
virtual void Invalidate(const CefRect& dirtyRect,
|
virtual void Invalidate(const CefRect& dirtyRect,
|
||||||
PaintElementType type) OVERRIDE;
|
PaintElementType type) OVERRIDE;
|
||||||
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
||||||
|
@ -82,6 +82,27 @@ bool CefRenderHandlerCToCpp::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
|||||||
return _retval?true:false;
|
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,
|
void CefRenderHandlerCToCpp::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||||
bool show) {
|
bool show) {
|
||||||
if (CEF_MEMBER_MISSING(struct_, on_popup_show))
|
if (CEF_MEMBER_MISSING(struct_, on_popup_show))
|
||||||
|
@ -40,6 +40,8 @@ class CefRenderHandlerCToCpp
|
|||||||
CefRect& rect) OVERRIDE;
|
CefRect& rect) OVERRIDE;
|
||||||
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser, int viewX,
|
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser, int viewX,
|
||||||
int viewY, int& screenX, int& screenY) OVERRIDE;
|
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 OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
||||||
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||||
const CefRect& rect) OVERRIDE;
|
const CefRect& rect) OVERRIDE;
|
||||||
|
@ -41,6 +41,11 @@ patches = [
|
|||||||
'name': 'gyp_331',
|
'name': 'gyp_331',
|
||||||
'path': '../tools/gyp/pylib/',
|
'path': '../tools/gyp/pylib/',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
# Enable popups in offscreen rendering on Mac
|
||||||
|
'name': 'webkit_popups',
|
||||||
|
'path': '../third_party/WebKit/Source/WebKit/chromium/',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
# http://code.google.com/p/chromiumembedded/issues/detail?id=364
|
# http://code.google.com/p/chromiumembedded/issues/detail?id=364
|
||||||
'name': 'spi_webcore_364',
|
'name': 'spi_webcore_364',
|
||||||
|
76
patch/patches/webkit_popups.patch
Normal file
76
patch/patches/webkit_popups.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
Index: src/WebViewImpl.cpp
|
||||||
|
===================================================================
|
||||||
|
--- src/WebViewImpl.cpp (revision 148366)
|
||||||
|
+++ src/WebViewImpl.cpp (working copy)
|
||||||
|
@@ -403,6 +403,7 @@
|
||||||
|
, m_fakeDoubleTapPageScaleFactor(0)
|
||||||
|
, m_fakeDoubleTapUseAnchor(false)
|
||||||
|
, m_contextMenuAllowed(false)
|
||||||
|
+ , m_shouldUseExternalPopupMenus(shouldUseExternalPopupMenus)
|
||||||
|
, m_doingDragAndDrop(false)
|
||||||
|
, m_ignoreInputEvents(false)
|
||||||
|
, m_suppressNextKeypressEvent(false)
|
||||||
|
@@ -3688,9 +3689,14 @@
|
||||||
|
updateLayerTreeViewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
+void WebViewImpl::setUseExternalPopupMenusThisInstance(bool useExternalPopupMenus)
|
||||||
|
+{
|
||||||
|
+ m_shouldUseExternalPopupMenus = useExternalPopupMenus;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool WebViewImpl::useExternalPopupMenus()
|
||||||
|
{
|
||||||
|
- return shouldUseExternalPopupMenus;
|
||||||
|
+ return m_shouldUseExternalPopupMenus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebViewImpl::setEmulatedTextZoomFactor(float textZoomFactor)
|
||||||
|
Index: src/WebViewImpl.h
|
||||||
|
===================================================================
|
||||||
|
--- src/WebViewImpl.h (revision 148366)
|
||||||
|
+++ src/WebViewImpl.h (working copy)
|
||||||
|
@@ -423,7 +423,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
|
||||||
|
{
|
||||||
|
@@ -752,6 +753,8 @@
|
||||||
|
|
||||||
|
bool m_contextMenuAllowed;
|
||||||
|
|
||||||
|
+ bool m_shouldUseExternalPopupMenus;
|
||||||
|
+
|
||||||
|
bool m_doingDragAndDrop;
|
||||||
|
|
||||||
|
bool m_ignoreInputEvents;
|
||||||
|
Index: src/ChromeClientImpl.cpp
|
||||||
|
===================================================================
|
||||||
|
--- src/ChromeClientImpl.cpp (revision 148366)
|
||||||
|
+++ src/ChromeClientImpl.cpp (working copy)
|
||||||
|
@@ -1024,7 +1024,7 @@
|
||||||
|
|
||||||
|
PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(PopupMenuClient* client) const
|
||||||
|
{
|
||||||
|
- if (WebViewImpl::useExternalPopupMenus())
|
||||||
|
+ if (m_webView->useExternalPopupMenus())
|
||||||
|
return adoptRef(new ExternalPopupMenu(client, m_webView->client()));
|
||||||
|
|
||||||
|
return adoptRef(new PopupMenuChromium(client));
|
||||||
|
Index: public/WebView.h
|
||||||
|
===================================================================
|
||||||
|
--- public/WebView.h (revision 148366)
|
||||||
|
+++ public/WebView.h (working copy)
|
||||||
|
@@ -413,6 +413,7 @@
|
||||||
|
|
||||||
|
// Sets whether select popup menus should be rendered by the browser.
|
||||||
|
WEBKIT_EXPORT static void setUseExternalPopupMenus(bool);
|
||||||
|
+ virtual void setUseExternalPopupMenusThisInstance(bool) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Visited link state --------------------------------------------------
|
@ -33,6 +33,7 @@ IDS_DIALOGS BINARY "res\\dialogs.html"
|
|||||||
IDS_DOMACCESS BINARY "res\\domaccess.html"
|
IDS_DOMACCESS BINARY "res\\domaccess.html"
|
||||||
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
|
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
|
||||||
IDS_LOGO BINARY "res\\logo.png"
|
IDS_LOGO BINARY "res\\logo.png"
|
||||||
|
IDS_OSRTEST BINARY "res\\osr_test.html"
|
||||||
IDS_OTHER_TESTS BINARY "res\\other_tests.html"
|
IDS_OTHER_TESTS BINARY "res\\other_tests.html"
|
||||||
IDS_PERFORMANCE BINARY "res\\performance.html"
|
IDS_PERFORMANCE BINARY "res\\performance.html"
|
||||||
IDS_TRANSPARENCY BINARY "res\\transparency.html"
|
IDS_TRANSPARENCY BINARY "res\\transparency.html"
|
||||||
@ -54,7 +55,7 @@ IDI_SMALL ICON "res\small.ico"
|
|||||||
// Menu
|
// Menu
|
||||||
//
|
//
|
||||||
|
|
||||||
IDC_CEFCLIENT MENU
|
IDC_CEFCLIENT MENU
|
||||||
BEGIN
|
BEGIN
|
||||||
POPUP "&File"
|
POPUP "&File"
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -86,7 +87,7 @@ END
|
|||||||
// Accelerator
|
// Accelerator
|
||||||
//
|
//
|
||||||
|
|
||||||
IDC_CEFCLIENT ACCELERATORS
|
IDC_CEFCLIENT ACCELERATORS
|
||||||
BEGIN
|
BEGIN
|
||||||
"?", IDM_ABOUT, ASCII, ALT
|
"?", IDM_ABOUT, ASCII, ALT
|
||||||
"/", IDM_ABOUT, ASCII, ALT
|
"/", IDM_ABOUT, ASCII, ALT
|
||||||
@ -116,12 +117,12 @@ END
|
|||||||
// TEXTINCLUDE
|
// TEXTINCLUDE
|
||||||
//
|
//
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
1 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"resource.h\0"
|
"resource.h\0"
|
||||||
END
|
END
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
2 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||||
"#include ""windows.h""\r\n"
|
"#include ""windows.h""\r\n"
|
||||||
@ -129,7 +130,7 @@ BEGIN
|
|||||||
"\0"
|
"\0"
|
||||||
END
|
END
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
3 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"\0"
|
"\0"
|
||||||
@ -143,7 +144,7 @@ END
|
|||||||
// String Table
|
// String Table
|
||||||
//
|
//
|
||||||
|
|
||||||
STRINGTABLE
|
STRINGTABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_APP_TITLE "cefclient"
|
IDS_APP_TITLE "cefclient"
|
||||||
IDC_CEFCLIENT "CEFCLIENT"
|
IDC_CEFCLIENT "CEFCLIENT"
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
#include "include/cef_runnable.h"
|
#include "include/cef_runnable.h"
|
||||||
|
#include "cefclient/cefclient_osr_widget_mac.h"
|
||||||
#include "cefclient/client_handler.h"
|
#include "cefclient/client_handler.h"
|
||||||
|
#include "cefclient/client_switches.h"
|
||||||
#include "cefclient/resource_util.h"
|
#include "cefclient/resource_util.h"
|
||||||
#include "cefclient/scheme_test.h"
|
#include "cefclient/scheme_test.h"
|
||||||
#include "cefclient/string_util.h"
|
#include "cefclient/string_util.h"
|
||||||
@ -19,6 +21,15 @@
|
|||||||
// The global ClientHandler reference.
|
// The global ClientHandler reference.
|
||||||
extern CefRefPtr<ClientHandler> g_handler;
|
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
|
char szWorkingDir[512]; // The current working directory
|
||||||
|
|
||||||
// Sizes for URL bar layout
|
// Sizes for URL bar layout
|
||||||
@ -93,15 +104,15 @@ const int kWindowHeight = 600;
|
|||||||
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender {
|
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender {
|
||||||
if (!g_handler.get() || !g_handler->GetBrowserId())
|
if (!g_handler.get() || !g_handler->GetBrowserId())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NSString *url = [sender stringValue];
|
NSString *url = [sender stringValue];
|
||||||
|
|
||||||
// if it doesn't already have a prefix, add http. If we can't parse it,
|
// if it doesn't already have a prefix, add http. If we can't parse it,
|
||||||
// just don't bother rather than making things worse.
|
// just don't bother rather than making things worse.
|
||||||
NSURL* tempUrl = [NSURL URLWithString:url];
|
NSURL* tempUrl = [NSURL URLWithString:url];
|
||||||
if (tempUrl && ![tempUrl scheme])
|
if (tempUrl && ![tempUrl scheme])
|
||||||
url = [@"http://" stringByAppendingString:url];
|
url = [@"http://" stringByAppendingString:url];
|
||||||
|
|
||||||
std::string urlStr = [url UTF8String];
|
std::string urlStr = [url UTF8String];
|
||||||
g_handler->GetBrowser()->GetMainFrame()->LoadURL(urlStr);
|
g_handler->GetBrowser()->GetMainFrame()->LoadURL(urlStr);
|
||||||
}
|
}
|
||||||
@ -176,7 +187,7 @@ const int kWindowHeight = 600;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deletes itself.
|
// Deletes itself.
|
||||||
- (void)cleanup:(id)window {
|
- (void)cleanup:(id)window {
|
||||||
[self release];
|
[self release];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,10 +226,10 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
|||||||
- (void)createApp:(id)object {
|
- (void)createApp:(id)object {
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
|
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
|
||||||
|
|
||||||
// Set the delegate for application events.
|
// Set the delegate for application events.
|
||||||
[NSApp setDelegate:self];
|
[NSApp setDelegate:self];
|
||||||
|
|
||||||
// Add the Tests menu.
|
// Add the Tests menu.
|
||||||
NSMenu* menubar = [NSApp mainMenu];
|
NSMenu* menubar = [NSApp mainMenu];
|
||||||
NSMenuItem *testItem = [[[NSMenuItem alloc] initWithTitle:@"Tests"
|
NSMenuItem *testItem = [[[NSMenuItem alloc] initWithTitle:@"Tests"
|
||||||
@ -260,10 +271,10 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
|||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[testItem setSubmenu:testMenu];
|
[testItem setSubmenu:testMenu];
|
||||||
[menubar addItem:testItem];
|
[menubar addItem:testItem];
|
||||||
|
|
||||||
// Create the delegate for control and browser window events.
|
// Create the delegate for control and browser window events.
|
||||||
ClientWindowDelegate* delegate = [[ClientWindowDelegate alloc] init];
|
ClientWindowDelegate* delegate = [[ClientWindowDelegate alloc] init];
|
||||||
|
|
||||||
// Create the main application window.
|
// Create the main application window.
|
||||||
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
|
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
|
||||||
NSRect window_rect = { {0, screen_rect.size.height - kWindowHeight},
|
NSRect window_rect = { {0, screen_rect.size.height - kWindowHeight},
|
||||||
@ -332,7 +343,22 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
|||||||
CefWindowInfo window_info;
|
CefWindowInfo window_info;
|
||||||
CefBrowserSettings settings;
|
CefBrowserSettings settings;
|
||||||
|
|
||||||
window_info.SetAsChild(contentView, 0, 0, kWindowWidth, kWindowHeight);
|
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.SetAsOffScreen(osr_window->GetWindowHandle());
|
||||||
|
window_info.SetTransparentPainting(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(),
|
CefBrowserHost::CreateBrowser(window_info, g_handler.get(),
|
||||||
g_handler->GetStartupURL(), settings);
|
g_handler->GetStartupURL(), settings);
|
||||||
|
|
||||||
@ -407,7 +433,7 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
|||||||
RunOtherTests(g_handler->GetBrowser());
|
RunOtherTests(g_handler->GetBrowser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the application<EFBFBD>s Quit menu item is selected.
|
// Called when the application's Quit menu item is selected.
|
||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
||||||
(NSApplication *)sender {
|
(NSApplication *)sender {
|
||||||
// Request that all browser windows close.
|
// Request that all browser windows close.
|
||||||
@ -445,7 +471,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Initialize the ClientApplication instance.
|
// Initialize the ClientApplication instance.
|
||||||
[ClientApplication sharedApplication];
|
[ClientApplication sharedApplication];
|
||||||
|
|
||||||
// Parse command line arguments.
|
// Parse command line arguments.
|
||||||
AppInitCommandLine(argc, argv);
|
AppInitCommandLine(argc, argv);
|
||||||
|
|
||||||
|
125
tests/cefclient/cefclient_osr_widget_mac.h
Normal file
125
tests/cefclient/cefclient_osr_widget_mac.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// 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 {
|
||||||
|
@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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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;
|
||||||
|
@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;
|
||||||
|
|
||||||
|
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_
|
||||||
|
|
905
tests/cefclient/cefclient_osr_widget_mac.mm
Normal file
905
tests/cefclient/cefclient_osr_widget_mac.mm
Normal file
@ -0,0 +1,905 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
|
||||||
|
#include "cefclient/cefclient_osr_widget_mac.h"
|
||||||
|
|
||||||
|
#include "include/cef_browser.h"
|
||||||
|
#include "include/cef_client.h"
|
||||||
|
#include "cefclient/cefclient.h"
|
||||||
|
#include "cefclient/osrenderer.h"
|
||||||
|
#include "cefclient/resource_util.h"
|
||||||
|
#include "cefclient/util.h"
|
||||||
|
|
||||||
|
@interface ClientOpenGLView ()
|
||||||
|
- (float)getDeviceScaleFactor;
|
||||||
|
- (void)windowDidChangeBackingProperties:(NSNotification*)notification;
|
||||||
|
|
||||||
|
- (bool) isOverPopupWidgetX: (int) x andY: (int) y;
|
||||||
|
- (void) applyPopupOffsetToX: (int&) x andY: (int&) y;
|
||||||
|
- (int) getPopupXOffset;
|
||||||
|
- (int) getPopupYOffset;
|
||||||
|
|
||||||
|
- (void) sendMouseClick: (NSEvent *)event
|
||||||
|
button: (CefBrowserHost::MouseButtonType)type
|
||||||
|
isUp: (bool)isUp;
|
||||||
|
|
||||||
|
- (void) convertRects: (const CefRenderHandler::RectList&) rects
|
||||||
|
toBackingRects: (CefRenderHandler::RectList*) scaled_rects
|
||||||
|
andSize: (const NSSize) size
|
||||||
|
toBackingSize: (NSSize*) scaled_size;
|
||||||
|
|
||||||
|
- (CefRect) convertRectToBackingInternal: (const CefRect&) rect;
|
||||||
|
- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect;
|
||||||
|
|
||||||
|
@property (readwrite, atomic) bool was_last_mouse_down_on_view;
|
||||||
|
@end
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static CefRect convertRect(const NSRect& target, const NSRect& frame) {
|
||||||
|
NSRect rect = target;
|
||||||
|
rect.origin.y = NSMaxY(frame) - NSMaxY(target);
|
||||||
|
return CefRect(rect.origin.x,
|
||||||
|
rect.origin.y,
|
||||||
|
rect.size.width,
|
||||||
|
rect.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ClientOSRHandler::ClientOSRHandler(ClientOpenGLView* view,
|
||||||
|
OSRBrowserProvider* browser_provider)
|
||||||
|
: view_(view),
|
||||||
|
painting_popup_(false) {
|
||||||
|
[view_ retain];
|
||||||
|
view_->browser_provider_ = browser_provider;
|
||||||
|
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
// Do not override the delegate; the mac client already does that
|
||||||
|
if ([view_ respondsToSelector:@selector(backingScaleFactor:)]) {
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
addObserver:view_
|
||||||
|
selector:@selector(windowDidChangeBackingProperties:)
|
||||||
|
name:NSWindowDidChangeBackingPropertiesNotification
|
||||||
|
object:[view_ window]];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientOSRHandler:: ~ClientOSRHandler() {
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([view_ respondsToSelector:@selector(backingScaleFactor:)]) {
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
removeObserver:view_
|
||||||
|
name:NSWindowDidChangeBackingPropertiesNotification
|
||||||
|
object:[view_ window]];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::Disconnect() {
|
||||||
|
[view_ release];
|
||||||
|
view_ = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CefRenderHandler methods
|
||||||
|
void ClientOSRHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||||
|
if (view_)
|
||||||
|
view_->browser_provider_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientOSRHandler::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRect& rect) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// The simulated screen and view rectangle are the same. This is necessary
|
||||||
|
// for popup menus to be located and sized inside the view.
|
||||||
|
const NSRect bounds = [view_ bounds];
|
||||||
|
rect.x = rect.y = 0;
|
||||||
|
rect.width = bounds.size.width;
|
||||||
|
rect.height = bounds.size.height;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientOSRHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||||
|
int viewX,
|
||||||
|
int viewY,
|
||||||
|
int& screenX,
|
||||||
|
int& screenY) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Convert the point from view coordinates to actual screen coordinates.
|
||||||
|
NSRect bounds = [view_ bounds];
|
||||||
|
NSPoint view_pt = NSMakePoint(viewX, bounds.size.height - viewY);
|
||||||
|
NSPoint window_pt = [view_ convertPoint:view_pt toView:nil];
|
||||||
|
NSPoint screen_pt = [[view_ window] convertBaseToScreen:window_pt];
|
||||||
|
screenX = screen_pt.x;
|
||||||
|
screenY = screen_pt.y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientOSRHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefScreenInfo& screen_info) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
NSWindow* window = [view_ window];
|
||||||
|
if (!window)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
screen_info.device_scale_factor = [view_ getDeviceScaleFactor];
|
||||||
|
|
||||||
|
NSScreen* screen = [window screen];
|
||||||
|
if (!screen)
|
||||||
|
screen = [NSScreen deepestScreen];
|
||||||
|
|
||||||
|
screen_info.depth = NSBitsPerPixelFromDepth([screen depth]);
|
||||||
|
screen_info.depth_per_component = NSBitsPerSampleFromDepth([screen depth]);
|
||||||
|
screen_info.is_monochrome =
|
||||||
|
[[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel;
|
||||||
|
// screen_info.is_monochrome = true;
|
||||||
|
screen_info.rect = convertRect([screen frame], [screen frame]);
|
||||||
|
screen_info.available_rect =
|
||||||
|
convertRect([screen visibleFrame], [screen frame]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||||
|
bool show) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!show) {
|
||||||
|
CefRect client_popup_rect = view_->renderer_->popup_rect();
|
||||||
|
|
||||||
|
// Clear the popup rectangles, so that the paint triggered by Invalidate
|
||||||
|
// will not repaint the popup content over the OpenGL view.
|
||||||
|
view_->renderer_->ClearPopupRects();
|
||||||
|
CefRect scaled_rect =
|
||||||
|
[view_ convertRectFromBackingInternal:client_popup_rect];
|
||||||
|
browser->GetHost()->Invalidate(scaled_rect, PET_VIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_->renderer_->OnPopupShow(browser, show);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||||
|
const CefRect& rect) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefRect scaled_rect = [view_ convertRectToBackingInternal:rect];
|
||||||
|
view_->renderer_->OnPopupSize(browser, scaled_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||||
|
PaintElementType type,
|
||||||
|
const RectList& dirtyRects,
|
||||||
|
const void* buffer,
|
||||||
|
int width, int height) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!view_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (painting_popup_) {
|
||||||
|
RectList scaled_dirty_rects;
|
||||||
|
NSSize scaled_size = NSMakeSize(0, 0);
|
||||||
|
[view_ convertRects:dirtyRects
|
||||||
|
toBackingRects:&scaled_dirty_rects
|
||||||
|
andSize:NSMakeSize(width, height)
|
||||||
|
toBackingSize:&scaled_size];
|
||||||
|
view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer,
|
||||||
|
scaled_size.width, scaled_size.height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSOpenGLContext* context = [view_ openGLContext];
|
||||||
|
[context makeCurrentContext];
|
||||||
|
|
||||||
|
RectList scaled_dirty_rects;
|
||||||
|
NSSize scaled_size = NSMakeSize(0, 0);
|
||||||
|
[view_ convertRects:dirtyRects
|
||||||
|
toBackingRects:&scaled_dirty_rects
|
||||||
|
andSize:NSMakeSize(width, height)
|
||||||
|
toBackingSize:&scaled_size];
|
||||||
|
|
||||||
|
view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer,
|
||||||
|
scaled_size.width, scaled_size.height);
|
||||||
|
|
||||||
|
if (type == PET_VIEW && !view_->renderer_->popup_rect().IsEmpty()) {
|
||||||
|
painting_popup_ = true;
|
||||||
|
CefRect client_popup_rect(0, 0,
|
||||||
|
view_->renderer_->popup_rect().width,
|
||||||
|
view_->renderer_->popup_rect().height);
|
||||||
|
|
||||||
|
CefRect scaled_popup_rect =
|
||||||
|
[view_ convertRectFromBackingInternal:client_popup_rect];
|
||||||
|
|
||||||
|
browser->GetHost()->Invalidate(scaled_popup_rect, PET_POPUP);
|
||||||
|
painting_popup_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
view_->renderer_->Render();
|
||||||
|
[context flushBuffer];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefCursorHandle cursor) {
|
||||||
|
REQUIRE_UI_THREAD();
|
||||||
|
[cursor set];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientOSRHandler::SetLoading(bool isLoading) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation ClientOpenGLView
|
||||||
|
|
||||||
|
@synthesize was_last_mouse_down_on_view = was_last_mouse_down_on_view_;
|
||||||
|
|
||||||
|
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency {
|
||||||
|
NSOpenGLPixelFormat * pixelFormat =
|
||||||
|
[[NSOpenGLPixelFormat alloc]
|
||||||
|
initWithAttributes:(NSOpenGLPixelFormatAttribute[]) {
|
||||||
|
NSOpenGLPFAWindow,
|
||||||
|
NSOpenGLPFADoubleBuffer,
|
||||||
|
NSOpenGLPFADepthSize,
|
||||||
|
32,
|
||||||
|
0}];
|
||||||
|
[pixelFormat autorelease];
|
||||||
|
|
||||||
|
self = [super initWithFrame:frame pixelFormat:pixelFormat];
|
||||||
|
if (self) {
|
||||||
|
renderer_ = new ClientOSRenderer(transparency);
|
||||||
|
rotating_ = false;
|
||||||
|
|
||||||
|
tracking_area_ =
|
||||||
|
[[NSTrackingArea alloc] initWithRect:frame
|
||||||
|
options:NSTrackingMouseMoved |
|
||||||
|
NSTrackingActiveInActiveApp |
|
||||||
|
NSTrackingInVisibleRect
|
||||||
|
owner:self
|
||||||
|
userInfo:nil];
|
||||||
|
[self addTrackingArea:tracking_area_];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
|
||||||
|
// enable HiDPI buffer
|
||||||
|
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser) {
|
||||||
|
static_cast<ClientOSRHandler*>(
|
||||||
|
browser->GetHost()->GetClient()->GetRenderHandler().get())->Disconnect();
|
||||||
|
browser->GetHost()->CloseBrowser(true);
|
||||||
|
browser = NULL;
|
||||||
|
}
|
||||||
|
if (renderer_)
|
||||||
|
delete renderer_;
|
||||||
|
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CefRefPtr<CefBrowser>)getBrowser {
|
||||||
|
return browser_provider_->GetBrowser();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFrame:(NSRect)frameRect {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[super setFrame:frameRect];
|
||||||
|
browser->GetHost()->WasResized();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) sendMouseClick:(NSEvent *)event
|
||||||
|
button: (CefBrowserHost::MouseButtonType)type
|
||||||
|
isUp: (bool)isUp {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefMouseEvent mouseEvent;
|
||||||
|
[self getMouseEvent: mouseEvent forEvent: event];
|
||||||
|
NSPoint point = [self getClickPointForEvent:event];
|
||||||
|
if (!isUp)
|
||||||
|
self.was_last_mouse_down_on_view = ![self isOverPopupWidgetX: point.x
|
||||||
|
andY: point.y];
|
||||||
|
else if (self.was_last_mouse_down_on_view &&
|
||||||
|
[self isOverPopupWidgetX:point.x andY: point.y] &&
|
||||||
|
([self getPopupXOffset] || [self getPopupYOffset])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
browser->GetHost()->SendMouseClickEvent(mouseEvent,
|
||||||
|
type,
|
||||||
|
isUp,
|
||||||
|
[event clickCount]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(NSEvent *)event {
|
||||||
|
[self sendMouseClick: event button:MBT_LEFT isUp:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rightMouseDown:(NSEvent *)event {
|
||||||
|
if ([event modifierFlags] & NSShiftKeyMask) {
|
||||||
|
// Start rotation effect.
|
||||||
|
last_mouse_pos_ = cur_mouse_pos_ = [self getClickPointForEvent:event];
|
||||||
|
rotating_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self sendMouseClick: event button:MBT_RIGHT isUp:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)otherMouseDown:(NSEvent *)event {
|
||||||
|
[self sendMouseClick: event button:MBT_MIDDLE isUp:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseUp:(NSEvent *)event {
|
||||||
|
[self sendMouseClick: event button: MBT_LEFT isUp: true];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rightMouseUp:(NSEvent *)event {
|
||||||
|
if (rotating_) {
|
||||||
|
// End rotation effect.
|
||||||
|
renderer_->SetSpin(0, 0);
|
||||||
|
rotating_ = false;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[self sendMouseClick: event button: MBT_RIGHT isUp: true];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)otherMouseUp:(NSEvent *)event {
|
||||||
|
[self sendMouseClick: event button: MBT_MIDDLE isUp: true];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseMoved:(NSEvent *)event {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rotating_) {
|
||||||
|
// Apply rotation effect.
|
||||||
|
cur_mouse_pos_ = [self getClickPointForEvent:event];;
|
||||||
|
renderer_->IncrementSpin((cur_mouse_pos_.x - last_mouse_pos_.x),
|
||||||
|
(cur_mouse_pos_.y - last_mouse_pos_.y));
|
||||||
|
last_mouse_pos_ = cur_mouse_pos_;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefMouseEvent mouseEvent;
|
||||||
|
[self getMouseEvent: mouseEvent forEvent: event];
|
||||||
|
browser->GetHost()->SendMouseMoveEvent(mouseEvent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDragged:(NSEvent *)event {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rightMouseDragged:(NSEvent *)event {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)otherMouseDragged:(NSEvent *)event {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseEntered:(NSEvent *)event {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseExited:(NSEvent *)event {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefMouseEvent mouseEvent;
|
||||||
|
[self getMouseEvent: mouseEvent forEvent: event];
|
||||||
|
browser->GetHost()->SendMouseMoveEvent(mouseEvent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)keyDown:(NSEvent *)event {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefKeyEvent keyEvent;
|
||||||
|
[self getKeyEvent:keyEvent forEvent:event];
|
||||||
|
|
||||||
|
keyEvent.type = KEYEVENT_KEYDOWN;
|
||||||
|
browser->GetHost()->SendKeyEvent(keyEvent);
|
||||||
|
|
||||||
|
if ([event modifierFlags] & (NSNumericPadKeyMask | NSFunctionKeyMask)) {
|
||||||
|
// Don't send a Char event for non-char keys like arrows, function keys and
|
||||||
|
// clear.
|
||||||
|
switch (keyEvent.native_key_code) {
|
||||||
|
case 81: // =
|
||||||
|
case 75: // /
|
||||||
|
case 67: // *
|
||||||
|
case 78: // -
|
||||||
|
case 69: // +
|
||||||
|
case 76: // Enter
|
||||||
|
case 65: // .
|
||||||
|
case 82: // 0
|
||||||
|
case 83: // 1
|
||||||
|
case 84: // 2
|
||||||
|
case 85: // 3
|
||||||
|
case 86: // 4
|
||||||
|
case 87: // 5
|
||||||
|
case 88: // 6
|
||||||
|
case 89: // 7
|
||||||
|
case 91: // 8
|
||||||
|
case 92: // 9
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyEvent.type = KEYEVENT_CHAR;
|
||||||
|
browser->GetHost()->SendKeyEvent(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)keyUp:(NSEvent *)event {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefKeyEvent keyEvent;
|
||||||
|
[self getKeyEvent:keyEvent forEvent:event];
|
||||||
|
|
||||||
|
keyEvent.type = KEYEVENT_KEYUP;
|
||||||
|
browser->GetHost()->SendKeyEvent(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)flagsChanged:(NSEvent *)event {
|
||||||
|
if ([self isKeyUpEvent:event])
|
||||||
|
[self keyUp:event];
|
||||||
|
else
|
||||||
|
[self keyDown:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollWheel:(NSEvent *)event {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CGEventRef cgEvent = [event CGEvent];
|
||||||
|
ASSERT(cgEvent);
|
||||||
|
|
||||||
|
int deltaX =
|
||||||
|
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
|
||||||
|
int deltaY =
|
||||||
|
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
|
||||||
|
|
||||||
|
CefMouseEvent mouseEvent;
|
||||||
|
[self getMouseEvent: mouseEvent forEvent: event];
|
||||||
|
browser->GetHost()->SendMouseWheelEvent(mouseEvent, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)canBecomeKeyView {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
return (browser != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)acceptsFirstResponder {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
return (browser != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)becomeFirstResponder {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser) {
|
||||||
|
browser->GetHost()->SendFocusEvent(true);
|
||||||
|
return [super becomeFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)resignFirstResponder {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser) {
|
||||||
|
browser->GetHost()->SendFocusEvent(false);
|
||||||
|
return [super resignFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)undo:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)redo:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cut:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Cut();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)copy:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)paste:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Paste();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)delete:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)selectAll:(id)sender {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (browser)
|
||||||
|
browser->GetFocusedFrame()->SelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSPoint)getClickPointForEvent:(NSEvent*)event {
|
||||||
|
NSPoint windowLocal = [event locationInWindow];
|
||||||
|
NSPoint contentLocal = [self convertPoint:windowLocal fromView:nil];
|
||||||
|
|
||||||
|
NSPoint point;
|
||||||
|
point.x = contentLocal.x;
|
||||||
|
point.y = [self frame].size.height - contentLocal.y; // Flip y.
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)getKeyEvent:(CefKeyEvent &)keyEvent forEvent:(NSEvent *)event {
|
||||||
|
if ([event type] == NSKeyDown || [event type] == NSKeyUp) {
|
||||||
|
NSString* s = [event characters];
|
||||||
|
if ([s length] > 0)
|
||||||
|
keyEvent.character = [s characterAtIndex:0];
|
||||||
|
|
||||||
|
s = [event charactersIgnoringModifiers];
|
||||||
|
if ([s length] > 0)
|
||||||
|
keyEvent.unmodified_character = [s characterAtIndex:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([event type] == NSFlagsChanged) {
|
||||||
|
keyEvent.character = 0;
|
||||||
|
keyEvent.unmodified_character = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyEvent.native_key_code = [event keyCode];
|
||||||
|
|
||||||
|
keyEvent.modifiers = [self getModifiersForEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event {
|
||||||
|
NSPoint point = [self getClickPointForEvent:event];
|
||||||
|
mouseEvent.x = point.x;
|
||||||
|
mouseEvent.y = point.y;
|
||||||
|
|
||||||
|
if ([self isOverPopupWidgetX:mouseEvent.x andY: mouseEvent.y]) {
|
||||||
|
[self applyPopupOffsetToX:mouseEvent.x andY: mouseEvent.y];
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseEvent.modifiers = [self getModifiersForEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)getModifiersForEvent:(NSEvent*)event {
|
||||||
|
int modifiers = 0;
|
||||||
|
|
||||||
|
if ([event modifierFlags] & NSControlKeyMask)
|
||||||
|
modifiers |= EVENTFLAG_CONTROL_DOWN;
|
||||||
|
if ([event modifierFlags] & NSShiftKeyMask)
|
||||||
|
modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||||
|
if ([event modifierFlags] & NSAlternateKeyMask)
|
||||||
|
modifiers |= EVENTFLAG_ALT_DOWN;
|
||||||
|
if ([event modifierFlags] & NSCommandKeyMask)
|
||||||
|
modifiers |= EVENTFLAG_COMMAND_DOWN;
|
||||||
|
if ([event modifierFlags] & NSAlphaShiftKeyMask)
|
||||||
|
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
|
||||||
|
|
||||||
|
if ([event type] == NSKeyUp ||
|
||||||
|
[event type] == NSKeyDown ||
|
||||||
|
[event type] == NSFlagsChanged) {
|
||||||
|
// Only perform this check for key events
|
||||||
|
if ([self isKeyPadEvent:event])
|
||||||
|
modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OS X does not have a modifier for NumLock, so I'm not entirely sure how to
|
||||||
|
// set EVENTFLAG_NUM_LOCK_ON;
|
||||||
|
//
|
||||||
|
// There is no EVENTFLAG for the function key either.
|
||||||
|
|
||||||
|
// Mouse buttons
|
||||||
|
switch ([event type]) {
|
||||||
|
case NSLeftMouseDragged:
|
||||||
|
case NSLeftMouseDown:
|
||||||
|
case NSLeftMouseUp:
|
||||||
|
modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||||
|
break;
|
||||||
|
case NSRightMouseDragged:
|
||||||
|
case NSRightMouseDown:
|
||||||
|
case NSRightMouseUp:
|
||||||
|
modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON;
|
||||||
|
break;
|
||||||
|
case NSOtherMouseDragged:
|
||||||
|
case NSOtherMouseDown:
|
||||||
|
case NSOtherMouseUp:
|
||||||
|
modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isKeyUpEvent:(NSEvent*)event {
|
||||||
|
if ([event type] != NSFlagsChanged)
|
||||||
|
return [event type] == NSKeyUp;
|
||||||
|
|
||||||
|
// FIXME: This logic fails if the user presses both Shift keys at once, for
|
||||||
|
// example: we treat releasing one of them as keyDown.
|
||||||
|
switch ([event keyCode]) {
|
||||||
|
case 54: // Right Command
|
||||||
|
case 55: // Left Command
|
||||||
|
return ([event modifierFlags] & NSCommandKeyMask) == 0;
|
||||||
|
|
||||||
|
case 57: // Capslock
|
||||||
|
return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0;
|
||||||
|
|
||||||
|
case 56: // Left Shift
|
||||||
|
case 60: // Right Shift
|
||||||
|
return ([event modifierFlags] & NSShiftKeyMask) == 0;
|
||||||
|
|
||||||
|
case 58: // Left Alt
|
||||||
|
case 61: // Right Alt
|
||||||
|
return ([event modifierFlags] & NSAlternateKeyMask) == 0;
|
||||||
|
|
||||||
|
case 59: // Left Ctrl
|
||||||
|
case 62: // Right Ctrl
|
||||||
|
return ([event modifierFlags] & NSControlKeyMask) == 0;
|
||||||
|
|
||||||
|
case 63: // Function
|
||||||
|
return ([event modifierFlags] & NSFunctionKeyMask) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isKeyPadEvent:(NSEvent*)event {
|
||||||
|
if ([event modifierFlags] & NSNumericPadKeyMask)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch ([event keyCode]) {
|
||||||
|
case 71: // Clear
|
||||||
|
case 81: // =
|
||||||
|
case 75: // /
|
||||||
|
case 67: // *
|
||||||
|
case 78: // -
|
||||||
|
case 69: // +
|
||||||
|
case 76: // Enter
|
||||||
|
case 65: // .
|
||||||
|
case 82: // 0
|
||||||
|
case 83: // 1
|
||||||
|
case 84: // 2
|
||||||
|
case 85: // 3
|
||||||
|
case 86: // 4
|
||||||
|
case 87: // 5
|
||||||
|
case 88: // 6
|
||||||
|
case 89: // 7
|
||||||
|
case 91: // 8
|
||||||
|
case 92: // 9
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowDidChangeBackingProperties:(NSNotification*)notification {
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
// This delegate method is only called on 10.7 and later, so don't worry about
|
||||||
|
// other backing changes calling it on 10.6 or earlier
|
||||||
|
CGFloat newBackingScaleFactor = [self getDeviceScaleFactor];
|
||||||
|
NSNumber* oldBackingScaleFactor =
|
||||||
|
[[notification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey];
|
||||||
|
if (newBackingScaleFactor != [oldBackingScaleFactor doubleValue]) {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
browser->GetHost()->NotifyScreenInfoChanged();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect: (NSRect) dirtyRect {
|
||||||
|
// The Invalidate below fixes flicker when resizing
|
||||||
|
if ([self inLiveResize]) {
|
||||||
|
CefRefPtr<CefBrowser> browser = [self getBrowser];
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NSRect b = [self bounds];
|
||||||
|
CefRect boundsRect = CefRect((int)b.origin.x,
|
||||||
|
(int)b.origin.y,
|
||||||
|
(int)b.size.width,
|
||||||
|
(int)b.size.height);
|
||||||
|
browser->GetHost()->Invalidate(boundsRect, PET_VIEW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility - private
|
||||||
|
- (float)getDeviceScaleFactor {
|
||||||
|
float deviceScaleFactor = 1;
|
||||||
|
NSWindow* window = [self window];
|
||||||
|
if (!window)
|
||||||
|
return deviceScaleFactor;
|
||||||
|
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([window respondsToSelector:@selector(backingScaleFactor)])
|
||||||
|
deviceScaleFactor = [window backingScaleFactor];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
deviceScaleFactor = [window userSpaceScaleFactor];
|
||||||
|
|
||||||
|
return deviceScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (bool) isOverPopupWidgetX: (int) x andY: (int) y {
|
||||||
|
CefRect rc = [self convertRectFromBackingInternal: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) getPopupXOffset {
|
||||||
|
int original_x =
|
||||||
|
[self convertRectFromBackingInternal:renderer_->original_popup_rect()].x;
|
||||||
|
int popup_x =
|
||||||
|
[self convertRectFromBackingInternal:renderer_->popup_rect()].x;
|
||||||
|
|
||||||
|
return original_x - popup_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) getPopupYOffset {
|
||||||
|
int original_y =
|
||||||
|
[self convertRectFromBackingInternal:renderer_->original_popup_rect()].y;
|
||||||
|
int popup_y =
|
||||||
|
[self convertRectFromBackingInternal:renderer_->popup_rect()].y;
|
||||||
|
|
||||||
|
return original_y - popup_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) applyPopupOffsetToX: (int&) x andY: (int&) y {
|
||||||
|
if ([self isOverPopupWidgetX:x andY:y]) {
|
||||||
|
x += [self getPopupXOffset];
|
||||||
|
y += [self getPopupYOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) convertRects: (const CefRenderHandler::RectList&) rects
|
||||||
|
toBackingRects: (CefRenderHandler::RectList*) scaled_rects
|
||||||
|
andSize: (const NSSize) size
|
||||||
|
toBackingSize: (NSSize*) scaled_size {
|
||||||
|
*scaled_rects = rects;
|
||||||
|
*scaled_size = size;
|
||||||
|
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([self getDeviceScaleFactor] != 1 &&
|
||||||
|
[self respondsToSelector:@selector(convertSizeToBacking:)] &&
|
||||||
|
[self respondsToSelector:@selector(convertRectToBacking:)]) {
|
||||||
|
CefRenderHandler::RectList scaled_dirty_rects;
|
||||||
|
for (size_t i = 0; i < rects.size(); ++i) {
|
||||||
|
scaled_dirty_rects.push_back([self convertRectToBackingInternal:rects[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*scaled_rects = scaled_dirty_rects;
|
||||||
|
*scaled_size = [self convertSizeToBacking:size];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CefRect) convertRectToBackingInternal: (const CefRect&) rect {
|
||||||
|
if ([self getDeviceScaleFactor] == 1)
|
||||||
|
return rect;
|
||||||
|
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([self respondsToSelector:@selector(convertRectToBacking:)]) {
|
||||||
|
NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
NSRect scaled_rect = [self convertRectToBacking:old_rect];
|
||||||
|
return CefRect((int)scaled_rect.origin.x,
|
||||||
|
(int)scaled_rect.origin.y,
|
||||||
|
(int)scaled_rect.size.width,
|
||||||
|
(int)scaled_rect.size.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect {
|
||||||
|
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
|
__MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if ([self respondsToSelector:@selector(convertRectFromBacking:)]) {
|
||||||
|
NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
NSRect scaled_rect = [self convertRectFromBacking:old_rect];
|
||||||
|
return CefRect((int)scaled_rect.origin.x,
|
||||||
|
(int)scaled_rect.origin.y,
|
||||||
|
(int)scaled_rect.size.width,
|
||||||
|
(int)scaled_rect.size.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
||||||
|
bool transparent,
|
||||||
|
CefWindowHandle parentView,
|
||||||
|
const CefRect& frame) {
|
||||||
|
return new OSRWindow(browser_provider, transparent, parentView, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||||
|
bool transparent,
|
||||||
|
CefWindowHandle parentView,
|
||||||
|
const CefRect& frame) {
|
||||||
|
NSRect window_rect = NSMakeRect(frame.x, frame.y, frame.width, frame.height);
|
||||||
|
ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect
|
||||||
|
andTransparency:transparent];
|
||||||
|
this->view_ = view;
|
||||||
|
[parentView addSubview:view];
|
||||||
|
[view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||||
|
[view setAutoresizesSubviews: true];
|
||||||
|
|
||||||
|
this->render_client = new ClientOSRHandler(view, browser_provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSRWindow::~OSRWindow() {
|
||||||
|
}
|
@ -99,6 +99,11 @@ bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
|||||||
|
|
||||||
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||||
bool show) {
|
bool show) {
|
||||||
|
if (!show) {
|
||||||
|
CefRect dirty_rect = renderer_.popup_rect();
|
||||||
|
renderer_.ClearPopupRects();
|
||||||
|
browser->GetHost()->Invalidate(dirty_rect, PET_VIEW);
|
||||||
|
}
|
||||||
renderer_.OnPopupShow(browser, show);
|
renderer_.OnPopupShow(browser, show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,13 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "cefclient/client_handler.h"
|
#include "cefclient/client_handler.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
#include "include/cef_path_util.h"
|
#include "include/cef_path_util.h"
|
||||||
@ -517,6 +520,13 @@ bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
|||||||
return m_OSRHandler->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
|
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,
|
void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||||
bool show) {
|
bool show) {
|
||||||
if (!m_OSRHandler.get())
|
if (!m_OSRHandler.get())
|
||||||
|
@ -194,6 +194,8 @@ class ClientHandler : public CefClient,
|
|||||||
int viewY,
|
int viewY,
|
||||||
int& screenX,
|
int& screenX,
|
||||||
int& screenY) OVERRIDE;
|
int& screenY) OVERRIDE;
|
||||||
|
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefScreenInfo& screen_info) OVERRIDE;
|
||||||
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
||||||
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||||
const CefRect& rect) OVERRIDE;
|
const CefRect& rect) OVERRIDE;
|
||||||
|
@ -143,11 +143,7 @@ void ClientOSRenderer::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
|||||||
bool show) {
|
bool show) {
|
||||||
if (!show) {
|
if (!show) {
|
||||||
// Clear the popup rectangle.
|
// Clear the popup rectangle.
|
||||||
CefRect popup_rect = popup_rect_;
|
ClearPopupRects();
|
||||||
popup_rect_.Set(0, 0, 0, 0);
|
|
||||||
original_popup_rect_.Set(0, 0, 0, 0);
|
|
||||||
// Invalidate the previous popup rectangle so that it will be repainted.
|
|
||||||
browser->GetHost()->Invalidate(popup_rect, PET_VIEW);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +175,11 @@ CefRect ClientOSRenderer::GetPopupRectInWebView(const CefRect& original_rect) {
|
|||||||
return rc;
|
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,
|
void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||||
CefRenderHandler::PaintElementType type,
|
CefRenderHandler::PaintElementType type,
|
||||||
const CefRenderHandler::RectList& dirtyRects,
|
const CefRenderHandler::RectList& dirtyRects,
|
||||||
|
@ -47,6 +47,7 @@ class ClientOSRenderer {
|
|||||||
const CefRect& original_popup_rect() const { return original_popup_rect_; }
|
const CefRect& original_popup_rect() const { return original_popup_rect_; }
|
||||||
|
|
||||||
CefRect GetPopupRectInWebView(const CefRect& original_rect);
|
CefRect GetPopupRectInWebView(const CefRect& original_rect);
|
||||||
|
void ClearPopupRects();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool transparent_;
|
bool transparent_;
|
||||||
|
69
tests/cefclient/res/osr_test.html
Normal file
69
tests/cefclient/res/osr_test.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<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;}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function sendBrowserMessage(paramString) {
|
||||||
|
app.sendMessage("osrtest", [paramString]);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = event.type;
|
||||||
|
|
||||||
|
if (event.type == "click")
|
||||||
|
param += event.button;
|
||||||
|
|
||||||
|
sendBrowserMessage(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
</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=''></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>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -44,11 +44,12 @@
|
|||||||
#define IDS_LOCALSTORAGE 1003
|
#define IDS_LOCALSTORAGE 1003
|
||||||
#define IDS_LOGO 1004
|
#define IDS_LOGO 1004
|
||||||
#define IDS_LOGOBALL 1005
|
#define IDS_LOGOBALL 1005
|
||||||
#define IDS_OTHER_TESTS 1006
|
#define IDS_OSRTEST 1006
|
||||||
#define IDS_PERFORMANCE 1007
|
#define IDS_OTHER_TESTS 1007
|
||||||
#define IDS_TRANSPARENCY 1008
|
#define IDS_PERFORMANCE 1008
|
||||||
#define IDS_WINDOW 1009
|
#define IDS_TRANSPARENCY 1009
|
||||||
#define IDS_XMLHTTPREQUEST 1010
|
#define IDS_WINDOW 1010
|
||||||
|
#define IDS_XMLHTTPREQUEST 1011
|
||||||
|
|
||||||
// Avoid files associated with MacOS
|
// Avoid files associated with MacOS
|
||||||
#define _X86_
|
#define _X86_
|
||||||
|
@ -29,7 +29,7 @@ bool AmIBundled() {
|
|||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (info.nodeFlags & kFSNodeIsDirectoryMask);
|
return (info.nodeFlags & kFSNodeIsDirectoryMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ bool GetResourceDir(std::string& dir) {
|
|||||||
// Retrieve the executable directory.
|
// Retrieve the executable directory.
|
||||||
uint32_t pathSize = 0;
|
uint32_t pathSize = 0;
|
||||||
_NSGetExecutablePath(NULL, &pathSize);
|
_NSGetExecutablePath(NULL, &pathSize);
|
||||||
if (pathSize > 0) {
|
if (pathSize > 0) {
|
||||||
dir.resize(pathSize);
|
dir.resize(pathSize);
|
||||||
_NSGetExecutablePath(const_cast<char*>(dir.c_str()), &pathSize);
|
_NSGetExecutablePath(const_cast<char*>(dir.c_str()), &pathSize);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ int GetResourceId(const char* resource_name) {
|
|||||||
{"domaccess.html", IDS_DOMACCESS},
|
{"domaccess.html", IDS_DOMACCESS},
|
||||||
{"localstorage.html", IDS_LOCALSTORAGE},
|
{"localstorage.html", IDS_LOCALSTORAGE},
|
||||||
{"logo.png", IDS_LOGO},
|
{"logo.png", IDS_LOGO},
|
||||||
|
{"osr_test.html", IDS_OSRTEST},
|
||||||
{"other_tests.html", IDS_OTHER_TESTS},
|
{"other_tests.html", IDS_OTHER_TESTS},
|
||||||
{"performance.html", IDS_PERFORMANCE},
|
{"performance.html", IDS_PERFORMANCE},
|
||||||
{"transparency.html", IDS_TRANSPARENCY},
|
{"transparency.html", IDS_TRANSPARENCY},
|
||||||
|
@ -3,63 +3,31 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/cef_runnable.h"
|
#include "include/cef_runnable.h"
|
||||||
|
#include "include/cef_v8.h"
|
||||||
|
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||||
|
|
||||||
|
#include "tests/cefclient/client_app.h"
|
||||||
|
#include "tests/cefclient/resource_util.h"
|
||||||
#include "tests/unittests/test_handler.h"
|
#include "tests/unittests/test_handler.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "ui/base/keycodes/keyboard_codes.h"
|
||||||
|
#include "ui/base/keycodes/keyboard_code_conversion.h"
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
#include "tests/unittests/os_rendering_unittest_mac.h"
|
||||||
|
#elif defined(OS_WIN)
|
||||||
|
// Required for resource_util_win, which uses this as an extern
|
||||||
|
HINSTANCE hInst = ::GetModuleHandle(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char kTestUrl[] = "http://tests/OSRTest";
|
const char kTestUrl[] = "http://tests/osrtest";
|
||||||
|
|
||||||
// this html should render on a 600 x 400 window with a little vertical
|
// this html should render on a 600 x 400 window with a little vertical
|
||||||
// offset with scrollbar.
|
// offset with scrollbar.
|
||||||
|
|
||||||
const char kOsrHtml[] =
|
|
||||||
"<html> "
|
|
||||||
" <head><title>OSR Test</title></head> "
|
|
||||||
" <style> "
|
|
||||||
" .red_hover:hover {color:red;} "
|
|
||||||
" body {background:rgba(255, 0, 0, 0.5);} "
|
|
||||||
" #LI11select {width: 75px;} "
|
|
||||||
" </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));} "
|
|
||||||
" </script> "
|
|
||||||
" <body onfocus='makeH1Red()' onblur='makeH1Black()' onload='load();'> "
|
|
||||||
" <h1 id='LI00'>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' class='red_hover'><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=''></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> "
|
|
||||||
" <br /> "
|
|
||||||
" <br /> "
|
|
||||||
" <br /> "
|
|
||||||
" <br /> "
|
|
||||||
" </body> "
|
|
||||||
"</html> ";
|
|
||||||
|
|
||||||
// #define DEBUGGER_ATTACHED
|
// #define DEBUGGER_ATTACHED
|
||||||
|
|
||||||
// default osr widget size
|
// default osr widget size
|
||||||
@ -67,6 +35,7 @@ const int kOsrWidth = 600;
|
|||||||
const int kOsrHeight = 400;
|
const int kOsrHeight = 400;
|
||||||
|
|
||||||
// precomputed bounding client rects for html elements (h1 and li).
|
// precomputed bounding client rects for html elements (h1 and li).
|
||||||
|
#if defined(OS_WIN)
|
||||||
const CefRect kExpectedRectLI[] = {
|
const CefRect kExpectedRectLI[] = {
|
||||||
CefRect(8, 8, 567, 74), // LI00
|
CefRect(8, 8, 567, 74), // LI00
|
||||||
CefRect(27, 103, 548, 20), // LI01
|
CefRect(27, 103, 548, 20), // LI01
|
||||||
@ -80,17 +49,44 @@ const CefRect kExpectedRectLI[] = {
|
|||||||
CefRect(27, 269, 548, 26), // LI09
|
CefRect(27, 269, 548, 26), // LI09
|
||||||
CefRect(27, 295, 548, 20), // LI10
|
CefRect(27, 295, 548, 20), // LI10
|
||||||
};
|
};
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
const CefRect kExpectedRectLI[] = {
|
||||||
|
CefRect(8, 8, 584, 74), // LI00
|
||||||
|
CefRect(28, 103, 564, 18), // LI01
|
||||||
|
CefRect(28, 121, 564, 18), // LI02
|
||||||
|
CefRect(28, 139, 564, 18), // LI03
|
||||||
|
CefRect(28, 157, 564, 18), // LI04
|
||||||
|
CefRect(28, 175, 564, 18), // LI05
|
||||||
|
CefRect(28, 193, 564, 18), // LI06
|
||||||
|
CefRect(28, 211, 564, 18), // LI07
|
||||||
|
CefRect(28, 229, 564, 23), // LI08
|
||||||
|
CefRect(28, 252, 564, 26), // LI09
|
||||||
|
CefRect(20, 278, 572, 18), // LI10
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
// bounding client rects for edit box and navigate button
|
// bounding client rects for edit box and navigate button
|
||||||
|
#if defined(OS_WIN)
|
||||||
const CefRect kEditBoxRect(412, 245, 153, 22);
|
const CefRect kEditBoxRect(412, 245, 153, 22);
|
||||||
const CefRect kNavigateButtonRect(360, 271, 140, 22);
|
const CefRect kNavigateButtonRect(360, 271, 140, 22);
|
||||||
const CefRect kSelectRect(467, 22, 75, 20);
|
const CefRect kSelectRect(467, 22, 75, 20);
|
||||||
const CefRect kExpandedSelectRect(467, 42, 81, 322);
|
const CefRect kExpandedSelectRect(467, 42, 81, 322);
|
||||||
const int kVerticalScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
|
const int kVerticalScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
|
||||||
const int kHorizontalScrollbarWidth = GetSystemMetrics(SM_CXHSCROLL);
|
const int kHorizontalScrollbarWidth = GetSystemMetrics(SM_CXHSCROLL);
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
const CefRect kEditBoxRect(429, 228, 129, 25);
|
||||||
|
const CefRect kNavigateButtonRect(375, 251, 138, 28);
|
||||||
|
const CefRect kSelectRect(461, 21, 87, 26);
|
||||||
|
const CefRect kExpandedSelectRect(467, 42, 80, 262);
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
// adjusted expected rect regarding system vertical scrollbar width
|
// adjusted expected rect regarding system vertical scrollbar width
|
||||||
CefRect ExpectedRect(int index) {
|
CefRect ExpectedRect(int index) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
// this is the scrollbar width for all the kExpectedRectLI
|
// this is the scrollbar width for all the kExpectedRectLI
|
||||||
const int kDefaultVerticalScrollbarWidth = 17;
|
const int kDefaultVerticalScrollbarWidth = 17;
|
||||||
if (kDefaultVerticalScrollbarWidth == kVerticalScrollbarWidth)
|
if (kDefaultVerticalScrollbarWidth == kVerticalScrollbarWidth)
|
||||||
@ -100,11 +96,23 @@ CefRect ExpectedRect(int index) {
|
|||||||
adjustedRect.width += kDefaultVerticalScrollbarWidth -
|
adjustedRect.width += kDefaultVerticalScrollbarWidth -
|
||||||
kVerticalScrollbarWidth;
|
kVerticalScrollbarWidth;
|
||||||
return adjustedRect;
|
return adjustedRect;
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
return kExpectedRectLI[index];
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// word to be written into edit box
|
// word to be written into edit box
|
||||||
const char kKeyTestWord[] = "done";
|
const char kKeyTestWord[] = "done";
|
||||||
|
|
||||||
|
const ui::KeyboardCode kKeyTestCodes[] = {
|
||||||
|
ui::VKEY_D,
|
||||||
|
ui::VKEY_O,
|
||||||
|
ui::VKEY_N,
|
||||||
|
ui::VKEY_E
|
||||||
|
};
|
||||||
|
|
||||||
// width for the icon that appear on the screen when pressing
|
// width for the icon that appear on the screen when pressing
|
||||||
// middle mouse button
|
// middle mouse button
|
||||||
const int kMiddleButtonIconWidth = 16;
|
const int kMiddleButtonIconWidth = 16;
|
||||||
@ -141,6 +149,9 @@ enum OSRTestType {
|
|||||||
OSR_TEST_TOOLTIP,
|
OSR_TEST_TOOLTIP,
|
||||||
// mouse wheel will trigger a scroll event
|
// mouse wheel will trigger a scroll event
|
||||||
OSR_TEST_SCROLLING,
|
OSR_TEST_SCROLLING,
|
||||||
|
// Right click will trigger a context menu, and on destroying the test, it
|
||||||
|
// should not crash
|
||||||
|
OSR_TEST_CONTEXT_MENU,
|
||||||
// clicking on dropdown box, PET_POPUP OnPaint is triggered
|
// clicking on dropdown box, PET_POPUP OnPaint is triggered
|
||||||
OSR_TEST_POPUP_PAINT,
|
OSR_TEST_POPUP_PAINT,
|
||||||
// clicking on dropdown box, a popup will show up
|
// clicking on dropdown box, a popup will show up
|
||||||
@ -174,7 +185,6 @@ class OSRTestHandler : public TestHandler,
|
|||||||
|
|
||||||
// TestHandler methods
|
// TestHandler methods
|
||||||
virtual void RunTest() OVERRIDE {
|
virtual void RunTest() OVERRIDE {
|
||||||
AddResource(kTestUrl, kOsrHtml, "text/html");
|
|
||||||
CreateOSRBrowser(kTestUrl);
|
CreateOSRBrowser(kTestUrl);
|
||||||
#if !defined(DEBUGGER_ATTACHED)
|
#if !defined(DEBUGGER_ATTACHED)
|
||||||
// Each test has a 5 second timeout. After this timeout it will be destroyed
|
// Each test has a 5 second timeout. After this timeout it will be destroyed
|
||||||
@ -196,13 +206,61 @@ class OSRTestHandler : public TestHandler,
|
|||||||
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
int httpStatusCode) OVERRIDE {
|
int httpStatusCode) OVERRIDE {
|
||||||
if (test_type_ == OSR_TEST_KEY_EVENTS && started()) {
|
if (!started())
|
||||||
std::string expectedUrl = std::string(kTestUrl) + "?k=" + kKeyTestWord;
|
return;
|
||||||
EXPECT_EQ(frame->GetURL(), expectedUrl);
|
|
||||||
DestroySucceededTestSoon();
|
switch(test_type_) {
|
||||||
|
case OSR_TEST_KEY_EVENTS:
|
||||||
|
EXPECT_EQ(frame->GetURL(), std::string(kTestUrl) + "?k=" + kKeyTestWord);
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Intentionally left blank
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool OnProcessMessageReceived(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) OVERRIDE {
|
||||||
|
EXPECT_TRUE(browser.get());
|
||||||
|
EXPECT_EQ(PID_RENDERER, source_process);
|
||||||
|
EXPECT_TRUE(message.get());
|
||||||
|
EXPECT_TRUE(message->IsReadOnly());
|
||||||
|
|
||||||
|
if (!started())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const CefString kMessageName = "osrtest";
|
||||||
|
EXPECT_EQ(kMessageName, message->GetName());
|
||||||
|
|
||||||
|
CefString stringParam = message->GetArgumentList()->GetString(0);
|
||||||
|
switch(test_type_) {
|
||||||
|
case OSR_TEST_FOCUS:
|
||||||
|
EXPECT_EQ(stringParam, std::string("focus"));
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
break;
|
||||||
|
case OSR_TEST_CLICK_LEFT:
|
||||||
|
EXPECT_EQ(stringParam, std::string("click0"));
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
break;
|
||||||
|
case OSR_TEST_CLICK_MIDDLE:
|
||||||
|
EXPECT_EQ(stringParam, std::string("click1"));
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
break;
|
||||||
|
case OSR_TEST_MOUSE_MOVE:
|
||||||
|
EXPECT_EQ(stringParam, std::string("mousemove"));
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Intentionally left blank
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// CefClient methods, providing handlers
|
// CefClient methods, providing handlers
|
||||||
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
|
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
|
||||||
return this;
|
return this;
|
||||||
@ -212,6 +270,26 @@ class OSRTestHandler : public TestHandler,
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefRequest> request) OVERRIDE {
|
||||||
|
std::string url = request->GetURL();
|
||||||
|
|
||||||
|
if (url.find("http://tests/osrtest") == 0) {
|
||||||
|
// Show the osr test contents
|
||||||
|
CefRefPtr<CefStreamReader> stream =
|
||||||
|
GetBinaryResourceReader("osr_test.html");
|
||||||
|
return new CefStreamResourceHandler("text/html", stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// CefRenderHandler methods
|
// CefRenderHandler methods
|
||||||
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||||
CefRect& rect) OVERRIDE {
|
CefRect& rect) OVERRIDE {
|
||||||
@ -232,11 +310,29 @@ class OSRTestHandler : public TestHandler,
|
|||||||
EXPECT_EQ(viewX, MiddleX(ExpectedRect(4)));
|
EXPECT_EQ(viewX, MiddleX(ExpectedRect(4)));
|
||||||
EXPECT_EQ(viewY, MiddleY(ExpectedRect(4)));
|
EXPECT_EQ(viewY, MiddleY(ExpectedRect(4)));
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
|
} else if (test_type_ == OSR_TEST_CONTEXT_MENU && started()){
|
||||||
|
screenX = 0;
|
||||||
|
screenY = 0;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// we don't want to see a contextual menu. stop here.
|
// we don't want to see a contextual menu. stop here.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefScreenInfo& screen_info) {
|
||||||
|
screen_info.device_scale_factor = 1;
|
||||||
|
|
||||||
|
// The screen info rectangles are used by the renderer to create and
|
||||||
|
// position popups. If not overwritten in this function, the rectangle from
|
||||||
|
// returned GetViewRect will be used to popuplate them.
|
||||||
|
// The popup in the test fits without modifications in the test window, so
|
||||||
|
// setting the screen to the test window size does not affect its rectangle.
|
||||||
|
screen_info.rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
|
||||||
|
screen_info.available_rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||||
bool show) OVERRIDE {
|
bool show) OVERRIDE {
|
||||||
if (show && started()) {
|
if (show && started()) {
|
||||||
@ -247,6 +343,8 @@ class OSRTestHandler : public TestHandler,
|
|||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!show && started()) {
|
if (!show && started()) {
|
||||||
@ -257,6 +355,8 @@ class OSRTestHandler : public TestHandler,
|
|||||||
case OSR_TEST_POPUP_HIDE_ON_SCROLL:
|
case OSR_TEST_POPUP_HIDE_ON_SCROLL:
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,6 +369,8 @@ class OSRTestHandler : public TestHandler,
|
|||||||
EXPECT_EQ(kExpandedSelectRect, rect);
|
EXPECT_EQ(kExpandedSelectRect, rect);
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,26 +403,22 @@ class OSRTestHandler : public TestHandler,
|
|||||||
switch (test_type_) {
|
switch (test_type_) {
|
||||||
case OSR_TEST_PAINT:
|
case OSR_TEST_PAINT:
|
||||||
// test that we have a full repaint
|
// test that we have a full repaint
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0xffff8080);
|
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0xffff8080);
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_TRANSPARENCY:
|
case OSR_TEST_TRANSPARENCY:
|
||||||
// test that we have a full repaint
|
// test that we have a full repaint
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
|
||||||
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0x7f7f0000);
|
EXPECT_EQ(*(reinterpret_cast<const uint32*>(buffer)), 0x7f7f0000U);
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_FOCUS:
|
case OSR_TEST_FOCUS:
|
||||||
if (StartTest()) {
|
if (StartTest()) {
|
||||||
// body.onfocus will make LI00 red
|
// body.onfocus will make LI00 red
|
||||||
browser->GetHost()->SendFocusEvent(true);
|
browser->GetHost()->SendFocusEvent(true);
|
||||||
} else {
|
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
|
||||||
EXPECT_EQ(dirtyRects[0], ExpectedRect(0));
|
|
||||||
DestroySucceededTestSoon();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_CURSOR:
|
case OSR_TEST_CURSOR:
|
||||||
@ -344,14 +442,11 @@ class OSRTestHandler : public TestHandler,
|
|||||||
mouse_event.y = MiddleY(ExpectedRect(3));
|
mouse_event.y = MiddleY(ExpectedRect(3));
|
||||||
mouse_event.modifiers = 0;
|
mouse_event.modifiers = 0;
|
||||||
browser->GetHost()->SendMouseMoveEvent(mouse_event, false);
|
browser->GetHost()->SendMouseMoveEvent(mouse_event, false);
|
||||||
} else {
|
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
|
||||||
EXPECT_EQ(dirtyRects[0], ExpectedRect(3));
|
|
||||||
DestroySucceededTestSoon();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_CLICK_RIGHT:
|
case OSR_TEST_CLICK_RIGHT:
|
||||||
case OSR_TEST_SCREEN_POINT:
|
case OSR_TEST_SCREEN_POINT:
|
||||||
|
case OSR_TEST_CONTEXT_MENU:
|
||||||
if (StartTest()) {
|
if (StartTest()) {
|
||||||
CefMouseEvent mouse_event;
|
CefMouseEvent mouse_event;
|
||||||
mouse_event.x = MiddleX(ExpectedRect(4));
|
mouse_event.x = MiddleX(ExpectedRect(4));
|
||||||
@ -366,17 +461,14 @@ class OSRTestHandler : public TestHandler,
|
|||||||
case OSR_TEST_CLICK_LEFT:
|
case OSR_TEST_CLICK_LEFT:
|
||||||
if (StartTest()) {
|
if (StartTest()) {
|
||||||
CefMouseEvent mouse_event;
|
CefMouseEvent mouse_event;
|
||||||
mouse_event.x = MiddleX(kEditBoxRect);
|
mouse_event.x = MiddleX(ExpectedRect(0));
|
||||||
mouse_event.y = MiddleY(kEditBoxRect);
|
mouse_event.y = MiddleY(ExpectedRect(0));
|
||||||
|
|
||||||
mouse_event.modifiers = 0;
|
mouse_event.modifiers = 0;
|
||||||
browser->GetHost()->SendMouseClickEvent(
|
browser->GetHost()->SendMouseClickEvent(
|
||||||
mouse_event, MBT_LEFT, false, 1);
|
mouse_event, MBT_LEFT, false, 1);
|
||||||
browser->GetHost()->SendMouseClickEvent(
|
browser->GetHost()->SendMouseClickEvent(
|
||||||
mouse_event, MBT_LEFT, true, 1);
|
mouse_event, MBT_LEFT, true, 1);
|
||||||
} else {
|
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
|
||||||
EXPECT_EQ(dirtyRects[0], kEditBoxRect);
|
|
||||||
DestroySucceededTestSoon();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_CLICK_MIDDLE:
|
case OSR_TEST_CLICK_MIDDLE:
|
||||||
@ -390,7 +482,7 @@ class OSRTestHandler : public TestHandler,
|
|||||||
browser->GetHost()->SendMouseClickEvent(
|
browser->GetHost()->SendMouseClickEvent(
|
||||||
mouse_event, MBT_MIDDLE, true, 1);
|
mouse_event, MBT_MIDDLE, true, 1);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
CefRect expectedRect(
|
CefRect expectedRect(
|
||||||
MiddleX(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
|
MiddleX(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
|
||||||
MiddleY(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
|
MiddleY(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
|
||||||
@ -405,7 +497,7 @@ class OSRTestHandler : public TestHandler,
|
|||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(kOsrWidth * 2, width);
|
EXPECT_EQ(kOsrWidth * 2, width);
|
||||||
EXPECT_EQ(kOsrHeight * 2, height);
|
EXPECT_EQ(kOsrHeight * 2, height);
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_TRUE(IsFullRepaint(dirtyRects[0], width, height));
|
EXPECT_TRUE(IsFullRepaint(dirtyRects[0], width, height));
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
}
|
}
|
||||||
@ -419,7 +511,7 @@ class OSRTestHandler : public TestHandler,
|
|||||||
invalidating = false;
|
invalidating = false;
|
||||||
} else {
|
} else {
|
||||||
EXPECT_TRUE(invalidating);
|
EXPECT_TRUE(invalidating);
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_EQ(dirtyRects[0], invalidate_rect);
|
EXPECT_EQ(dirtyRects[0], invalidate_rect);
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
}
|
}
|
||||||
@ -442,21 +534,35 @@ class OSRTestHandler : public TestHandler,
|
|||||||
event.is_system_key = false;
|
event.is_system_key = false;
|
||||||
event.modifiers = 0;
|
event.modifiers = 0;
|
||||||
|
|
||||||
size_t word_lenght = strlen(kKeyTestWord);
|
size_t word_length = strlen(kKeyTestWord);
|
||||||
for (size_t i = 0; i < word_lenght; ++i) {
|
for (size_t i = 0; i < word_length; ++i) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
BYTE VkCode = LOBYTE(VkKeyScanA(kKeyTestWord[i]));
|
BYTE VkCode = LOBYTE(VkKeyScanA(kKeyTestWord[i]));
|
||||||
UINT scanCode = MapVirtualKey(VkCode, MAPVK_VK_TO_VSC);
|
UINT scanCode = MapVirtualKey(VkCode, MAPVK_VK_TO_VSC);
|
||||||
event.native_key_code = (scanCode << 16) | // key scan code
|
event.native_key_code = (scanCode << 16) | // key scan code
|
||||||
1; // key repeat count
|
1; // key repeat count
|
||||||
event.windows_key_code = VkCode;
|
event.windows_key_code = VkCode;
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
|
||||||
|
#else
|
||||||
|
NOTREACHED();
|
||||||
|
#endif
|
||||||
event.type = KEYEVENT_RAWKEYDOWN;
|
event.type = KEYEVENT_RAWKEYDOWN;
|
||||||
browser->GetHost()->SendKeyEvent(event);
|
browser->GetHost()->SendKeyEvent(event);
|
||||||
|
#if defined(OS_WIN)
|
||||||
event.windows_key_code = kKeyTestWord[i];
|
event.windows_key_code = kKeyTestWord[i];
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
|
||||||
|
#endif
|
||||||
event.type = KEYEVENT_CHAR;
|
event.type = KEYEVENT_CHAR;
|
||||||
browser->GetHost()->SendKeyEvent(event);
|
browser->GetHost()->SendKeyEvent(event);
|
||||||
|
#if defined(OS_WIN)
|
||||||
event.windows_key_code = VkCode;
|
event.windows_key_code = VkCode;
|
||||||
// bits 30 and 31 should be always 1 for WM_KEYUP
|
// bits 30 and 31 should be always 1 for WM_KEYUP
|
||||||
event.native_key_code |= 0xC0000000;
|
event.native_key_code |= 0xC0000000;
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
|
||||||
|
#endif
|
||||||
event.type = KEYEVENT_KEYUP;
|
event.type = KEYEVENT_KEYUP;
|
||||||
browser->GetHost()->SendKeyEvent(event);
|
browser->GetHost()->SendKeyEvent(event);
|
||||||
}
|
}
|
||||||
@ -488,20 +594,38 @@ class OSRTestHandler : public TestHandler,
|
|||||||
mouse_event.modifiers = 0;
|
mouse_event.modifiers = 0;
|
||||||
browser->GetHost()->SendMouseWheelEvent(mouse_event, 0, - deltaY);
|
browser->GetHost()->SendMouseWheelEvent(mouse_event, 0, - deltaY);
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(OS_WIN)
|
||||||
// there should be 3 update areas:
|
// there should be 3 update areas:
|
||||||
// 1) vertical scrollbar
|
// 1) vertical scrollbar
|
||||||
// 2) discovered new area (bottom side)
|
// 2) discovered new area (bottom side)
|
||||||
// 3) the whole visible rect.
|
// 3) the whole visible rect.
|
||||||
EXPECT_EQ(dirtyRects.size(), 3);
|
EXPECT_EQ(dirtyRects.size(), 3U);
|
||||||
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
|
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
|
||||||
kOsrWidth - kVerticalScrollbarWidth, kHorizontalScrollbarWidth));
|
kOsrWidth - kVerticalScrollbarWidth, kHorizontalScrollbarWidth));
|
||||||
|
|
||||||
EXPECT_EQ(dirtyRects[1], CefRect(0, kHorizontalScrollbarWidth,
|
EXPECT_EQ(dirtyRects[1], CefRect(0, kHorizontalScrollbarWidth,
|
||||||
kOsrWidth, kOsrHeight - 2 * kHorizontalScrollbarWidth));
|
kOsrWidth, kOsrHeight - 2 * kHorizontalScrollbarWidth));
|
||||||
|
|
||||||
EXPECT_EQ(dirtyRects[2],
|
EXPECT_EQ(dirtyRects[2],
|
||||||
CefRect(0, kOsrHeight - kHorizontalScrollbarWidth,
|
CefRect(0, kOsrHeight - kHorizontalScrollbarWidth,
|
||||||
kOsrWidth - kVerticalScrollbarWidth,
|
kOsrWidth - kVerticalScrollbarWidth,
|
||||||
kHorizontalScrollbarWidth));
|
kHorizontalScrollbarWidth));
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
// On Mac, when scrollbars are Always on, there is a single update of
|
||||||
|
// the whole view
|
||||||
|
// When scrollbars are set to appear 'When scrolling', the first
|
||||||
|
// rectangle is of the whole view, and next comes a longer sequence of
|
||||||
|
// updates, each with one rectangle update for the whole scrollbar
|
||||||
|
// rectangle(584,0,16,400)
|
||||||
|
// Validating the first, full update passes in both cases
|
||||||
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
|
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
|
||||||
|
kOsrWidth, kOsrHeight));
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -544,11 +668,17 @@ class OSRTestHandler : public TestHandler,
|
|||||||
} else if (type == PET_POPUP) {
|
} else if (type == PET_POPUP) {
|
||||||
CefKeyEvent event;
|
CefKeyEvent event;
|
||||||
event.is_system_key = false;
|
event.is_system_key = false;
|
||||||
|
#if defined(OS_WIN)
|
||||||
BYTE VkCode = LOBYTE(VK_ESCAPE);
|
BYTE VkCode = LOBYTE(VK_ESCAPE);
|
||||||
UINT scanCode = MapVirtualKey(VkCode, MAPVK_VK_TO_VSC);
|
UINT scanCode = MapVirtualKey(VkCode, MAPVK_VK_TO_VSC);
|
||||||
event.native_key_code = (scanCode << 16) | // key scan code
|
event.native_key_code = (scanCode << 16) | // key scan code
|
||||||
1; // key repeat count
|
1; // key repeat count
|
||||||
event.windows_key_code = VkCode;
|
event.windows_key_code = VkCode;
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
osr_unittests::GetKeyEvent(event, ui::VKEY_ESCAPE, 0);
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
event.type = KEYEVENT_CHAR;
|
event.type = KEYEVENT_CHAR;
|
||||||
browser->GetHost()->SendKeyEvent(event);
|
browser->GetHost()->SendKeyEvent(event);
|
||||||
}
|
}
|
||||||
@ -563,7 +693,7 @@ class OSRTestHandler : public TestHandler,
|
|||||||
if (StartTest()) {
|
if (StartTest()) {
|
||||||
ExpandDropDown();
|
ExpandDropDown();
|
||||||
} else if (type == PET_POPUP) {
|
} else if (type == PET_POPUP) {
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_EQ(dirtyRects[0],
|
EXPECT_EQ(dirtyRects[0],
|
||||||
CefRect(0, 0,
|
CefRect(0, 0,
|
||||||
kExpandedSelectRect.width,
|
kExpandedSelectRect.width,
|
||||||
@ -576,28 +706,46 @@ class OSRTestHandler : public TestHandler,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSR_TEST_POPUP_SCROLL_INSIDE:
|
case OSR_TEST_POPUP_SCROLL_INSIDE:
|
||||||
static enum {NotStarted, Started, Scrolled}
|
{
|
||||||
scroll_inside_state = NotStarted;
|
static enum {NotStarted, Started, Scrolled}
|
||||||
if (StartTest()) {
|
scroll_inside_state = NotStarted;
|
||||||
ExpandDropDown();
|
if (StartTest()) {
|
||||||
scroll_inside_state = Started;
|
ExpandDropDown();
|
||||||
} else if (type == PET_POPUP) {
|
scroll_inside_state = Started;
|
||||||
if (scroll_inside_state == Started) {
|
} else if (type == PET_POPUP) {
|
||||||
CefMouseEvent mouse_event;
|
if (scroll_inside_state == Started) {
|
||||||
mouse_event.x = MiddleX(kExpandedSelectRect);
|
CefMouseEvent mouse_event;
|
||||||
mouse_event.y = MiddleY(kExpandedSelectRect);
|
mouse_event.x = MiddleX(kExpandedSelectRect);
|
||||||
mouse_event.modifiers = 0;
|
mouse_event.y = MiddleY(kExpandedSelectRect);
|
||||||
browser->GetHost()->SendMouseWheelEvent(mouse_event, 0, -10);
|
mouse_event.modifiers = 0;
|
||||||
scroll_inside_state = Scrolled;
|
browser->GetHost()->SendMouseWheelEvent(mouse_event, 0, -10);
|
||||||
} else if (scroll_inside_state == Scrolled) {
|
scroll_inside_state = Scrolled;
|
||||||
EXPECT_EQ(dirtyRects.size(), 1);
|
} else if (scroll_inside_state == Scrolled) {
|
||||||
// border is not redrawn
|
EXPECT_EQ(dirtyRects.size(), 1U);
|
||||||
EXPECT_EQ(dirtyRects[0], CefRect(1, 1,
|
#if defined(OS_WIN)
|
||||||
kExpandedSelectRect.width - 3,
|
// border is not redrawn
|
||||||
kExpandedSelectRect.height - 2));
|
EXPECT_EQ(dirtyRects[0],
|
||||||
DestroySucceededTestSoon();
|
CefRect(1,
|
||||||
|
1,
|
||||||
|
kExpandedSelectRect.width - 3,
|
||||||
|
kExpandedSelectRect.height - 2));
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
EXPECT_EQ(dirtyRects[0],
|
||||||
|
CefRect(1,
|
||||||
|
0,
|
||||||
|
kExpandedSelectRect.width - 3,
|
||||||
|
kExpandedSelectRect.height - 1));
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
|
DestroySucceededTestSoon();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,10 +769,15 @@ class OSRTestHandler : public TestHandler,
|
|||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefContextMenuParams> params,
|
CefRefPtr<CefContextMenuParams> params,
|
||||||
CefRefPtr<CefMenuModel> model) OVERRIDE {
|
CefRefPtr<CefMenuModel> model) OVERRIDE {
|
||||||
if (test_type_ == OSR_TEST_CLICK_RIGHT && started()) {
|
if (!started())
|
||||||
|
return;
|
||||||
|
if (test_type_ == OSR_TEST_CLICK_RIGHT) {
|
||||||
EXPECT_EQ(params->GetXCoord(), MiddleX(ExpectedRect(4)));
|
EXPECT_EQ(params->GetXCoord(), MiddleX(ExpectedRect(4)));
|
||||||
EXPECT_EQ(params->GetYCoord(), MiddleY(ExpectedRect(4)));
|
EXPECT_EQ(params->GetYCoord(), MiddleY(ExpectedRect(4)));
|
||||||
DestroySucceededTestSoon();
|
DestroySucceededTestSoon();
|
||||||
|
} else if (test_type_ == OSR_TEST_CONTEXT_MENU) {
|
||||||
|
// This test will pass if it does not crash on destruction
|
||||||
|
DestroySucceededTestSoon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +785,18 @@ class OSRTestHandler : public TestHandler,
|
|||||||
void CreateOSRBrowser(const CefString& url) {
|
void CreateOSRBrowser(const CefString& url) {
|
||||||
CefWindowInfo windowInfo;
|
CefWindowInfo windowInfo;
|
||||||
CefBrowserSettings settings;
|
CefBrowserSettings settings;
|
||||||
|
#if defined(OS_WIN)
|
||||||
windowInfo.SetAsOffScreen(GetDesktopWindow());
|
windowInfo.SetAsOffScreen(GetDesktopWindow());
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
// An actual vies is needed only for the ContextMenu test. The menu runner
|
||||||
|
// checks if the view is not nil before showing the context menu.
|
||||||
|
if (test_type_ == OSR_TEST_CONTEXT_MENU)
|
||||||
|
windowInfo.SetAsOffScreen(osr_unittests::GetFakeView());
|
||||||
|
else
|
||||||
|
windowInfo.SetAsOffScreen(NULL);
|
||||||
|
#else
|
||||||
|
#error "Unsupported platform"
|
||||||
|
#endif
|
||||||
if (test_type_ == OSR_TEST_TRANSPARENCY)
|
if (test_type_ == OSR_TEST_TRANSPARENCY)
|
||||||
windowInfo.SetTransparentPainting(TRUE);
|
windowInfo.SetTransparentPainting(TRUE);
|
||||||
CefBrowserHost::CreateBrowser(windowInfo, this, url, settings);
|
CefBrowserHost::CreateBrowser(windowInfo, this, url, settings);
|
||||||
@ -727,6 +891,7 @@ OSR_TEST(Invalidate, OSR_TEST_INVALIDATE);
|
|||||||
OSR_TEST(KeyEvents, OSR_TEST_KEY_EVENTS);
|
OSR_TEST(KeyEvents, OSR_TEST_KEY_EVENTS);
|
||||||
OSR_TEST(Tooltip, OSR_TEST_TOOLTIP);
|
OSR_TEST(Tooltip, OSR_TEST_TOOLTIP);
|
||||||
OSR_TEST(Scrolling, OSR_TEST_SCROLLING);
|
OSR_TEST(Scrolling, OSR_TEST_SCROLLING);
|
||||||
|
OSR_TEST(ContextMenu, OSR_TEST_CONTEXT_MENU);
|
||||||
OSR_TEST(PopupPaint, OSR_TEST_POPUP_PAINT);
|
OSR_TEST(PopupPaint, OSR_TEST_POPUP_PAINT);
|
||||||
OSR_TEST(PopupShow, OSR_TEST_POPUP_SHOW);
|
OSR_TEST(PopupShow, OSR_TEST_POPUP_SHOW);
|
||||||
OSR_TEST(PopupSize, OSR_TEST_POPUP_SIZE);
|
OSR_TEST(PopupSize, OSR_TEST_POPUP_SIZE);
|
||||||
|
18
tests/unittests/os_rendering_unittest_mac.h
Normal file
18
tests/unittests/os_rendering_unittest_mac.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// 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_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_
|
||||||
|
#define CEF_TESTS_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_
|
||||||
|
|
||||||
|
#include "include/cef_base.h"
|
||||||
|
#include "ui/base/keycodes/keyboard_codes.h"
|
||||||
|
|
||||||
|
namespace osr_unittests {
|
||||||
|
|
||||||
|
CefWindowHandle GetFakeView();
|
||||||
|
void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers);
|
||||||
|
|
||||||
|
} // namespace osr_unittests
|
||||||
|
|
||||||
|
#endif
|
39
tests/unittests/os_rendering_unittest_mac.mm
Normal file
39
tests/unittests/os_rendering_unittest_mac.mm
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "os_rendering_unittest_mac.h"
|
||||||
|
|
||||||
|
#include "ui/base/keycodes/keyboard_code_conversion_mac.h"
|
||||||
|
|
||||||
|
#include "include/cef_base.h"
|
||||||
|
|
||||||
|
namespace osr_unittests {
|
||||||
|
|
||||||
|
CefWindowHandle GetFakeView() {
|
||||||
|
NSScreen *mainScreen = [NSScreen mainScreen];
|
||||||
|
NSRect screenRect = [mainScreen visibleFrame];
|
||||||
|
NSView* fakeView = [[NSView alloc] initWithFrame: screenRect];
|
||||||
|
return fakeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers) {
|
||||||
|
unichar character;
|
||||||
|
unichar unmodified_character;
|
||||||
|
|
||||||
|
// TODO(port): translate modifiers from the input format to NSFlags
|
||||||
|
// MacKeyCodeForWindowsKeyCode takes a NSUinteger as flags.
|
||||||
|
int macKeyCode = ui::MacKeyCodeForWindowsKeyCode(keyCode,
|
||||||
|
modifiers,
|
||||||
|
&character,
|
||||||
|
&unmodified_character);
|
||||||
|
|
||||||
|
event.native_key_code = macKeyCode;
|
||||||
|
event.character = character;
|
||||||
|
event.unmodified_character = unmodified_character;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace osr_unittests
|
@ -170,6 +170,7 @@
|
|||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
|
||||||
|
'$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
|
||||||
'$(CONFIGURATION)/libcef.dylib',
|
'$(CONFIGURATION)/libcef.dylib',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user