Changeset 74028 in webkit


Ignore:
Timestamp:
Dec 14, 2010 8:25:19 AM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2010-12-14 Carlos Garcia Campos <cgarcia@igalia.com>

Reviewed by Martin Robinson.

[GTK] Simplify context-menu handling code
https://bugs.webkit.org/show_bug.cgi?id=49658

  • wtf/PlatformRefPtr.h: Add leakRef()

2010-12-14 Carlos Garcia Campos <cgarcia@igalia.com>

Reviewed by Martin Robinson.

[GTK] Simplify context-menu handling code
https://bugs.webkit.org/show_bug.cgi?id=49658

  • platform/ContextMenuItem.h:
  • platform/gtk/ContextMenuGtk.cpp: (WebCore::ContextMenu::appendItem):
  • platform/gtk/ContextMenuItemGtk.cpp: (WebCore::ContextMenuItem::ContextMenuItem): (WebCore::ContextMenuItem::~ContextMenuItem): (WebCore::ContextMenuItem::releasePlatformDescription): (WebCore::ContextMenuItem::type): (WebCore::ContextMenuItem::setType): (WebCore::ContextMenuItem::action): (WebCore::ContextMenuItem::setAction): (WebCore::ContextMenuItem::title): (WebCore::ContextMenuItem::setTitle): (WebCore::ContextMenuItem::platformSubMenu): (WebCore::ContextMenuItem::setSubMenu): (WebCore::ContextMenuItem::setChecked): (WebCore::ContextMenuItem::setEnabled):

2010-12-14 Carlos Garcia Campos <cgarcia@igalia.com>

Reviewed by Martin Robinson.

[GTK] Simplify context-menu handling code
https://bugs.webkit.org/show_bug.cgi?id=49658

Use gtk_container_foreach() so that we only iterate the list of
children once and we avoid creating/destroying the list. It also
connects the activate signal for submenu items.

  • webkit/webkitwebview.cpp: (contextMenuConnectActivate): (webkit_web_view_forward_context_menu_event):
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r73981 r74028  
     12010-12-14  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        Reviewed by Martin Robinson.
     4
     5        [GTK] Simplify context-menu handling code
     6        https://bugs.webkit.org/show_bug.cgi?id=49658
     7
     8        * wtf/PlatformRefPtr.h: Add leakRef()
     9
    1102010-12-13  Cameron Zwarich  <zwarich@apple.com>
    211
  • trunk/JavaScriptCore/wtf/PlatformRefPtr.h

    r73746 r74028  
    7373        if (ptr)
    7474            derefPlatformPtr(ptr);
     75    }
     76
     77    T* leakRef() WARN_UNUSED_RETURN
     78    {
     79        T* ptr = m_ptr;
     80        m_ptr = 0;
     81        return ptr;
    7582    }
    7683
  • trunk/WebCore/ChangeLog

    r74025 r74028  
     12010-12-14  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        Reviewed by Martin Robinson.
     4
     5        [GTK] Simplify context-menu handling code
     6        https://bugs.webkit.org/show_bug.cgi?id=49658
     7
     8        * platform/ContextMenuItem.h:
     9        * platform/gtk/ContextMenuGtk.cpp:
     10        (WebCore::ContextMenu::appendItem):
     11        * platform/gtk/ContextMenuItemGtk.cpp:
     12        (WebCore::ContextMenuItem::ContextMenuItem):
     13        (WebCore::ContextMenuItem::~ContextMenuItem):
     14        (WebCore::ContextMenuItem::releasePlatformDescription):
     15        (WebCore::ContextMenuItem::type):
     16        (WebCore::ContextMenuItem::setType):
     17        (WebCore::ContextMenuItem::action):
     18        (WebCore::ContextMenuItem::setAction):
     19        (WebCore::ContextMenuItem::title):
     20        (WebCore::ContextMenuItem::setTitle):
     21        (WebCore::ContextMenuItem::platformSubMenu):
     22        (WebCore::ContextMenuItem::setSubMenu):
     23        (WebCore::ContextMenuItem::setChecked):
     24        (WebCore::ContextMenuItem::setEnabled):
     25
    1262010-12-14  Mario Sanchez Prada  <msanchez@igalia.com>
    227
  • trunk/WebCore/platform/ContextMenuItem.h

    r73802 r74028  
    4343typedef struct tagMENUITEMINFOW MENUITEMINFO;
    4444#elif PLATFORM(GTK)
     45#include <GRefPtr.h>
    4546typedef struct _GtkMenuItem GtkMenuItem;
    4647#elif PLATFORM(QT)
     
    184185    };
    185186#elif PLATFORM(GTK)
    186     struct PlatformMenuItemDescription {
    187         PlatformMenuItemDescription()
    188             : type(ActionType)
    189             , action(ContextMenuItemTagNoAction)
    190             , subMenu(0)
    191             , checked(false)
    192             , enabled(true)
    193         {}
    194 
    195         ContextMenuItemType type;
    196         ContextMenuAction action;
    197         String title;
    198         GtkMenu* subMenu;
    199         bool checked;
    200         bool enabled;
    201     };
     187    typedef GtkMenuItem* PlatformMenuItemDescription;
    202188#elif PLATFORM(WX)
    203189    struct PlatformMenuItemDescription {
     
    293279        ContextMenuItem(ContextMenuAction, const String&, bool enabled, bool checked, Vector<ContextMenuItem>& submenuItems);
    294280
    295 #if PLATFORM(GTK)
    296         ContextMenuItem(GtkMenuItem*);
    297 #endif
    298 
    299281        PlatformMenuItemDescription releasePlatformDescription();
    300282
     
    305287        void setSubMenu(Vector<ContextMenuItem>&);
    306288
    307         // FIXME: Do we need a keyboard accelerator here?
    308 #if PLATFORM(GTK)
    309         static GtkMenuItem* createNativeMenuItem(const PlatformMenuItemDescription&);
    310 #endif
    311289#endif // USE(CROSS_PLATFORM_CONTEXT_MENUS)
    312 
    313290    private:
    314291#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
     
    322299#if PLATFORM(MAC)
    323300        RetainPtr<NSMenuItem> m_platformDescription;
     301#elif PLATFORM(GTK)
     302        PlatformRefPtr<GtkMenuItem> m_platformDescription;
    324303#else
    325304        PlatformMenuItemDescription m_platformDescription;
  • trunk/WebCore/platform/gtk/ContextMenuGtk.cpp

    r73746 r74028  
    4141    ASSERT(m_platformDescription);
    4242
    43     GtkMenuItem* platformItem = ContextMenuItem::createNativeMenuItem(item.releasePlatformDescription());
     43    GtkMenuItem* platformItem = item.releasePlatformDescription();
    4444    ASSERT(platformItem);
    4545    gtk_menu_shell_append(GTK_MENU_SHELL(m_platformDescription), GTK_WIDGET(platformItem));
  • trunk/WebCore/platform/gtk/ContextMenuItemGtk.cpp

    r73746 r74028  
    1919
    2020#include "config.h"
     21
     22#include "ContextMenuItem.h"
     23
    2124#include "ContextMenu.h"
    22 #include "ContextMenuItem.h"
     25#include "GOwnPtr.h"
    2326#include "NotImplemented.h"
     27#include <gtk/gtk.h>
    2428#include <wtf/text/CString.h>
    25 
    26 #include <gtk/gtk.h>
    2729
    2830#define WEBKIT_CONTEXT_MENU_ACTION "webkit-context-menu"
     
    115117
    116118// Extract the ActionType from the menu item
    117 ContextMenuItem::ContextMenuItem(GtkMenuItem* item)
    118     : m_platformDescription()
    119 {
    120     if (GTK_IS_SEPARATOR_MENU_ITEM(item))
    121         m_platformDescription.type = SeparatorType;
    122     else if (gtk_menu_item_get_submenu(item))
    123         m_platformDescription.type = SubmenuType;
    124     else if (GTK_IS_CHECK_MENU_ITEM(item)) {
    125         m_platformDescription.type = CheckableActionType;
    126         m_platformDescription.checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
    127     } else
    128         m_platformDescription.type = ActionType;
    129 #if GTK_CHECK_VERSION (2, 16, 0)
    130     m_platformDescription.title = String::fromUTF8(gtk_menu_item_get_label(GTK_MENU_ITEM(item)));
    131 #else
    132     GtkWidget* label = gtk_bin_get_child(GTK_BIN(item));
    133     m_platformDescription.title = String::fromUTF8(gtk_label_get_label(GTK_LABEL(label)));
    134 #endif
    135 
    136     m_platformDescription.action = *static_cast<ContextMenuAction*>(g_object_get_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION));
    137 
    138     m_platformDescription.subMenu = GTK_MENU(gtk_menu_item_get_submenu(item));
    139     if (m_platformDescription.subMenu)
    140         g_object_ref(m_platformDescription.subMenu);
     119ContextMenuItem::ContextMenuItem(PlatformMenuItemDescription item)
     120    : m_platformDescription(item)
     121{
    141122}
    142123
     
    148129ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
    149130{
    150     m_platformDescription.type = type;
    151     m_platformDescription.action = action;
    152     m_platformDescription.title = title;
    153 
    154     setSubMenu(subMenu);
     131    if (type == SeparatorType) {
     132        m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new());
     133        return;
     134    }
     135
     136    GOwnPtr<char> actionName(g_strdup_printf("context-menu-action-%d", action));
     137    GtkAction* platformAction = 0;
     138
     139    if (type == CheckableActionType)
     140        platformAction = GTK_ACTION(gtk_toggle_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action)));
     141    else
     142        platformAction = gtk_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action));
     143
     144    m_platformDescription = GTK_MENU_ITEM(gtk_action_create_menu_item(platformAction));
     145    g_object_unref(platformAction);
     146
     147    g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
     148
     149    if (subMenu)
     150        setSubMenu(subMenu);
    155151}
    156152
    157153ContextMenuItem::~ContextMenuItem()
    158154{
    159     if (m_platformDescription.subMenu)
    160         g_object_unref(m_platformDescription.subMenu);
    161 }
    162 
    163 GtkMenuItem* ContextMenuItem::createNativeMenuItem(const PlatformMenuItemDescription& menu)
    164 {
    165     GtkMenuItem* item = 0;
    166     if (menu.type == SeparatorType)
    167         item = GTK_MENU_ITEM(gtk_separator_menu_item_new());
    168     else {
    169         if (menu.type == CheckableActionType) {
    170             item = GTK_MENU_ITEM(gtk_check_menu_item_new_with_mnemonic(menu.title.utf8().data()));
    171             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), menu.checked);
    172         } else {
    173             if (const gchar* stockID = gtkStockIDFromContextMenuAction(menu.action)) {
    174                 item = GTK_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(menu.title.utf8().data()));
    175                 GtkWidget* image = gtk_image_new_from_stock(stockID, GTK_ICON_SIZE_MENU);
    176                 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
    177             } else
    178                 item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(menu.title.utf8().data()));
    179         }
    180 
    181         ContextMenuAction* menuAction = static_cast<ContextMenuAction*>(malloc(sizeof(ContextMenuAction*)));
    182         *menuAction = menu.action;
    183         g_object_set_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION, menuAction);
    184 
    185         gtk_widget_set_sensitive(GTK_WIDGET(item), menu.enabled);
    186 
    187         if (menu.subMenu)
    188             gtk_menu_item_set_submenu(item, GTK_WIDGET(menu.subMenu));
    189     }
    190 
    191     return item;
    192155}
    193156
    194157PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription()
    195158{
    196     PlatformMenuItemDescription description = m_platformDescription;
    197     m_platformDescription = PlatformMenuItemDescription();
    198     return description;
     159    return m_platformDescription.leakRef();
    199160}
    200161
    201162ContextMenuItemType ContextMenuItem::type() const
    202163{
    203     return m_platformDescription.type;
     164    if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription.get()))
     165        return SeparatorType;
     166    if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription.get()))
     167        return CheckableActionType;
     168    if (gtk_menu_item_get_submenu(m_platformDescription.get()))
     169        return SubmenuType;
     170    return ActionType;
    204171}
    205172
    206173void ContextMenuItem::setType(ContextMenuItemType type)
    207174{
    208     m_platformDescription.type = type;
     175    if (type == SeparatorType)
     176        m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new());
    209177}
    210178
    211179ContextMenuAction ContextMenuItem::action() const
    212180{
    213     return m_platformDescription.action;
     181    return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION)));
    214182}
    215183
    216184void ContextMenuItem::setAction(ContextMenuAction action)
    217185{
    218     m_platformDescription.action = action;
     186    g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action));
    219187}
    220188
    221189String ContextMenuItem::title() const
    222190{
    223     return m_platformDescription.title;
     191    GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get()));
     192    return action ? String(gtk_action_get_label(action)) : String();
    224193}
    225194
    226195void ContextMenuItem::setTitle(const String& title)
    227196{
    228     m_platformDescription.title = title;
     197    GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get()));
     198    if (action)
     199        gtk_action_set_label(action, title.utf8().data());
    229200}
    230201
    231202PlatformMenuDescription ContextMenuItem::platformSubMenu() const
    232203{
    233     return m_platformDescription.subMenu;
     204    GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription.get());
     205    return subMenu ? GTK_MENU(subMenu) : 0;
    234206}
    235207
    236208void ContextMenuItem::setSubMenu(ContextMenu* menu)
    237209{
    238     if (m_platformDescription.subMenu)
    239         g_object_unref(m_platformDescription.subMenu);
    240 
    241     if (!menu)
    242         return;
    243 
    244     m_platformDescription.subMenu = menu->releasePlatformDescription();
    245     m_platformDescription.type = SubmenuType;
    246 
    247     g_object_ref_sink(G_OBJECT(m_platformDescription.subMenu));
     210    gtk_menu_item_set_submenu(m_platformDescription.get(), GTK_WIDGET(menu->platformDescription()));
    248211}
    249212
    250213void ContextMenuItem::setChecked(bool shouldCheck)
    251214{
    252     m_platformDescription.checked = shouldCheck;
     215    GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get()));
     216    if (action && GTK_IS_TOGGLE_ACTION(action))
     217        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), shouldCheck);
    253218}
    254219
    255220void ContextMenuItem::setEnabled(bool shouldEnable)
    256221{
    257     m_platformDescription.enabled = shouldEnable;
    258 }
    259 
    260 }
     222    GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get()));
     223    if (action)
     224        gtk_action_set_sensitive(action, shouldEnable);
     225}
     226
     227}
  • trunk/WebKit/gtk/ChangeLog

    r74026 r74028  
     12010-12-14  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        Reviewed by Martin Robinson.
     4
     5        [GTK] Simplify context-menu handling code
     6        https://bugs.webkit.org/show_bug.cgi?id=49658
     7
     8        Use gtk_container_foreach() so that we only iterate the list of
     9        children once and we avoid creating/destroying the list. It also
     10        connects the activate signal for submenu items.
     11
     12        * webkit/webkitwebview.cpp:
     13        (contextMenuConnectActivate):
     14        (webkit_web_view_forward_context_menu_event):
     15
    1162010-12-14  Carlos Garcia Campos  <cgarcia@igalia.com>
    217
  • trunk/WebKit/gtk/webkit/webkitwebview.cpp

    r74018 r74028  
    286286}
    287287
     288static void contextMenuConnectActivate(GtkMenuItem* item, ContextMenuController* controller)
     289{
     290    if (GTK_IS_SEPARATOR_MENU_ITEM(item))
     291        return;
     292
     293    if (GtkWidget* menu = gtk_menu_item_get_submenu(item)) {
     294        gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller);
     295        return;
     296    }
     297
     298    g_signal_connect(item, "activate", G_CALLBACK(contextMenuItemActivated), controller);
     299}
     300
    288301static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event)
    289302{
     
    347360    // We connect the "activate" signal here rather than in ContextMenuGtk to avoid
    348361    // a layering violation. ContextMenuGtk should not know about the ContextMenuController.
    349     // FIXME: This should handle submenu items.
     362    gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller);
     363
     364    g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, menu);
     365
     366    // If the context menu is now empty, don't show it.
    350367    GOwnPtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu)));
    351     GList* currentListItem = items.get();
    352     while (currentListItem) {
    353         GtkMenuItem* item = GTK_MENU_ITEM(currentListItem->data);
    354         if (!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_menu_item_get_submenu(item))
    355             g_signal_connect(item, "activate", G_CALLBACK(contextMenuItemActivated), controller);
    356         currentListItem = currentListItem->next;
    357     }
    358 
    359     g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, menu);
    360 
    361     // If the context menu is now empty, don't show it.
    362     items.set(gtk_container_get_children(GTK_CONTAINER(menu)));
    363368    if (!items)
    364369        return FALSE;
Note: See TracChangeset for help on using the changeset viewer.