Changeset 206505 in webkit


Ignore:
Timestamp:
Sep 28, 2016 12:49:05 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] Switch to use GMenu internally in the context menu implementation
https://bugs.webkit.org/show_bug.cgi?id=162603

Reviewed by Michael Catanzaro.

Source/WebKit2:

Switch to use GAction instead of GtkAction internally, but still keeping a GtkAction associated to the GAction,
because our API depends on GtkAction.

  • Shared/gtk/WebContextMenuItemGtk.cpp:

(WebKit::WebContextMenuItemGtk::WebContextMenuItemGtk):
(WebKit::WebContextMenuItemGtk::createActionIfNeeded): Create the GAction and the associated GtkAction. Ensure a
unique name for the GAction, since the name now matters.

  • Shared/gtk/WebContextMenuItemGtk.h:

(WebKit::WebContextMenuItemGtk::gtkAction):
(WebKit::WebContextMenuItemGtk::gAction):
(WebKit::WebContextMenuItemGtk::submenuItems): Deleted.

  • UIProcess/gtk/WebContextMenuProxyGtk.cpp:

(WebKit::contextMenuItemActivatedCallback): Use the GAction.
(WebKit::WebContextMenuProxyGtk::append): Create a new GMenuItem for the GAction.
(WebKit::WebContextMenuProxyGtk::buildMenu): Build a GMenu for the given items.
(WebKit::WebContextMenuProxyGtk::populate): Create a GMenu and bind it ot the GtkMenu.
(WebKit::WebContextMenuProxyGtk::WebContextMenuProxyGtk): Create the GActionGroup for the menu.
(WebKit::WebContextMenuProxyGtk::~WebContextMenuProxyGtk): Remove the action group from the GtkMenu.

  • UIProcess/gtk/WebContextMenuProxyGtk.h:

Tools:

Remove smart separators test, since that's now done automatically by GTK+.

  • TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp:

(beforeAll):
(testContextMenuWebExtensionMenu): Deleted.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r206479 r206505  
     12016-09-28  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Switch to use GMenu internally in the context menu implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=162603
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Switch to use GAction instead of GtkAction internally, but still keeping a GtkAction associated to the GAction,
     9        because our API depends on GtkAction.
     10
     11        * Shared/gtk/WebContextMenuItemGtk.cpp:
     12        (WebKit::WebContextMenuItemGtk::WebContextMenuItemGtk):
     13        (WebKit::WebContextMenuItemGtk::createActionIfNeeded): Create the GAction and the associated GtkAction. Ensure a
     14        unique name for the GAction, since the name now matters.
     15        * Shared/gtk/WebContextMenuItemGtk.h:
     16        (WebKit::WebContextMenuItemGtk::gtkAction):
     17        (WebKit::WebContextMenuItemGtk::gAction):
     18        (WebKit::WebContextMenuItemGtk::submenuItems): Deleted.
     19        * UIProcess/gtk/WebContextMenuProxyGtk.cpp:
     20        (WebKit::contextMenuItemActivatedCallback): Use the GAction.
     21        (WebKit::WebContextMenuProxyGtk::append): Create a new GMenuItem for the GAction.
     22        (WebKit::WebContextMenuProxyGtk::buildMenu): Build a GMenu for the given items.
     23        (WebKit::WebContextMenuProxyGtk::populate): Create a GMenu and bind it ot the GtkMenu.
     24        (WebKit::WebContextMenuProxyGtk::WebContextMenuProxyGtk): Create the GActionGroup for the menu.
     25        (WebKit::WebContextMenuProxyGtk::~WebContextMenuProxyGtk): Remove the action group from the GtkMenu.
     26        * UIProcess/gtk/WebContextMenuProxyGtk.h:
     27
    1282016-09-27  Daniel Bates  <dabates@apple.com>
    229
  • trunk/Source/WebKit2/Shared/gtk/WebContextMenuItemGtk.cpp

    r194496 r206505  
    123123{
    124124    ASSERT(type != SubmenuType);
    125     createGtkActionIfNeeded();
     125    createActionIfNeeded();
    126126}
    127127
     
    129129    : WebContextMenuItemData(data.type() == SubmenuType ? ActionType : data.type(), data.action(), data.title(), data.enabled(), data.checked())
    130130{
    131     createGtkActionIfNeeded();
     131    createActionIfNeeded();
    132132}
    133133
     
    135135    : WebContextMenuItemData(ActionType, data.action(), data.title(), data.enabled(), false)
    136136{
    137     m_action = data.gtkAction();
     137    m_gAction = G_SIMPLE_ACTION(data.gAction());
     138    m_gtkAction = data.gtkAction();
    138139    m_submenuItems = WTFMove(submenu);
    139140}
     
    142143    : WebContextMenuItemData(GTK_IS_TOGGLE_ACTION(action) ? CheckableActionType : ActionType, ContextMenuItemBaseApplicationTag, String::fromUTF8(gtk_action_get_label(action)), gtk_action_get_sensitive(action), GTK_IS_TOGGLE_ACTION(action) ? gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)) : false)
    143144{
    144     m_action = action;
     145    m_gtkAction = action;
     146    createActionIfNeeded();
     147    g_object_set_data_full(G_OBJECT(m_gAction.get()), "webkit-gtk-action", g_object_ref(m_gtkAction), g_object_unref);
    145148}
    146149
     
    149152}
    150153
    151 void WebContextMenuItemGtk::createGtkActionIfNeeded()
     154void WebContextMenuItemGtk::createActionIfNeeded()
    152155{
    153156    if (type() == SeparatorType)
    154157        return;
    155158
    156     GUniquePtr<char> actionName(g_strdup_printf("context-menu-action-%d", action()));
    157     if (type() == CheckableActionType) {
    158         m_action = adoptGRef(GTK_ACTION(gtk_toggle_action_new(actionName.get(), title().utf8().data(), nullptr, gtkStockIDFromContextMenuAction(action()))));
    159         gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(m_action.get()), checked());
    160     } else
    161         m_action = adoptGRef(gtk_action_new(actionName.get(), title().utf8().data(), 0, gtkStockIDFromContextMenuAction(action())));
    162     gtk_action_set_sensitive(m_action.get(), enabled());
     159    static uint64_t actionID = 0;
     160    GUniquePtr<char> actionName(g_strdup_printf("action-%" PRIu64, ++actionID));
     161    if (type() == CheckableActionType)
     162        m_gAction = adoptGRef(g_simple_action_new_stateful(actionName.get(), nullptr, g_variant_new_boolean(checked())));
     163    else
     164        m_gAction = adoptGRef(g_simple_action_new(actionName.get(), nullptr));
     165    g_simple_action_set_enabled(m_gAction.get(), enabled());
     166
     167    // Create the GtkAction for backwards compatibility only.
     168    if (!m_gtkAction) {
     169        if (type() == CheckableActionType) {
     170            m_gtkAction = GTK_ACTION(gtk_toggle_action_new(actionName.get(), title().utf8().data(), nullptr, gtkStockIDFromContextMenuAction(action())));
     171            gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(m_gtkAction), checked());
     172        } else
     173            m_gtkAction = gtk_action_new(actionName.get(), title().utf8().data(), 0, gtkStockIDFromContextMenuAction(action()));
     174        gtk_action_set_sensitive(m_gtkAction, enabled());
     175        g_object_set_data_full(G_OBJECT(m_gAction.get()), "webkit-gtk-action", m_gtkAction, g_object_unref);
     176    }
     177
     178    g_signal_connect_object(m_gAction.get(), "activate", G_CALLBACK(gtk_action_activate), m_gtkAction, G_CONNECT_SWAPPED);
    163179}
    164180
  • trunk/Source/WebKit2/Shared/gtk/WebContextMenuItemGtk.h

    r192881 r206505  
    3232
    3333typedef struct _GtkAction GtkAction;
     34typedef struct _GAction GAction;
     35typedef struct _GSimpleAction GSimpleAction;
    3436
    3537namespace WebKit {
     
    4648    // We don't use the SubmenuType internally, so check if we have submenu items.
    4749    WebCore::ContextMenuItemType type() const { return m_submenuItems.isEmpty() ? WebContextMenuItemData::type() : WebCore::SubmenuType; }
    48     GtkAction* gtkAction() const { return m_action.get(); }
     50    GtkAction* gtkAction() const { return m_gtkAction; }
     51    GAction* gAction() const { return reinterpret_cast<GAction*>(m_gAction.get()); }
    4952    const Vector<WebContextMenuItemGtk>& submenuItems() const { return m_submenuItems; }
    5053
    5154private:
    52     void createGtkActionIfNeeded();
     55    void createActionIfNeeded();
    5356
    54     GRefPtr<GtkAction> m_action;
     57    GRefPtr<GSimpleAction> m_gAction;
     58    GtkAction* m_gtkAction { nullptr };
    5559    Vector<WebContextMenuItemGtk> m_submenuItems;
    5660};
  • trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp

    r192247 r206505  
    3737#include "WebProcessProxy.h"
    3838#include <WebCore/GtkUtilities.h>
     39#include <gio/gio.h>
    3940#include <gtk/gtk.h>
    4041#include <wtf/text/CString.h>
    4142
    42 
    4343static const char* gContextMenuActionId = "webkit-context-menu-action";
     44static const char* gContextMenuTitle = "webkit-context-menu-title";
     45static const char* gContextMenuItemGroup = "webkitContextMenu";
    4446
    4547using namespace WebCore;
     
    4749namespace WebKit {
    4850
    49 static void contextMenuItemActivatedCallback(GtkAction* action, WebPageProxy* page)
    50 {
    51     gboolean isToggle = GTK_IS_TOGGLE_ACTION(action);
     51static void contextMenuItemActivatedCallback(GAction* action, GVariant*, WebPageProxy* page)
     52{
     53    auto* stateType = g_action_get_state_type(action);
     54    gboolean isToggle = stateType && g_variant_type_equal(stateType, G_VARIANT_TYPE_BOOLEAN);
     55    GRefPtr<GVariant> state = isToggle ? adoptGRef(g_action_get_state(action)) : nullptr;
    5256    WebContextMenuItemData item(isToggle ? CheckableActionType : ActionType,
    5357        static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), gContextMenuActionId))),
    54         String::fromUTF8(gtk_action_get_label(action)), gtk_action_get_sensitive(action),
    55         isToggle ? gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)) : false);
     58        String::fromUTF8(static_cast<const char*>(g_object_get_data(G_OBJECT(action), gContextMenuTitle))), g_action_get_enabled(action),
     59        state ? g_variant_get_boolean(state.get()) : false);
    5660    page->contextMenuItemSelected(item);
    5761}
    5862
    59 static void contextMenuItemVisibilityChanged(GtkAction*, GParamSpec*, WebContextMenuProxyGtk* contextMenuProxy)
    60 {
    61     GtkMenu* menu = contextMenuProxy->gtkMenu();
    62     if (!menu)
    63         return;
    64 
    65     GUniquePtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu)));
    66     bool previousVisibleItemIsNotASeparator = false;
    67     GtkWidget* lastItemVisibleSeparator = 0;
    68     for (GList* iter = items.get(); iter; iter = g_list_next(iter)) {
    69         GtkWidget* widget = GTK_WIDGET(iter->data);
    70 
    71         if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) {
    72             if (previousVisibleItemIsNotASeparator) {
    73                 gtk_widget_show(widget);
    74                 lastItemVisibleSeparator = widget;
    75                 previousVisibleItemIsNotASeparator = false;
    76             } else
    77                 gtk_widget_hide(widget);
    78         } else if (gtk_widget_get_visible(widget)) {
    79             lastItemVisibleSeparator = 0;
    80             previousVisibleItemIsNotASeparator = true;
     63void WebContextMenuProxyGtk::append(GMenu* menu, const WebContextMenuItemGtk& menuItem)
     64{
     65    unsigned long signalHandlerId;
     66    GRefPtr<GMenuItem> gMenuItem;
     67    GAction* action = menuItem.gAction();
     68    ASSERT(action);
     69    g_action_map_add_action(G_ACTION_MAP(gtk_widget_get_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup)), action);
     70
     71    switch (menuItem.type()) {
     72    case ActionType:
     73    case CheckableActionType: {
     74        GUniquePtr<char> actionName(g_strdup_printf("%s.%s", gContextMenuItemGroup, g_action_get_name(action)));
     75        gMenuItem = adoptGRef(g_menu_item_new(menuItem.title().utf8().data(), nullptr));
     76        g_menu_item_set_action_and_target_value(gMenuItem.get(), actionName.get(), nullptr);
     77
     78        g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action()));
     79        g_object_set_data_full(G_OBJECT(action), gContextMenuTitle, g_strdup(menuItem.title().utf8().data()), g_free);
     80        signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page);
     81        m_signalHandlers.set(signalHandlerId, action);
     82        break;
     83    }
     84    case SubmenuType: {
     85        GRefPtr<GMenu> submenu = buildMenu(menuItem.submenuItems());
     86        gMenuItem = adoptGRef(g_menu_item_new_submenu(menuItem.title().utf8().data(), G_MENU_MODEL(submenu.get())));
     87        break;
     88    }
     89    case SeparatorType:
     90        ASSERT_NOT_REACHED();
     91        break;
     92    }
     93
     94    g_menu_append_item(menu, gMenuItem.get());
     95}
     96
     97GRefPtr<GMenu> WebContextMenuProxyGtk::buildMenu(const Vector<WebContextMenuItemGtk>& items)
     98{
     99    GRefPtr<GMenu> menu = adoptGRef(g_menu_new());
     100    GMenu* sectionMenu = menu.get();
     101    for (const auto& item : items) {
     102        if (item.type() == SeparatorType) {
     103            GRefPtr<GMenu> section = adoptGRef(g_menu_new());
     104            g_menu_append_section(menu.get(), nullptr, G_MENU_MODEL(section.get()));
     105            sectionMenu = section.get();
     106        } else
     107            append(sectionMenu, item);
     108    }
     109
     110    return menu;
     111}
     112
     113void WebContextMenuProxyGtk::populate(const Vector<WebContextMenuItemGtk>& items)
     114{
     115    GRefPtr<GMenu> menu = buildMenu(items);
     116    gtk_menu_shell_bind_model(GTK_MENU_SHELL(m_menu), G_MENU_MODEL(menu.get()), nullptr, TRUE);
     117}
     118
     119void WebContextMenuProxyGtk::populate(const Vector<RefPtr<WebContextMenuItem>>& items)
     120{
     121    GRefPtr<GMenu> menu = adoptGRef(g_menu_new());
     122    GMenu* sectionMenu = menu.get();
     123    for (const auto& item : items) {
     124        if (item->data().type() == SeparatorType) {
     125            GRefPtr<GMenu> section = adoptGRef(g_menu_new());
     126            g_menu_append_section(menu.get(), nullptr, G_MENU_MODEL(section.get()));
     127            sectionMenu = section.get();
     128        } else {
     129            WebContextMenuItemGtk menuitem(item->data());
     130            append(sectionMenu, menuitem);
    81131        }
    82132    }
    83 
    84     if (lastItemVisibleSeparator)
    85         gtk_widget_hide(lastItemVisibleSeparator);
    86 }
    87 
    88 void WebContextMenuProxyGtk::append(GtkMenu* menu, const WebContextMenuItemGtk& menuItem)
    89 {
    90     unsigned long signalHandlerId;
    91     GtkWidget* gtkMenuItem;
    92     if (GtkAction* action = menuItem.gtkAction()) {
    93         gtkMenuItem = gtk_action_create_menu_item(action);
    94 
    95         switch (menuItem.type()) {
    96         case ActionType:
    97         case CheckableActionType:
    98             g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action()));
    99             signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page);
    100             m_signalHandlers.set(signalHandlerId, action);
    101             signalHandlerId = g_signal_connect(action, "notify::visible", G_CALLBACK(contextMenuItemVisibilityChanged), this);
    102             m_signalHandlers.set(signalHandlerId, action);
    103             break;
    104         case SubmenuType: {
    105             signalHandlerId = g_signal_connect(action, "notify::visible", G_CALLBACK(contextMenuItemVisibilityChanged), this);
    106             m_signalHandlers.set(signalHandlerId, action);
    107             GtkMenu* submenu = GTK_MENU(gtk_menu_new());
    108             for (const auto& item : menuItem.submenuItems())
    109                 append(submenu, item);
    110             gtk_menu_item_set_submenu(GTK_MENU_ITEM(gtkMenuItem), GTK_WIDGET(submenu));
    111             break;
    112         }
    113         case SeparatorType:
    114             ASSERT_NOT_REACHED();
    115             break;
    116         }
    117     } else {
    118         ASSERT(menuItem.type() == SeparatorType);
    119         gtkMenuItem = gtk_separator_menu_item_new();
    120     }
    121 
    122     gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkMenuItem);
    123     gtk_widget_show(gtkMenuItem);
    124 }
    125 
    126 // Populate the context menu ensuring that:
    127 //  - There aren't separators next to each other.
    128 //  - There aren't separators at the beginning of the menu.
    129 //  - There aren't separators at the end of the menu.
    130 void WebContextMenuProxyGtk::populate(Vector<WebContextMenuItemGtk>& items)
    131 {
    132     bool previousIsSeparator = false;
    133     bool isEmpty = true;
    134     for (size_t i = 0; i < items.size(); i++) {
    135         WebContextMenuItemGtk& menuItem = items.at(i);
    136         if (menuItem.type() == SeparatorType) {
    137             previousIsSeparator = true;
    138             continue;
    139         }
    140 
    141         if (previousIsSeparator && !isEmpty)
    142             append(m_menu, items.at(i - 1));
    143         previousIsSeparator = false;
    144 
    145         append(m_menu, menuItem);
    146         isEmpty = false;
    147     }
    148 }
    149 
    150 void WebContextMenuProxyGtk::populate(const Vector<RefPtr<WebContextMenuItem>>& items)
    151 {
    152     for (const auto& item : items) {
    153         WebContextMenuItemGtk menuitem(item->data());
    154         append(m_menu, menuitem);
    155     }
     133    gtk_menu_shell_bind_model(GTK_MENU_SHELL(m_menu), G_MENU_MODEL(menu.get()), nullptr, TRUE);
    156134}
    157135
     
    196174    , m_menu(GTK_MENU(gtk_menu_new()))
    197175{
     176    GRefPtr<GSimpleActionGroup> group = adoptGRef(g_simple_action_group_new());
     177    gtk_widget_insert_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup, G_ACTION_GROUP(group.get()));
    198178    webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), this);
    199179}
     
    207187    m_signalHandlers.clear();
    208188
     189    gtk_widget_insert_action_group(GTK_WIDGET(m_menu), "webkitContextMenu", nullptr);
    209190    gtk_widget_destroy(GTK_WIDGET(m_menu));
    210191}
  • trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h

    r197563 r206505  
    3333#include <WebCore/IntPoint.h>
    3434#include <wtf/HashMap.h>
     35#include <wtf/glib/GRefPtr.h>
     36
     37typedef struct _GMenu GMenu;
    3538
    3639namespace WebKit {
     
    4548    ~WebContextMenuProxyGtk();
    4649
    47     void populate(Vector<WebContextMenuItemGtk>&);
     50    void populate(const Vector<WebContextMenuItemGtk>&);
    4851    GtkMenu* gtkMenu() const { return m_menu; }
    4952
    5053private:
    5154    void show() override;
    52     void append(GtkMenu*, const WebContextMenuItemGtk&);
     55    void append(GMenu*, const WebContextMenuItemGtk&);
     56    GRefPtr<GMenu> buildMenu(const Vector<WebContextMenuItemGtk>&);
    5357    void populate(const Vector<RefPtr<WebContextMenuItem>>&);
    5458    static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, WebContextMenuProxyGtk*);
     
    5862    GtkMenu* m_menu;
    5963    WebCore::IntPoint m_popupPosition;
    60     HashMap<unsigned long, GtkAction*> m_signalHandlers;
     64    HashMap<unsigned long, void*> m_signalHandlers;
    6165};
    6266
  • trunk/Tools/ChangeLog

    r206480 r206505  
     12016-09-28  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Switch to use GMenu internally in the context menu implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=162603
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Remove smart separators test, since that's now done automatically by GTK+.
     9
     10        * TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp:
     11        (beforeAll):
     12        (testContextMenuWebExtensionMenu): Deleted.
     13
    1142016-09-27  Alex Christensen  <achristensen@webkit.org>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp

    r206382 r206505  
    762762}
    763763
    764 class ContextMenuSmartSeparatorsTest: public ContextMenuTest {
    765 public:
    766     MAKE_GLIB_TEST_FIXTURE(ContextMenuSmartSeparatorsTest);
    767 
    768     bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*)
    769     {
    770         webkit_context_menu_remove_all(contextMenu);
    771 
    772         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    773         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    774         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_BACK));
    775         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD));
    776         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    777         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    778         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_COPY));
    779         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    780         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT));
    781         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    782         webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator());
    783 
    784         quitMainLoop();
    785 
    786         return false;
    787     }
    788 
    789     GtkMenu* showContextMenuAndGetGtkMenu()
    790     {
    791         showContextMenuAndWaitUntilFinished();
    792         return getPopupMenu();
    793     }
    794 };
    795 
    796 static void testContextMenuSmartSeparators(ContextMenuSmartSeparatorsTest* test, gconstpointer)
    797 {
    798     test->showInWindowAndWaitUntilMapped();
    799 
    800     test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///");
    801     test->waitUntilLoadFinished();
    802 
    803     GtkMenu* menu = test->showContextMenuAndGetGtkMenu();
    804     g_assert(menu);
    805 
    806     // Leading and trailing separators are not added to the context menu.
    807     GUniquePtr<GList> menuItems(gtk_container_get_children(GTK_CONTAINER(menu)));
    808     g_assert_cmpuint(g_list_length(menuItems.get()), ==, 6);
    809     GtkWidget* item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0));
    810     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    811     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1));
    812     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    813     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2));
    814     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    815     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3));
    816     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    817     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4));
    818     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    819     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5));
    820     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    821 
    822     // Hiding a menu item between two separators hides the following separator.
    823     GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(g_list_nth_data(menuItems.get(), 3)));
    824     gtk_action_set_visible(action, FALSE);
    825     menuItems.reset(gtk_container_get_children(GTK_CONTAINER(menu)));
    826     g_assert_cmpuint(g_list_length(menuItems.get()), ==, 6);
    827     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0));
    828     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    829     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1));
    830     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    831     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2));
    832     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    833     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3));
    834     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item));
    835     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4));
    836     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item));
    837     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5));
    838     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    839     gtk_action_set_visible(action, TRUE);
    840 
    841     // Showing an action between two separators shows the hidden separator.
    842     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0));
    843     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    844     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1));
    845     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    846     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2));
    847     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    848     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3));
    849     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    850     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4));
    851     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    852     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5));
    853     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    854 
    855     // Trailing separators are hidden too.
    856     action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(g_list_nth_data(menuItems.get(), 5)));
    857     gtk_action_set_visible(action, FALSE);
    858     menuItems.reset(gtk_container_get_children(GTK_CONTAINER(menu)));
    859     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0));
    860     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    861     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1));
    862     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    863     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2));
    864     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    865     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3));
    866     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item));
    867     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4));
    868     g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item));
    869     item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5));
    870     g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item));
    871 }
    872 
    873764class ContextMenuWebExtensionTest: public ContextMenuTest {
    874765public:
     
    1034925    ContextMenuSubmenuTest::add("WebKitWebView", "submenu", testContextMenuSubMenu);
    1035926    ContextMenuDismissedTest::add("WebKitWebView", "menu-dismissed", testContextMenuDismissed);
    1036     ContextMenuSmartSeparatorsTest::add("WebKitWebView", "smart-separators", testContextMenuSmartSeparators);
    1037927    ContextMenuWebExtensionTest::add("WebKitWebPage", "context-menu", testContextMenuWebExtensionMenu);
    1038928    ContextMenuWebExtensionNodeTest::add("WebKitWebPage", "context-menu-node", testContextMenuWebExtensionNode);
Note: See TracChangeset for help on using the changeset viewer.