Title: [111843] trunk/Source/WebKit/gtk
Revision
111843
Author
carlo...@webkit.org
Date
2012-03-23 02:29:03 -0700 (Fri, 23 Mar 2012)

Log Message

[GTK] Add a signal to allow applications to handle its own context menu
https://bugs.webkit.org/show_bug.cgi?id=49904

Reviewed by Gustavo Noronha Silva.

* 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): Add x and y construct only
properties to keep the coordinates of the event relative to view's
widget.
(WebKit::kit):
* 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:

Modified Paths

Diff

Modified: trunk/Source/WebKit/gtk/ChangeLog (111842 => 111843)


--- trunk/Source/WebKit/gtk/ChangeLog	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/ChangeLog	2012-03-23 09:29:03 UTC (rev 111843)
@@ -1,5 +1,36 @@
 2012-03-23  Carlos Garcia Campos  <cgar...@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 Gustavo Noronha Silva.
+
+        * 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): Add x and y construct only
+        properties to keep the coordinates of the event relative to view's
+        widget.
+        (WebKit::kit):
+        * 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:
+
+2012-03-23  Carlos Garcia Campos  <cgar...@igalia.com>
+
         Unreviewed. Fix GTK+ build after r111707.
 
         * WebCoreSupport/UserMediaClientGtk.h:

Modified: trunk/Source/WebKit/gtk/tests/testhittestresult.c (111842 => 111843)


--- trunk/Source/WebKit/gtk/tests/testhittestresult.c	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/tests/testhittestresult.c	2012-03-23 09:29:03 UTC (rev 111843)
@@ -83,6 +83,7 @@
         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 @@
         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.

Modified: trunk/Source/WebKit/gtk/webkit/webkithittestresult.cpp (111842 => 111843)


--- trunk/Source/WebKit/gtk/webkit/webkithittestresult.cpp	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/webkit/webkithittestresult.cpp	2012-03-23 09:29:03 UTC (rev 111843)
@@ -21,6 +21,8 @@
 #include "config.h"
 #include "webkithittestresult.h"
 
+#include "Frame.h"
+#include "FrameView.h"
 #include "HitTestResult.h"
 #include "KURL.h"
 #include "WebKitDOMBinding.h"
@@ -49,6 +51,7 @@
     char* imageURI;
     char* mediaURI;
     GRefPtr<WebKitDOMNode> innerNode;
+    WebCore::IntPoint position;
 };
 
 enum {
@@ -58,7 +61,9 @@
     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 @@
     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 @@
     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 @@
                                                         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.10
+     */
+    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.10
+     */
+    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 @@
     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 @@
     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));
 }
 

Modified: trunk/Source/WebKit/gtk/webkit/webkitwebsettings.cpp (111842 => 111843)


--- trunk/Source/WebKit/gtk/webkit/webkitwebsettings.cpp	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/webkit/webkitwebsettings.cpp	2012-03-23 09:29:03 UTC (rev 111843)
@@ -754,6 +754,8 @@
      * right-clicks that are handled by the page itself.
      *
      * Since: 1.1.18
+     *
+     * Deprecated: 1.10: Use #WebKitWebView::context-menu signal instead.
      */
     g_object_class_install_property(gobject_class,
                                     PROP_ENABLE_DEFAULT_CONTEXT_MENU,

Modified: trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp (111842 => 111843)


--- trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp	2012-03-23 09:29:03 UTC (rev 111843)
@@ -219,6 +219,7 @@
     RESOURCE_LOAD_FAILED,
     ENTERING_FULLSCREEN,
     LEAVING_FULLSCREEN,
+    CONTEXT_MENU,
 
     LAST_SIGNAL
 };
@@ -323,23 +324,36 @@
     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.position());
+    return frame->document()->prepareMouseEvent(request, point, event);
+}
+
+// Check enable-default-context-menu setting for compatibility.
+static bool defaultContextMenuEnabled(WebKitWebView* webView)
+{
+    gboolean enableDefaultContextMenu;
+    g_object_get(webkit_web_view_get_settings(webView), "enable-default-context-menu", &enableDefaultContextMenu, NULL);
+    return enableDefaultContextMenu;
+}
+
+static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event, bool triggeredWithKeyboard)
+{
     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.position());
-        MouseEventWithHitTestResults mev = mainFrame->document()->prepareMouseEvent(request, point, event);
-
+        MouseEventWithHitTestResults mev = prepareMouseEventForFrame(mainFrame, event);
         Frame* targetFrame = EventHandler::subframeForHitTestResult(mev);
         if (!targetFrame)
             targetFrame = mainFrame;
@@ -349,13 +363,14 @@
             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;
@@ -368,37 +383,42 @@
     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 = coreMenu->platformDescription();
+    ASSERT(defaultMenu);
 
-    if (!enableDefaultContextMenu)
-        return FALSE;
+    // 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), reinterpret_cast<GtkCallback>(contextMenuConnectActivate), controller);
 
-    GtkMenu* menu = GTK_MENU(coreMenu->platformDescription());
-    if (!menu)
+    if (!hitTestResult) {
+        MouseEventWithHitTestResults mev = prepareMouseEventForFrame(focusedFrame, event);
+        hitTestResult = adoptGRef(kit(mev.hitTestResult()));
+    }
+
+    gboolean handled;
+    g_signal_emit(webView, webkit_web_view_signals[CONTEXT_MENU], 0, defaultMenu, hitTestResult.get(), triggeredWithKeyboard, &handled);
+    if (handled)
+        return TRUE;
+
+    // Return now if default context menu is disabled by enable-default-context-menu setting.
+    // Check enable-default-context-menu setting for compatibility.
+    if (!defaultContextMenuEnabled(webView))
         return FALSE;
 
-    // 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);
+    // Emit populate-popup signal for compatibility.
+    g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, defaultMenu);
 
-    g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, menu);
-
     // 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.globalPosition().x();
     priv->lastPopupYPosition = event.globalPosition().y();
 
-    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;
 }
 
@@ -439,7 +459,7 @@
 
     IntPoint globalPoint(convertWidgetPointToScreenPoint(widget, location));
     PlatformMouseEvent event(location, globalPoint, RightButton, PlatformEvent::MousePressed, 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);
 }
 
 static void setHorizontalAdjustment(WebKitWebView* webView, GtkAdjustment* adjustment)
@@ -740,7 +760,7 @@
     platformEvent.setClickCount(count);
 
     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())
@@ -2105,6 +2125,8 @@
      * 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.10: Use #WebKitWebView::context-menu signal instead.
      */
     webkit_web_view_signals[POPULATE_POPUP] = g_signal_new("populate-popup",
             G_TYPE_FROM_CLASS(webViewClass),
@@ -2825,6 +2847,41 @@
             WEBKIT_TYPE_WEB_RESOURCE,
             G_TYPE_POINTER);
 
+    /**
+     * WebKitWebView::context-menu:
+     * @web_view: 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 @web_view window.
+     *
+     * If your application will create and display its own popup menu, %TRUE should be returned.
+     * Note that when the context menu is handled by the application, the #WebKitWebSettings:enable-default-context-menu
+     * setting will be ignored and the #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.10
+     */
+    webkit_web_view_signals[CONTEXT_MENU] = g_signal_new("context-menu",
+            G_TYPE_FROM_CLASS(webViewClass),
+            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
      */

Modified: trunk/Source/WebKit/gtk/webkitmarshal.list (111842 => 111843)


--- trunk/Source/WebKit/gtk/webkitmarshal.list	2012-03-23 09:26:47 UTC (rev 111842)
+++ trunk/Source/WebKit/gtk/webkitmarshal.list	2012-03-23 09:29:03 UTC (rev 111843)
@@ -2,6 +2,7 @@
 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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to