WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
New patch
context-menu5.diff (text/plain), 18.06 KB, created by
Carlos Garcia Campos
on 2011-09-06 02:45:10 PDT
(
hide
)
Description:
New patch
Filename:
MIME Type:
Creator:
Carlos Garcia Campos
Created:
2011-09-06 02:45:10 PDT
Size:
18.06 KB
patch
obsolete
>diff --git a/Source/WebKit/gtk/ChangeLog b/Source/WebKit/gtk/ChangeLog >index ef20dee..7e6d47a 100644 >--- a/Source/WebKit/gtk/ChangeLog >+++ b/Source/WebKit/gtk/ChangeLog >@@ -1,3 +1,33 @@ >+2011-09-06 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [GTK] Add a signal to allow applications to handle its own context menu >+ https://bugs.webkit.org/show_bug.cgi?id=49904 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * tests/testhittestresult.c: >+ (load_status_cb): Test x, y properties of WebKitHitTestResult. >+ * webkit/webkithittestresult.cpp: >+ (webkit_hit_test_result_get_property): >+ (webkit_hit_test_result_set_property): >+ (webkit_hit_test_result_class_init): >+ (WebKit::kit): Add x and y construct only properties to keep the >+ coordinates of the event relative to view's widget. >+ * webkit/webkitwebsettings.cpp: >+ (webkit_web_settings_class_init): Mark enable-default-context-menu >+ property as deprecated. >+ * webkit/webkitwebview.cpp: >+ (prepareMouseEventForFrame): >+ (defaultContextMenuEnabled): Helper function to check whether >+ default context menu setting is enabled or not. >+ (webkit_web_view_forward_context_menu_event): Emit the new >+ context-menu signal. >+ (webkit_web_view_popup_menu_handler): >+ (webkit_web_view_button_press_event): >+ (webkit_web_view_class_init): Add new context-menu signal and mark >+ populate-popup as deprecated. >+ * webkitmarshal.list: >+ > 2011-08-30 Sheriff Bot <webkit.review.bot@gmail.com> > > Unreviewed, rolling out r94142, r94144, r94145, and r94148. >diff --git a/Source/WebKit/gtk/tests/testhittestresult.c b/Source/WebKit/gtk/tests/testhittestresult.c >index 0d7fb05..203713b 100644 >--- a/Source/WebKit/gtk/tests/testhittestresult.c >+++ b/Source/WebKit/gtk/tests/testhittestresult.c >@@ -83,6 +83,7 @@ load_status_cb(WebKitWebView* webView, > guint context; > GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); > WebKitDOMNode* node; >+ gint x, y; > > /* Close enough to 0,0 */ > event->button.x = 5; >@@ -98,6 +99,11 @@ load_status_cb(WebKitWebView* webView, > g_object_get(result, "inner-node", &node, NULL); > g_assert(node); > g_assert(WEBKIT_DOM_IS_NODE(node)); >+ >+ g_object_get(result, "x", &x, "y", &y, NULL); >+ g_assert_cmpint(x, ==, 5); >+ g_assert_cmpint(y, ==, 5); >+ > /* We can only test these node types at the moment. In the > * input case there seems to be an extra layer with a DIV on > * top of the input, which gets assigned to the inner-node. >diff --git a/Source/WebKit/gtk/webkit/webkithittestresult.cpp b/Source/WebKit/gtk/webkit/webkithittestresult.cpp >index cb7ac4b..83b675b 100644 >--- a/Source/WebKit/gtk/webkit/webkithittestresult.cpp >+++ b/Source/WebKit/gtk/webkit/webkithittestresult.cpp >@@ -21,6 +21,8 @@ > #include "config.h" > #include "webkithittestresult.h" > >+#include "Frame.h" >+#include "FrameView.h" > #include "GOwnPtr.h" > #include "GRefPtr.h" > #include "HitTestResult.h" >@@ -49,6 +51,7 @@ struct _WebKitHitTestResultPrivate { > char* imageURI; > char* mediaURI; > GRefPtr<WebKitDOMNode> innerNode; >+ WebCore::IntPoint position; > }; > > enum { >@@ -58,7 +61,9 @@ enum { > PROP_LINK_URI, > PROP_IMAGE_URI, > PROP_MEDIA_URI, >- PROP_INNER_NODE >+ PROP_INNER_NODE, >+ PROP_X, >+ PROP_Y > }; > > static void webkit_hit_test_result_finalize(GObject* object) >@@ -101,6 +106,12 @@ static void webkit_hit_test_result_get_property(GObject* object, guint propertyI > case PROP_INNER_NODE: > g_value_set_object(value, priv->innerNode.get()); > break; >+ case PROP_X: >+ g_value_set_int(value, priv->position.x()); >+ break; >+ case PROP_Y: >+ g_value_set_int(value, priv->position.y()); >+ break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec); > } >@@ -130,6 +141,12 @@ static void webkit_hit_test_result_set_property(GObject* object, guint propertyI > case PROP_INNER_NODE: > priv->innerNode = static_cast<WebKitDOMNode*>(g_value_get_object(value)); > break; >+ case PROP_X: >+ priv->position.setX(g_value_get_int(value)); >+ break; >+ case PROP_Y: >+ priv->position.setY(g_value_get_int(value)); >+ break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec); > } >@@ -225,6 +242,34 @@ static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* webHitTe > WEBKIT_TYPE_DOM_NODE, > static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); > >+ /** >+ * WebKitHitTestResult:x: >+ * >+ * The x coordintate of the event relative to the view's window. >+ * >+ * Since: 1.5.3 >+ */ >+ g_object_class_install_property(objectClass, PROP_X, >+ g_param_spec_int("x", >+ _("X coordinate"), >+ _("The x coordintate of the event relative to the view's window."), >+ G_MININT, G_MAXINT, 0, >+ static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); >+ >+ /** >+ * WebKitHitTestResult:y: >+ * >+ * The x coordintate of the event relative to the view's window. >+ * >+ * Since: 1.5.3 >+ */ >+ g_object_class_install_property(objectClass, PROP_Y, >+ g_param_spec_int("y", >+ _("Y coordinate"), >+ _("The y coordintate of the event relative to the view's window."), >+ G_MININT, G_MAXINT, 0, >+ static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); >+ > g_type_class_add_private(webHitTestResultClass, sizeof(WebKitHitTestResultPrivate)); > } > >@@ -243,6 +288,8 @@ WebKitHitTestResult* kit(const WebCore::HitTestResult& result) > GOwnPtr<char> imageURI(0); > GOwnPtr<char> mediaURI(0); > WebKitDOMNode* node = 0; >+ WebCore::Frame* targetFrame; >+ WebCore::IntPoint point; > > if (!result.absoluteLinkURL().isEmpty()) { > context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK; >@@ -268,12 +315,21 @@ WebKitHitTestResult* kit(const WebCore::HitTestResult& result) > if (result.innerNonSharedNode()) > node = kit(result.innerNonSharedNode()); > >+ targetFrame = result.targetFrame(); >+ if (targetFrame && targetFrame->view()) { >+ // Convert document coords to widget coords. >+ point = targetFrame->view()->contentsToWindow(result.point()); >+ } else >+ point = result.point(); >+ > return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT, > "link-uri", linkURI.get(), > "image-uri", imageURI.get(), > "media-uri", mediaURI.get(), > "context", context, > "inner-node", node, >+ "x", point.x(), >+ "y", point.y(), > NULL)); > } > >diff --git a/Source/WebKit/gtk/webkit/webkitwebsettings.cpp b/Source/WebKit/gtk/webkit/webkitwebsettings.cpp >index 34e4321..6398a78 100644 >--- a/Source/WebKit/gtk/webkit/webkitwebsettings.cpp >+++ b/Source/WebKit/gtk/webkit/webkitwebsettings.cpp >@@ -761,6 +761,8 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) > * right-clicks that are handled by the page itself. > * > * Since: 1.1.18 >+ * >+ * Deprecated: 1.5.3: Use #WebKitWebView::context-menu signal instead. > */ > g_object_class_install_property(gobject_class, > PROP_ENABLE_DEFAULT_CONTEXT_MENU, >diff --git a/Source/WebKit/gtk/webkit/webkitwebview.cpp b/Source/WebKit/gtk/webkit/webkitwebview.cpp >index 38be5a2..6390d2c 100644 >--- a/Source/WebKit/gtk/webkit/webkitwebview.cpp >+++ b/Source/WebKit/gtk/webkit/webkitwebview.cpp >@@ -204,6 +204,7 @@ enum { > EDITING_ENDED, > VIEWPORT_ATTRIBUTES_RECOMPUTE_REQUESTED, > VIEWPORT_ATTRIBUTES_CHANGED, >+ CONTEXT_MENU, > > LAST_SIGNAL > }; >@@ -308,23 +309,37 @@ static void contextMenuConnectActivate(GtkMenuItem* item, ContextMenuController* > g_signal_connect(item, "activate", G_CALLBACK(contextMenuItemActivated), controller); > } > >-static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event) >+static MouseEventWithHitTestResults prepareMouseEventForFrame(Frame* frame, const PlatformMouseEvent& event) >+{ >+ HitTestRequest request(HitTestRequest::Active); >+ IntPoint point = frame->view()->windowToContents(event.pos()); >+ return frame->document()->prepareMouseEvent(request, point, event); >+} >+ >+// Check enable-default-context-menu setting for compatibility. >+static bool defaultContextMenuEnabled(WebKitWebView* webView) >+{ >+ WebKitWebSettings* settings = webkit_web_view_get_settings(webView); >+ gboolean enableDefaultContextMenu; >+ g_object_get(settings, "enable-default-context-menu", &enableDefaultContextMenu, NULL); >+ return enableDefaultContextMenu; >+} >+ >+static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event, bool keyboardMode) > { > Page* page = core(webView); > page->contextMenuController()->clearContextMenu(); > Frame* focusedFrame; > Frame* mainFrame = page->mainFrame(); > gboolean mousePressEventResult = FALSE; >+ GRefPtr<WebKitHitTestResult> hitTestResult; > > if (!mainFrame->view()) > return FALSE; > > mainFrame->view()->setCursor(pointerCursor()); > if (page->frameCount()) { >- HitTestRequest request(HitTestRequest::Active); >- IntPoint point = mainFrame->view()->windowToContents(event.pos()); >- MouseEventWithHitTestResults mev = mainFrame->document()->prepareMouseEvent(request, point, event); >- >+ MouseEventWithHitTestResults mev = prepareMouseEventForFrame(mainFrame, event); > Frame* targetFrame = EventHandler::subframeForHitTestResult(mev); > if (!targetFrame) > targetFrame = mainFrame; >@@ -334,13 +349,14 @@ static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webVie > page->focusController()->setFocusedFrame(targetFrame); > focusedFrame = targetFrame; > } >+ if (focusedFrame == mainFrame) >+ hitTestResult = adoptGRef(kit(mev.hitTestResult())); > } else > focusedFrame = mainFrame; > > if (focusedFrame->view() && focusedFrame->eventHandler()->handleMousePressEvent(event)) > mousePressEventResult = TRUE; > >- > bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(event); > if (!handledEvent) > return FALSE; >@@ -353,37 +369,42 @@ static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webVie > if (!coreMenu) > return mousePressEventResult; > >- // If we reach here, it's because WebCore is going to show the >- // default context menu. We check our setting to figure out >- // whether we want it or not. >- WebKitWebSettings* settings = webkit_web_view_get_settings(webView); >- gboolean enableDefaultContextMenu; >- g_object_get(settings, "enable-default-context-menu", &enableDefaultContextMenu, NULL); >+ GtkMenu* defaultMenu = GTK_MENU(coreMenu->platformDescription()); >+ if (defaultMenu) { >+ // We connect the "activate" signal here rather than in ContextMenuGtk to avoid >+ // a layering violation. ContextMenuGtk should not know about the ContextMenuController. >+ gtk_container_foreach(GTK_CONTAINER(defaultMenu), (GtkCallback)contextMenuConnectActivate, controller); >+ } > >- if (!enableDefaultContextMenu) >- return FALSE; >+ if (!hitTestResult) { >+ MouseEventWithHitTestResults mev = prepareMouseEventForFrame(focusedFrame, event); >+ hitTestResult = adoptGRef(kit(mev.hitTestResult())); >+ } > >- GtkMenu* menu = GTK_MENU(coreMenu->platformDescription()); >- if (!menu) >- return FALSE; >+ gboolean handled; >+ g_signal_emit(webView, webkit_web_view_signals[CONTEXT_MENU], 0, defaultMenu, hitTestResult.get(), keyboardMode, &handled); >+ if (handled) >+ return TRUE; > >- // We connect the "activate" signal here rather than in ContextMenuGtk to avoid >- // a layering violation. ContextMenuGtk should not know about the ContextMenuController. >- gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller); >+ // Return now ff there's no default context menu or it's disabled by enable-default-context-menu setting. >+ // Check enable-default-context-menu setting for compatibility. >+ if (!defaultMenu || !defaultContextMenuEnabled(webView)) >+ return FALSE; > >- g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, menu); >+ // Emit populate-popup signal for compatibility. >+ g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, defaultMenu); > > // If the context menu is now empty, don't show it. >- GOwnPtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu))); >+ GOwnPtr<GList> items(gtk_container_get_children(GTK_CONTAINER(defaultMenu))); > if (!items) > return FALSE; > > WebKitWebViewPrivate* priv = webView->priv; >- priv->currentMenu = menu; >+ priv->currentMenu = defaultMenu; > priv->lastPopupXPosition = event.globalX(); > priv->lastPopupYPosition = event.globalY(); > >- gtk_menu_popup(menu, 0, 0, &PopupMenuPositionFunc, webView, event.button() + 1, gtk_get_current_event_time()); >+ gtk_menu_popup(defaultMenu, 0, 0, &PopupMenuPositionFunc, webView, event.button() + 1, gtk_get_current_event_time()); > return TRUE; > } > >@@ -424,7 +445,7 @@ static gboolean webkit_web_view_popup_menu_handler(GtkWidget* widget) > > IntPoint globalPoint(convertWidgetPointToScreenPoint(widget, location)); > PlatformMouseEvent event(location, globalPoint, RightButton, MouseEventPressed, 0, false, false, false, false, gtk_get_current_event_time()); >- return webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event); >+ return webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event, true); > } > > #ifndef GTK_API_VERSION_2 >@@ -782,7 +803,7 @@ static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventBu > platformEvent.setClickCount(priv->clickCounter.clickCountForGdkButtonEvent(widget, event)); > > if (event->button == 3) >- return webkit_web_view_forward_context_menu_event(webView, PlatformMouseEvent(event)); >+ return webkit_web_view_forward_context_menu_event(webView, PlatformMouseEvent(event), false); > > Frame* frame = core(webView)->mainFrame(); > if (!frame->view()) >@@ -2166,6 +2187,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) > * When a context menu is about to be displayed this signal is emitted. > * > * Add menu items to #menu to extend the context menu. >+ * >+ * Deprecated: 1.5.3: Use #WebKitWebView::context-menu signal instead. > */ > webkit_web_view_signals[POPULATE_POPUP] = g_signal_new("populate-popup", > G_TYPE_FROM_CLASS(webViewClass), >@@ -2745,6 +2768,43 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) > WEBKIT_TYPE_VIEWPORT_ATTRIBUTES); > > /* >+ * WebKitWebView::context-menu >+ * @webView: the object which received the signal >+ * @default_menu: the default context menu >+ * @hit_test_result: a #WebKitHitTestResult with the context of the current position. >+ * @keyboard_mode: %TRUE if the context menu was triggered using the keyboard >+ * >+ * Emmited when a context menu is about to be displayed to give the application >+ * a chance to create and handle its own context menu. If you only want to add custom >+ * options to the default context menu you can simply modify the given @default_menu. >+ * >+ * When keyboard_mode is %TRUE the coordinates of the given @hit_test_result should be >+ * used to position the popup menu. When the context menu has been triggered by a >+ * mouse event you could either use the @hit_test_result coordinates or pass %NULL >+ * to the #GtkMenuPositionFunc parameter of gtk_menu_popup() function. >+ * Note that coordinates of @hit_test_result are relative to @webView window. >+ * >+ * When the signal is handled and a popup menu has been created by the application, >+ * %TRUE should be returned. Note that when the context menu is handled by the >+ * application, the "enable-default-context-menu" setting will be ignored and >+ * #WebKitWebView::populate-popup signal won't be emitted. >+ * If you don't want any context menu to be shown, you can simply connect to this signal >+ * and return %TRUE without doing anything else. >+ * >+ * Since: 1.5.3 >+ */ >+ webkit_web_view_signals[CONTEXT_MENU] = g_signal_new("context-menu", >+ G_TYPE_FROM_CLASS(webViewClass), >+ (GSignalFlags)G_SIGNAL_RUN_LAST, >+ 0, >+ 0, 0, >+ webkit_marshal_BOOLEAN__OBJECT_OBJECT_BOOLEAN, >+ G_TYPE_BOOLEAN, 3, >+ GTK_TYPE_WIDGET, >+ WEBKIT_TYPE_HIT_TEST_RESULT, >+ G_TYPE_BOOLEAN); >+ >+ /* > * implementations of virtual methods > */ > webViewClass->create_web_view = webkit_web_view_real_create_web_view; >diff --git a/Source/WebKit/gtk/webkitmarshal.list b/Source/WebKit/gtk/webkitmarshal.list >index 5372c57..86bcaa5 100644 >--- a/Source/WebKit/gtk/webkitmarshal.list >+++ b/Source/WebKit/gtk/webkitmarshal.list >@@ -2,6 +2,7 @@ BOOLEAN:ENUM,INT > BOOLEAN:INT,INT,STRING > BOOLEAN:OBJECT > BOOLEAN:OBJECT,OBJECT >+BOOLEAN:OBJECT,OBJECT,BOOLEAN > BOOLEAN:OBJECT,OBJECT,ENUM > BOOLEAN:OBJECT,OBJECT,ENUM,BOOLEAN > BOOLEAN:OBJECT,OBJECT,OBJECT,OBJECT
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 49904
:
74543
|
75018
|
76383
|
76818
|
76876
|
106400
|
106401
|
106556