[WK2] Keyboard menu key should show context menu
authortpopela@redhat.com <tpopela@redhat.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 14:20:47 +0000 (14:20 +0000)
committertpopela@redhat.com <tpopela@redhat.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 14:20:47 +0000 (14:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72099

Source/WebCore:

Reviewed by Carlos Garcia Campos.

Show the context menu when the GtkWidget::popup-menu signal is
emitted. This signal is triggered by pressing a key (usually
the Menu key or the Shift + F10 shortcut) or it could be emitted on
WebKitWebView.

Test: fast/events/context-activated-by-key-event.html

Also could be tested by:

ManualTests/keyboard-menukey-event.html
ManualTests/win/contextmenu-key.html
ManualTests/win/contextmenu-key2.html

* page/EventHandler.cpp:
(WebCore::EventHandler::sendContextMenuEventForKey):
Correctly send the mouse event that used for showing the context menu.
Previously the event was immediately dispatched as it is, but this was
only the right way if some element was focused on the page. If there
was no focused element or non-empty text range then the event lacked
the right node, where it was supposed to be shown. The correct node
is determined and added to the event in the sendContextMenuEvent() so
we have to use this function to send the event.

Also use absoluteBoundingBoxRect() instead of
pixelSnappedAbsoluteClippedOverflowRect() when determining
a coordinate where to show the context menu for the currently focus
element. The latter is not returning a right box (it is bigger) which
could lead to the situation that no menu will be displayed at all,
because the HitTest won't contain the right element as the
determined coordinates could be outside of the element.
* page/EventHandler.h:

Source/WebKit2:

Reviewed by Carlos Garcia Campos.

Show the context menu when the GtkWidget::popup-menu signal is
emitted. This signal is triggered by pressing a key (usually
the Menu key or the Shift + F10 shortcut) or it could be emitted on
WebKitWebView.

* UIProcess/API/gtk/WebKitWebView.cpp:
(webkit_web_view_class_init):
(webkit_web_view_class_init): Update the documentation for the
context-menu signal
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBasePopupMenu): Connect to the popup-menu signal and
save the event that was used to trigger the signal. If there is no
such event create a new GdkEvent with GDK_NOTHING type.
(webkitWebViewBasePopupMenu):
(webkit_web_view_base_class_init):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleContextMenuKeyEvent):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::contextMenuForKeyEvent):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Show the context menu when the GtkWidget::popup-menu signal is
emitted. This signal is triggered by pressing a key (usually
the Menu key or the Shift + F10 shortcut) or it could be emitted on
WebKitWebView.

Reviewed by Carlos Garcia Campos.

* TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp:
(testContextMenuDefaultMenu):
* TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.cpp:
(WebViewTest::emitPopupMenuSignal):
* TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.h:

LayoutTests:

Reviewed by Carlos Garcia Campos.

Skip the fast/events/context-activated-by-key-event.html on Mac as it
does not have a key to activate the context menu and on iOS as well.

* platform/ios-simulator-wk2/TestExpectations:
* platform/mac-wk2/TestExpectations:
* platform/mac/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213278 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/context-activated-by-key-event-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/context-activated-by-key-event.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator-wk2/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/EventHandler.h
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp
Tools/TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.cpp
Tools/TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.h

index b23148b..9e5be26 100644 (file)
@@ -1,3 +1,17 @@
+2017-03-02  Tomas Popela  <tpopela@redhat.com>
+
+        [WK2] Keyboard menu key should show context menu
+        https://bugs.webkit.org/show_bug.cgi?id=72099
+
+        Reviewed by Carlos Garcia Campos.
+
+        Skip the fast/events/context-activated-by-key-event.html on Mac as it
+        does not have a key to activate the context menu and on iOS as well.
+
+        * platform/ios-simulator-wk2/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2017-03-02  Javier Fernandez  <jfernandez@igalia.com>
 
         [GTK] Unreviewed test gardening 
diff --git a/LayoutTests/fast/events/context-activated-by-key-event-expected.txt b/LayoutTests/fast/events/context-activated-by-key-event-expected.txt
new file mode 100644 (file)
index 0000000..98706e5
--- /dev/null
@@ -0,0 +1,7 @@
+This tests whether the context menu is displayed on the menu key press.
+example.com
+PASS WINDOW
+PASS CONTENTEDITABLE
+PASS ELEMENT
+PASS CONTENTEDITABLE SELECTION
+
diff --git a/LayoutTests/fast/events/context-activated-by-key-event.html b/LayoutTests/fast/events/context-activated-by-key-event.html
new file mode 100644 (file)
index 0000000..79925b2
--- /dev/null
@@ -0,0 +1,56 @@
+<html>
+<body>
+<div id="contenteditable" contenteditable>This tests whether the context menu is displayed on the menu key press.</div>
+<a id="link" href="example.com">example.com</a>
+<p id='result'></p>
+</body>
+</html>
+
+
+<script>
+function log(text) {
+  document.getElementById('result').appendChild(document.createTextNode(text));
+  document.getElementById('result').appendChild(document.createElement("br"));
+}
+
+function onWindowContextMenu(event) {
+  log('PASS WINDOW');
+  event.stopPropagation();
+}
+function onContentEditableContextMenu(event) {
+  if (window.getSelection().toString())
+    log('PASS CONTENTEDITABLE SELECTION');
+  else
+    log('PASS CONTENTEDITABLE');
+  event.stopPropagation();
+}
+function onFocusedElementContextMenu(event) {
+  log('PASS ELEMENT');
+  event.stopPropagation();
+}
+
+window.addEventListener('contextmenu', onWindowContextMenu);
+document.getElementById('contenteditable').addEventListener('contextmenu', onContentEditableContextMenu);
+document.getElementById('link').addEventListener('contextmenu', onFocusedElementContextMenu);
+
+if (window.testRunner) {
+  eventSender.keyDown('menu');
+
+  var rect = document.getElementById('contenteditable').getBoundingClientRect();
+  var x = rect.left + rect.width / 2;
+  var y = rect.top + rect.height / 2;
+  eventSender.mouseMoveTo(x, y);
+  eventSender.mouseDown();
+  eventSender.mouseUp();
+  eventSender.keyDown('menu');
+
+  document.getElementById('link').focus();
+  eventSender.keyDown('menu');
+
+  window.getSelection().selectAllChildren(document.getElementById('contenteditable'));
+  eventSender.keyDown('menu');
+
+  testRunner.dumpAsText();
+}
+
+</script>
index a0aa171..d3aea05 100644 (file)
@@ -1916,3 +1916,6 @@ fast/css/deferred-parsing/hover-test.html [ Skip ]
 webkit.org/b/166025 http/tests/fetch/fetching-same-resource-with-diffferent-options.html [ Pass Failure ]
 
 imported/w3c/web-platform-tests/webrtc [ Skip ]
+
+# Skipped because there is no key to show the context menu
+fast/events/context-activated-by-key-event.html [ Skip ]
index 30b5d05..452845f 100644 (file)
@@ -638,4 +638,8 @@ webkit.org/b/168089 [ Release ] animations/trigger-container-scroll-empty.html [
 
 webkit.org/b/168391 [ ElCapitan Debug ] storage/indexeddb/modern/idbcursor-continue-primary-key-1.html [ Pass Timeout ]
 
+
 webkit.org/b/168380 [ ElCapitan Debug ] imported/w3c/web-platform-tests/IndexedDB/idb-binary-key-roundtrip.htm [ Pass Failure ]
+
+# Skipped because Mac doesn't have a key to show the context menu
+fast/events/context-activated-by-key-event.html [ Skip ]
index dc2e681..fd2a0d4 100644 (file)
@@ -1550,3 +1550,6 @@ webkit.org/b/168503 editing/pasteboard/drag-drop-copy-content.html [ Failure ]
 webkit.org/b/168936 imported/w3c/web-platform-tests/IndexedDB/idbdatabase-deleteObjectStore-exception-order.htm [ Pass Failure ]
 
 webkit.org/b/168927 fast/dom/timer-throttling-hidden-page.html [ Pass Failure ]
+
+# Skipped because Mac doesn't have a key to show the context menu
+fast/events/context-activated-by-key-event.html [ Skip ]
index b9d8168..deb7f46 100644 (file)
@@ -1,3 +1,42 @@
+2017-03-02  Tomas Popela  <tpopela@redhat.com>
+
+        [WK2] Keyboard menu key should show context menu
+        https://bugs.webkit.org/show_bug.cgi?id=72099
+
+        Reviewed by Carlos Garcia Campos.
+
+        Show the context menu when the GtkWidget::popup-menu signal is
+        emitted. This signal is triggered by pressing a key (usually
+        the Menu key or the Shift + F10 shortcut) or it could be emitted on
+        WebKitWebView.
+
+        Test: fast/events/context-activated-by-key-event.html
+
+        Also could be tested by:
+
+        ManualTests/keyboard-menukey-event.html
+        ManualTests/win/contextmenu-key.html
+        ManualTests/win/contextmenu-key2.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::sendContextMenuEventForKey):
+        Correctly send the mouse event that used for showing the context menu.
+        Previously the event was immediately dispatched as it is, but this was
+        only the right way if some element was focused on the page. If there
+        was no focused element or non-empty text range then the event lacked
+        the right node, where it was supposed to be shown. The correct node
+        is determined and added to the event in the sendContextMenuEvent() so
+        we have to use this function to send the event.
+
+        Also use absoluteBoundingBoxRect() instead of
+        pixelSnappedAbsoluteClippedOverflowRect() when determining
+        a coordinate where to show the context menu for the currently focus
+        element. The latter is not returning a right box (it is bigger) which
+        could lead to the situation that no menu will be displayed at all,
+        because the HitTest won't contain the right element as the
+        determined coordinates could be outside of the element.
+        * page/EventHandler.h:
+
 2017-03-02  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Crash in WebCore::CoordinatedGraphicsLayer::notifyFlushRequired
index da81d83..a9ec397 100644 (file)
@@ -2899,8 +2899,9 @@ bool EventHandler::sendContextMenuEventForKey()
         RenderBoxModelObject* box = focusedElement->renderBoxModelObject();
         if (!box)
             return false;
-        IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
-        location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
+
+        IntRect boundingBoxRect = box->absoluteBoundingBoxRect(true);
+        location = IntPoint(boundingBoxRect.x(), boundingBoxRect.maxY() - 1);
     } else {
         location = IntPoint(
             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
@@ -2932,7 +2933,7 @@ bool EventHandler::sendContextMenuEventForKey()
 
     PlatformMouseEvent platformMouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime(), ForceAtClick, NoTap);
 
-    return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, platformMouseEvent, false);
+    return sendContextMenuEvent(platformMouseEvent);
 }
 #endif // ENABLE(CONTEXT_MENUS)
 
index 6af608c..deb09c4 100644 (file)
@@ -234,7 +234,7 @@ public:
 
 #if ENABLE(CONTEXT_MENUS)
     WEBCORE_EXPORT bool sendContextMenuEvent(const PlatformMouseEvent&);
-    bool sendContextMenuEventForKey();
+    WEBCORE_EXPORT bool sendContextMenuEventForKey();
 #endif
 
     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
index d25b217..cc43f33 100644 (file)
@@ -1,3 +1,33 @@
+2017-03-02  Tomas Popela  <tpopela@redhat.com>
+
+        [WK2] Keyboard menu key should show context menu
+        https://bugs.webkit.org/show_bug.cgi?id=72099
+
+        Reviewed by Carlos Garcia Campos.
+
+        Show the context menu when the GtkWidget::popup-menu signal is
+        emitted. This signal is triggered by pressing a key (usually
+        the Menu key or the Shift + F10 shortcut) or it could be emitted on
+        WebKitWebView.
+
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (webkit_web_view_class_init):
+        (webkit_web_view_class_init): Update the documentation for the
+        context-menu signal
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBasePopupMenu): Connect to the popup-menu signal and
+        save the event that was used to trigger the signal. If there is no
+        such event create a new GdkEvent with GDK_NOTHING type.
+        (webkitWebViewBasePopupMenu):
+        (webkit_web_view_base_class_init):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleContextMenuKeyEvent):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::contextMenuForKeyEvent):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2017-03-01  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Replace -[WKWebView adjustedDataInteractionItemProviders:] with a UI delegate method
index 52237c3..e4fb234 100644 (file)
@@ -1616,6 +1616,21 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
      * </para></listitem>
      * </itemizedlist>
      *
+     * The @event is expected to be one of the following types:
+     * <itemizedlist>
+     * <listitem><para>
+     * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu
+     * was triggered with mouse.
+     * <listitem><para>
+     * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show
+     * the menu.
+     * </para></listitem>
+     * <listitem><para>
+     * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget:popup-menu
+     * signal was used to show the context menu.
+     * </para></listitem>
+     * </itemizedlist>
+     *
      * If the signal handler returns %FALSE the context menu represented by @context_menu
      * will be shown, if it return %TRUE the context menu will not be shown.
      *
index 01fe963..b057a5a 100644 (file)
@@ -807,6 +807,20 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll*
     return TRUE;
 }
 
+static gboolean webkitWebViewBasePopupMenu(GtkWidget* widget)
+{
+    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+
+    GdkEvent* currentEvent = gtk_get_current_event();
+    if (!currentEvent)
+        currentEvent = gdk_event_new(GDK_NOTHING);
+    priv->contextMenuEvent.reset(currentEvent);
+    priv->pageProxy->handleContextMenuKeyEvent();
+
+    return TRUE;
+}
+
 static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event)
 {
     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
@@ -1121,6 +1135,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie
     widgetClass->button_press_event = webkitWebViewBaseButtonPressEvent;
     widgetClass->button_release_event = webkitWebViewBaseButtonReleaseEvent;
     widgetClass->scroll_event = webkitWebViewBaseScrollEvent;
+    widgetClass->popup_menu = webkitWebViewBasePopupMenu;
     widgetClass->motion_notify_event = webkitWebViewBaseMotionNotifyEvent;
     widgetClass->enter_notify_event = webkitWebViewBaseCrossingNotifyEvent;
     widgetClass->leave_notify_event = webkitWebViewBaseCrossingNotifyEvent;
index 9c7fd4d..fc02b5e 100644 (file)
@@ -4654,6 +4654,11 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
 
     m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
 }
+
+void WebPageProxy::handleContextMenuKeyEvent()
+{
+    m_process->send(Messages::WebPage::ContextMenuForKeyEvent(), m_pageID);
+}
 #endif // ENABLE(CONTEXT_MENUS)
 
 #if PLATFORM(IOS)
index d56c7b9..95ab2a5 100644 (file)
@@ -897,6 +897,7 @@ public:
 #if ENABLE(CONTEXT_MENUS)
     // Called by the WebContextMenuProxy.
     void contextMenuItemSelected(const WebContextMenuItemData&);
+    void handleContextMenuKeyEvent();
 #endif
 
     // Called by the WebOpenPanelResultListenerProxy.
index c2f254a..b3f3010 100644 (file)
@@ -2201,6 +2201,16 @@ static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent,
 
     return handled;
 }
+
+void WebPage::contextMenuForKeyEvent()
+{
+    corePage()->contextMenuController().clearContextMenu();
+
+    Frame& frame = m_page->focusController().focusedOrMainFrame();
+    bool handled = frame.eventHandler().sendContextMenuEventForKey();
+    if (handled)
+        contextMenu()->show();
+}
 #endif
 
 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, bool onlyUpdateScrollbars)
index 4714fc7..f0c9127 100644 (file)
@@ -1060,6 +1060,7 @@ private:
 #endif
 #if ENABLE(CONTEXT_MENUS)
     void contextMenuHidden() { m_isShowingContextMenu = false; }
+    void contextMenuForKeyEvent();
 #endif
 
     static bool scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity);
index 5291649..746e25d 100644 (file)
@@ -121,6 +121,7 @@ messages -> WebPage LegacyReceiver {
 
 #if ENABLE(CONTEXT_MENUS)
     ContextMenuHidden()
+    ContextMenuForKeyEvent()
 #endif
 
     ScrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
index 83812cb..4650afd 100644 (file)
@@ -1,3 +1,21 @@
+2017-03-02  Tomas Popela  <tpopela@redhat.com>
+
+        [WK2] Keyboard menu key should show context menu
+        https://bugs.webkit.org/show_bug.cgi?id=72099
+
+        Show the context menu when the GtkWidget::popup-menu signal is
+        emitted. This signal is triggered by pressing a key (usually
+        the Menu key or the Shift + F10 shortcut) or it could be emitted on
+        WebKitWebView.
+
+        Reviewed by Carlos Garcia Campos.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp:
+        (testContextMenuDefaultMenu):
+        * TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.cpp:
+        (WebViewTest::emitPopupMenuSignal):
+        * TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.h:
+
 2017-03-01  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Replace -[WKWebView adjustedDataInteractionItemProviders:] with a UI delegate method
index 42f606e..3d7ab00 100644 (file)
@@ -33,10 +33,24 @@ public:
     void checkContextMenuEvent(GdkEvent* event)
     {
         g_assert(event);
-        g_assert_cmpint(event->type, ==, GDK_BUTTON_PRESS);
-        g_assert_cmpint(event->button.button, ==, 3);
-        g_assert_cmpint(event->button.x, ==, m_menuPositionX);
-        g_assert_cmpint(event->button.y, ==, m_menuPositionY);
+        g_assert_cmpint(event->type, ==, m_expectedEventType);
+
+        switch (m_expectedEventType) {
+        case GDK_BUTTON_PRESS:
+            g_assert_cmpint(event->button.button, ==, 3);
+            g_assert_cmpint(event->button.x, ==, m_menuPositionX);
+            g_assert_cmpint(event->button.y, ==, m_menuPositionY);
+            break;
+        case GDK_KEY_PRESS:
+            g_assert_cmpint(event->key.keyval, ==, GDK_KEY_Menu);
+            break;
+        case GDK_NOTHING:
+            // GDK_NOTHING means that the context menu was triggered by the
+            // popup-menu signal. We don't have anything to check here.
+            break;
+        default:
+            g_assert_not_reached();
+        }
     }
 
     static gboolean contextMenuCallback(WebKitWebView* webView, WebKitContextMenu* contextMenu, GdkEvent* event, WebKitHitTestResult* hitTestResult, ContextMenuTest* test)
@@ -58,6 +72,7 @@ public:
     ContextMenuTest()
         : m_menuPositionX(0)
         , m_menuPositionY(0)
+        , m_expectedEventType(GDK_BUTTON_PRESS)
     {
         g_signal_connect(m_webView, "context-menu", G_CALLBACK(contextMenuCallback), this);
         g_signal_connect(m_webView, "context-menu-dismissed", G_CALLBACK(contextMenuDismissedCallback), this);
@@ -199,6 +214,7 @@ public:
 
     void showContextMenuAndWaitUntilFinished()
     {
+        m_expectedEventType = GDK_BUTTON_PRESS;
         showContextMenuAtPositionAndWaitUntilFinished(0, 0);
     }
 
@@ -214,8 +230,35 @@ public:
         g_main_loop_run(m_mainLoop);
     }
 
+    static gboolean emitPopupMenuSignalIdleCallback(ContextMenuTest* test)
+    {
+        test->emitPopupMenuSignal();
+        return FALSE;
+    }
+
+    void showContextMenuTriggeredByPopupEventAndWaitUntilFinished()
+    {
+        m_expectedEventType = GDK_NOTHING;
+        g_idle_add(reinterpret_cast<GSourceFunc>(emitPopupMenuSignalIdleCallback), this);
+        g_main_loop_run(m_mainLoop);
+    }
+
+    static gboolean simulateMenuKeyIdleCallback(ContextMenuTest* test)
+    {
+        test->keyStroke(GDK_KEY_Menu);
+        return FALSE;
+    }
+
+    void showContextMenuTriggeredByContextMenuKeyAndWaitUntilFinished()
+    {
+        m_expectedEventType = GDK_KEY_PRESS;
+        g_idle_add(reinterpret_cast<GSourceFunc>(simulateMenuKeyIdleCallback), this);
+        g_main_loop_run(m_mainLoop);
+    }
+
     double m_menuPositionX;
     double m_menuPositionY;
+    GdkEventType m_expectedEventType;
 };
 
 class ContextMenuDefaultTest: public ContextMenuTest {
@@ -365,10 +408,8 @@ public:
     DefaultMenuType m_expectedMenuType;
 };
 
-static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpointer)
+static void prepareContextMenuTestView(ContextMenuDefaultTest* test)
 {
-    test->showInWindowAndWaitUntilMapped();
-
     GUniquePtr<char> baseDir(g_strdup_printf("file://%s/", Test::getResourcesDir().data()));
     const char* linksHTML =
         "<html><body>"
@@ -388,6 +429,13 @@ static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpoint
         "</body></html>";
     test->loadHtml(linksHTML, baseDir.get());
     test->waitUntilLoadFinished();
+}
+
+static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpointer)
+{
+    test->showInWindowAndWaitUntilMapped();
+
+    prepareContextMenuTestView(test);
 
     // Context menu for selection.
     // This test should always be the first because any other click removes the selection.
@@ -427,6 +475,26 @@ static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpoint
     test->showContextMenuAtPositionAndWaitUntilFinished(5, 35);
 }
 
+static void testPopupEventSignal(ContextMenuDefaultTest* test, gconstpointer)
+{
+    test->showInWindowAndWaitUntilMapped();
+
+    prepareContextMenuTestView(test);
+
+    test->m_expectedMenuType = ContextMenuDefaultTest::Selection;
+    test->showContextMenuTriggeredByPopupEventAndWaitUntilFinished();
+}
+
+static void testContextMenuKey(ContextMenuDefaultTest* test, gconstpointer)
+{
+    test->showInWindowAndWaitUntilMapped();
+
+    prepareContextMenuTestView(test);
+
+    test->m_expectedMenuType = ContextMenuDefaultTest::Selection;
+    test->showContextMenuTriggeredByContextMenuKeyAndWaitUntilFinished();
+}
+
 class ContextMenuCustomTest: public ContextMenuTest {
 public:
     MAKE_GLIB_TEST_FIXTURE(ContextMenuCustomTest);
@@ -917,6 +985,8 @@ static void testContextMenuWebExtensionNode(ContextMenuWebExtensionNodeTest* tes
 void beforeAll()
 {
     ContextMenuDefaultTest::add("WebKitWebView", "default-menu", testContextMenuDefaultMenu);
+    ContextMenuDefaultTest::add("WebKitWebView", "context-menu-key", testContextMenuKey);
+    ContextMenuDefaultTest::add("WebKitWebView", "popup-event-signal", testPopupEventSignal);
     ContextMenuCustomTest::add("WebKitWebView", "populate-menu", testContextMenuPopulateMenu);
     ContextMenuCustomFullTest::add("WebKitWebView", "custom-menu", testContextMenuCustomMenu);
     ContextMenuDisabledTest::add("WebKitWebView", "disable-menu", testContextMenuDisableMenu);
index 880d064..7071910 100644 (file)
@@ -333,6 +333,15 @@ void WebViewTest::clickMouseButton(int x, int y, unsigned button, unsigned mouse
     doMouseButtonEvent(GDK_BUTTON_RELEASE, x, y, button, mouseModifiers);
 }
 
+void WebViewTest::emitPopupMenuSignal()
+{
+    GtkWidget* viewWidget = GTK_WIDGET(m_webView);
+    g_assert(gtk_widget_get_realized(viewWidget));
+
+    gboolean handled;
+    g_signal_emit_by_name(viewWidget, "popup-menu", &handled);
+}
+
 void WebViewTest::keyStroke(unsigned keyVal, unsigned keyModifiers)
 {
     g_assert(m_parentWindow);
index 4f0c4c7..cfcc6c7 100644 (file)
@@ -63,6 +63,8 @@ public:
     void clickMouseButton(int x, int y, unsigned button = 1, unsigned mouseModifiers = 0);
     void keyStroke(unsigned keyVal, unsigned keyModifiers = 0);
 
+    void emitPopupMenuSignal();
+
     WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**);
     WebKitJavascriptResult* runJavaScriptFromGResourceAndWaitUntilFinished(const char* resource, GError**);