diff --git a/include/capi/cef_render_handler_capi.h b/include/capi/cef_render_handler_capi.h index 151292c8e..6245f9dbd 100644 --- a/include/capi/cef_render_handler_capi.h +++ b/include/capi/cef_render_handler_capi.h @@ -109,8 +109,8 @@ typedef struct _cef_render_handler_t { // Called when an element should be painted. |type| indicates whether the // element is the view or the popup widget. |buffer| contains the pixel data // for the whole image. |dirtyRects| contains the set of rectangles that need - // to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes in - // size and represents a BGRA image with an upper-left origin. + // to be repainted. |buffer| will be |width|*|height|*4 bytes in size and + // represents a BGRA image with an upper-left origin. /// void (CEF_CALLBACK *on_paint)(struct _cef_render_handler_t* self, struct _cef_browser_t* browser, cef_paint_element_type_t type, @@ -118,10 +118,13 @@ typedef struct _cef_render_handler_t { int width, int height); /// - // Called when the browser window's cursor has changed. + // Called when the browser's cursor has changed. If |type| is CT_CUSTOM then + // |custom_cursor_info| will be populated with the custom cursor information. /// void (CEF_CALLBACK *on_cursor_change)(struct _cef_render_handler_t* self, - struct _cef_browser_t* browser, cef_cursor_handle_t cursor); + struct _cef_browser_t* browser, cef_cursor_handle_t cursor, + cef_cursor_type_t type, + const struct _cef_cursor_info_t* custom_cursor_info); /// // Called when the user starts dragging content in the web view. Contextual diff --git a/include/cef_render_handler.h b/include/cef_render_handler.h index aa4157f8d..812c00a29 100644 --- a/include/cef_render_handler.h +++ b/include/cef_render_handler.h @@ -50,6 +50,7 @@ /*--cef(source=client)--*/ class CefRenderHandler : public virtual CefBase { public: + typedef cef_cursor_type_t CursorType; typedef cef_drag_operations_mask_t DragOperation; typedef cef_drag_operations_mask_t DragOperationsMask; typedef cef_paint_element_type_t PaintElementType; @@ -114,8 +115,8 @@ class CefRenderHandler : public virtual CefBase { // Called when an element should be painted. |type| indicates whether the // element is the view or the popup widget. |buffer| contains the pixel data // for the whole image. |dirtyRects| contains the set of rectangles that need - // to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes - // in size and represents a BGRA image with an upper-left origin. + // to be repainted. |buffer| will be |width|*|height|*4 bytes in size and + // represents a BGRA image with an upper-left origin. /// /*--cef()--*/ virtual void OnPaint(CefRefPtr browser, @@ -125,11 +126,14 @@ class CefRenderHandler : public virtual CefBase { int width, int height) =0; /// - // Called when the browser window's cursor has changed. + // Called when the browser's cursor has changed. If |type| is CT_CUSTOM then + // |custom_cursor_info| will be populated with the custom cursor information. /// /*--cef()--*/ virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) {} + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) {} /// // Called when the user starts dragging content in the web view. Contextual diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 4354f5829..6bf5d0d23 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1840,6 +1840,68 @@ typedef struct _cef_page_range_t { int to; } cef_page_range_t; +/// +// Cursor type values. +/// +typedef enum { + CT_POINTER = 0, + CT_CROSS, + CT_HAND, + CT_IBEAM, + CT_WAIT, + CT_HELP, + CT_EASTRESIZE, + CT_NORTHRESIZE, + CT_NORTHEASTRESIZE, + CT_NORTHWESTRESIZE, + CT_SOUTHRESIZE, + CT_SOUTHEASTRESIZE, + CT_SOUTHWESTRESIZE, + CT_WESTRESIZE, + CT_NORTHSOUTHRESIZE, + CT_EASTWESTRESIZE, + CT_NORTHEASTSOUTHWESTRESIZE, + CT_NORTHWESTSOUTHEASTRESIZE, + CT_COLUMNRESIZE, + CT_ROWRESIZE, + CT_MIDDLEPANNING, + CT_EASTPANNING, + CT_NORTHPANNING, + CT_NORTHEASTPANNING, + CT_NORTHWESTPANNING, + CT_SOUTHPANNING, + CT_SOUTHEASTPANNING, + CT_SOUTHWESTPANNING, + CT_WESTPANNING, + CT_MOVE, + CT_VERTICALTEXT, + CT_CELL, + CT_CONTEXTMENU, + CT_ALIAS, + CT_PROGRESS, + CT_NODROP, + CT_COPY, + CT_NONE, + CT_NOTALLOWED, + CT_ZOOMIN, + CT_ZOOMOUT, + CT_GRAB, + CT_GRABBING, + CT_CUSTOM, +} cef_cursor_type_t; + +/// +// Structure representing cursor information. |buffer| will be +// |size.width|*|size.height|*4 bytes in size and represents a BGRA image with +// an upper-left origin. +/// +typedef struct _cef_cursor_info_t { + cef_point_t hotspot; + float image_scale_factor; + void* buffer; + cef_size_t size; +} cef_cursor_info_t; + #ifdef __cplusplus } #endif diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 3f0a9a9b4..9a4036d9c 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -756,4 +756,25 @@ inline bool operator!=(const CefPageRange& a, const CefPageRange& b) { } +struct CefCursorInfoTraits { + typedef cef_cursor_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->hotspot = src->hotspot; + target->image_scale_factor = src->image_scale_factor; + target->buffer = src->buffer; + target->size = src->size; + } +}; + +/// +// Class representing cursor information. +/// +typedef CefStructBase CefCursorInfo; + #endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ diff --git a/libcef/browser/render_widget_host_view_osr.cc b/libcef/browser/render_widget_host_view_osr.cc index 242487e5b..798b0ab8f 100644 --- a/libcef/browser/render_widget_host_view_osr.cc +++ b/libcef/browser/render_widget_host_view_osr.cc @@ -368,6 +368,21 @@ void CefRenderWidgetHostViewOSR::UpdateCursor( if (!browser_impl_.get()) return; + content::WebCursor::CursorInfo cursor_info; + cursor.GetCursorInfo(&cursor_info); + + const cef_cursor_type_t cursor_type = + static_cast(cursor_info.type); + CefCursorInfo custom_cursor_info; + if (cursor.IsCustom()) { + custom_cursor_info.hotspot.x = cursor_info.hotspot.x(); + custom_cursor_info.hotspot.y = cursor_info.hotspot.y(); + custom_cursor_info.image_scale_factor = cursor_info.image_scale_factor; + custom_cursor_info.buffer = cursor_info.custom_image.getPixels(); + custom_cursor_info.size.width = cursor_info.custom_image.width(); + custom_cursor_info.size.height = cursor_info.custom_image.height(); + } + #if defined(USE_AURA) content::WebCursor web_cursor = cursor; @@ -376,19 +391,17 @@ void CefRenderWidgetHostViewOSR::UpdateCursor( // |web_cursor| owns the resulting |platform_cursor|. platform_cursor = web_cursor.GetPlatformCursor(); } else { - content::WebCursor::CursorInfo cursor_info; - cursor.GetCursorInfo(&cursor_info); platform_cursor = browser_impl_->GetPlatformCursor(cursor_info.type); } browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange( - browser_impl_.get(), platform_cursor); + browser_impl_.get(), platform_cursor, cursor_type, custom_cursor_info); #elif defined(OS_MACOSX) // |web_cursor| owns the resulting |native_cursor|. content::WebCursor web_cursor = cursor; CefCursorHandle native_cursor = web_cursor.GetNativeCursor(); browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange( - browser_impl_.get(), native_cursor); + browser_impl_.get(), native_cursor, cursor_type, custom_cursor_info); #else // TODO(port): Implement this method to work on other platforms as part of // off-screen rendering support. diff --git a/libcef_dll/cpptoc/render_handler_cpptoc.cc b/libcef_dll/cpptoc/render_handler_cpptoc.cc index 203322453..e7e99be2f 100644 --- a/libcef_dll/cpptoc/render_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/render_handler_cpptoc.cc @@ -249,7 +249,8 @@ void CEF_CALLBACK render_handler_on_paint(struct _cef_render_handler_t* self, void CEF_CALLBACK render_handler_on_cursor_change( struct _cef_render_handler_t* self, cef_browser_t* browser, - cef_cursor_handle_t cursor) { + cef_cursor_handle_t cursor, cef_cursor_type_t type, + const struct _cef_cursor_info_t* custom_cursor_info) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -259,11 +260,22 @@ void CEF_CALLBACK render_handler_on_cursor_change( DCHECK(browser); if (!browser) return; + // Verify param: custom_cursor_info; type: struct_byref_const + DCHECK(custom_cursor_info); + if (!custom_cursor_info) + return; + + // Translate param: custom_cursor_info; type: struct_byref_const + CefCursorInfo custom_cursor_infoObj; + if (custom_cursor_info) + custom_cursor_infoObj.Set(*custom_cursor_info, false); // Execute CefRenderHandlerCppToC::Get(self)->OnCursorChange( CefBrowserCToCpp::Wrap(browser), - cursor); + cursor, + type, + custom_cursor_infoObj); } int CEF_CALLBACK render_handler_start_dragging( diff --git a/libcef_dll/ctocpp/render_handler_ctocpp.cc b/libcef_dll/ctocpp/render_handler_ctocpp.cc index 3b46f9d14..d5d298a9b 100644 --- a/libcef_dll/ctocpp/render_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/render_handler_ctocpp.cc @@ -186,7 +186,8 @@ void CefRenderHandlerCToCpp::OnPaint(CefRefPtr browser, } void CefRenderHandlerCToCpp::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { + CefCursorHandle cursor, CursorType type, + const CefCursorInfo& custom_cursor_info) { if (CEF_MEMBER_MISSING(struct_, on_cursor_change)) return; @@ -200,7 +201,9 @@ void CefRenderHandlerCToCpp::OnCursorChange(CefRefPtr browser, // Execute struct_->on_cursor_change(struct_, CefBrowserCppToC::Wrap(browser), - cursor); + cursor, + type, + &custom_cursor_info); } bool CefRenderHandlerCToCpp::StartDragging(CefRefPtr browser, diff --git a/libcef_dll/ctocpp/render_handler_ctocpp.h b/libcef_dll/ctocpp/render_handler_ctocpp.h index ac03608d6..aab5906c3 100644 --- a/libcef_dll/ctocpp/render_handler_ctocpp.h +++ b/libcef_dll/ctocpp/render_handler_ctocpp.h @@ -44,8 +44,8 @@ class CefRenderHandlerCToCpp void OnPaint(CefRefPtr browser, PaintElementType type, const RectList& dirtyRects, const void* buffer, int width, int height) override; - void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) override; + void OnCursorChange(CefRefPtr browser, CefCursorHandle cursor, + CursorType type, const CefCursorInfo& custom_cursor_info) override; bool StartDragging(CefRefPtr browser, CefRefPtr drag_data, DragOperationsMask allowed_ops, int x, int y) override; diff --git a/tests/cefclient/cefclient_osr_widget_gtk.cpp b/tests/cefclient/cefclient_osr_widget_gtk.cpp index 13ae6cc5f..5db6166d5 100644 --- a/tests/cefclient/cefclient_osr_widget_gtk.cpp +++ b/tests/cefclient/cefclient_osr_widget_gtk.cpp @@ -1184,13 +1184,9 @@ void OSRWindow::OnPaint(CefRefPtr browser, } void OSRWindow::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { - /*GtkWidget* window = gtk_widget_get_toplevel(glarea_); - GdkWindow* gdk_window = gtk_widget_get_window(window); - if (cursor->type == GDK_LAST_CURSOR) - cursor = NULL; - gdk_window_set_cursor(gdk_window, cursor);*/ - + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) { // Retrieve the X11 display shared with Chromium. ::Display* xdisplay = cef_get_xdisplay(); DCHECK(xdisplay); diff --git a/tests/cefclient/cefclient_osr_widget_gtk.h b/tests/cefclient/cefclient_osr_widget_gtk.h index 6fd5f704a..e79a3fa79 100644 --- a/tests/cefclient/cefclient_osr_widget_gtk.h +++ b/tests/cefclient/cefclient_osr_widget_gtk.h @@ -60,7 +60,9 @@ class OSRWindow : public ClientHandler::RenderHandler { int width, int height) OVERRIDE; virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) OVERRIDE; void Invalidate(); bool IsOverPopupWidget(int x, int y) const; diff --git a/tests/cefclient/cefclient_osr_widget_mac.h b/tests/cefclient/cefclient_osr_widget_mac.h index 51d53c091..30e48e096 100644 --- a/tests/cefclient/cefclient_osr_widget_mac.h +++ b/tests/cefclient/cefclient_osr_widget_mac.h @@ -92,7 +92,9 @@ class ClientOSRHandler : public ClientHandler::RenderHandler { int width, int height) OVERRIDE; virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) OVERRIDE; virtual bool StartDragging(CefRefPtr browser, CefRefPtr drag_data, diff --git a/tests/cefclient/cefclient_osr_widget_mac.mm b/tests/cefclient/cefclient_osr_widget_mac.mm index b51d96fa5..c881320e8 100644 --- a/tests/cefclient/cefclient_osr_widget_mac.mm +++ b/tests/cefclient/cefclient_osr_widget_mac.mm @@ -252,7 +252,9 @@ void ClientOSRHandler::OnPaint(CefRefPtr browser, } void ClientOSRHandler::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) { CEF_REQUIRE_UI_THREAD(); [cursor set]; } diff --git a/tests/cefclient/cefclient_osr_widget_win.cpp b/tests/cefclient/cefclient_osr_widget_win.cpp index b884900b0..feecbfc7e 100644 --- a/tests/cefclient/cefclient_osr_widget_win.cpp +++ b/tests/cefclient/cefclient_osr_widget_win.cpp @@ -147,7 +147,9 @@ void OSRWindow::OnPaint(CefRefPtr browser, } void OSRWindow::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) { if (!::IsWindow(hWnd_)) return; diff --git a/tests/cefclient/cefclient_osr_widget_win.h b/tests/cefclient/cefclient_osr_widget_win.h index 700c83d86..c28467b1a 100644 --- a/tests/cefclient/cefclient_osr_widget_win.h +++ b/tests/cefclient/cefclient_osr_widget_win.h @@ -68,7 +68,9 @@ class OSRWindow : public ClientHandler::RenderHandler int width, int height) OVERRIDE; virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) OVERRIDE; virtual bool StartDragging(CefRefPtr browser, CefRefPtr drag_data, CefRenderHandler::DragOperationsMask allowed_ops, diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index b30c7f846..92de2a1ac 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -649,11 +649,13 @@ void ClientHandler::OnPaint(CefRefPtr browser, } void ClientHandler::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) { CEF_REQUIRE_UI_THREAD(); if (!osr_handler_.get()) return; - osr_handler_->OnCursorChange(browser, cursor); + osr_handler_->OnCursorChange(browser, cursor, type, custom_cursor_info); } bool ClientHandler::StartDragging(CefRefPtr browser, diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index 36bc4b702..effdc87d1 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -237,7 +237,9 @@ class ClientHandler : public CefClient, int width, int height) OVERRIDE; virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) OVERRIDE; virtual bool StartDragging(CefRefPtr browser, CefRefPtr drag_data, CefRenderHandler::DragOperationsMask allowed_ops, diff --git a/tests/unittests/os_rendering_unittest.cc b/tests/unittests/os_rendering_unittest.cc index 7ae50b08f..62e32bcaf 100644 --- a/tests/unittests/os_rendering_unittest.cc +++ b/tests/unittests/os_rendering_unittest.cc @@ -783,10 +783,14 @@ class OSRTestHandler : public RoutingTestHandler, } void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) override { - if (test_type_ == OSR_TEST_CURSOR && started()) { - DestroySucceededTestSoon(); - } + CefCursorHandle cursor, + CursorType type, + const CefCursorInfo& custom_cursor_info) override { + if (test_type_ == OSR_TEST_CURSOR && started()) { + EXPECT_EQ(CT_HAND, type); + EXPECT_EQ(NULL, custom_cursor_info.buffer); + DestroySucceededTestSoon(); + } } bool StartDragging(CefRefPtr browser,