[Libreoffice-commits] core.git: 2 commits - vcl/inc vcl/unx

Caolán McNamara caolanm at redhat.com
Fri May 6 10:23:27 UTC 2016


 vcl/inc/unx/gtk/gtksalmenu.hxx |   12 +-
 vcl/unx/gtk/gloactiongroup.cxx |   48 ++---------
 vcl/unx/gtk/gtksalframe.cxx    |    2 
 vcl/unx/gtk/gtksalmenu.cxx     |  165 +++++++++--------------------------------
 vcl/unx/gtk3/gtk3gtkframe.cxx  |    2 
 5 files changed, 59 insertions(+), 170 deletions(-)

New commits:
commit 27014f563577c3c5da19e37a57d4e73c0ebae140
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri May 6 11:18:50 2016 +0100

    Resolves: tdf#92067 and tdf#99599, use a foolproof action naming scheme
    
    encode the GtkSalMenu and the item id into the action_name so
    each one is unique and directly refers to the menu and item in the
    menu so knowing which one is which is direct and simple
    
    Change-Id: I81bb278e73946f864e29aeab884e07e16835dad3

diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 2e182e6..9bd0a77 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -54,7 +54,6 @@ private:
     GMenuModel*                     mpMenuModel;
     GActionGroup*                   mpActionGroup;
 
-    GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand, int& rDupsToSkip, gboolean bGetSubmenu );
     void                        ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries);
     void                        ActivateAllSubmenus(Menu* pMenuBar);
 
@@ -98,17 +97,18 @@ public:
     void                        NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck );
     void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const vcl::KeyCode& rKeyCode, const OUString& rKeyName );
 
-    void                        DispatchCommand( gint itemId, const gchar* aCommand );
     void                        ActivateAllSubmenus()
     {
         ActivateAllSubmenus(mpVCLMenu);
     }
-    void                        Activate( const gchar* aMenuCommand );
-    void                        Deactivate( const gchar* aMenuCommand );
+    static void                 DispatchCommand(const gchar* pMenuCommand);
+    static void                 Activate(const gchar* pMenuCommand);
+    static void                 Deactivate(const gchar* pMenuCommand);
     void                        EnableUnity(bool bEnable);
     bool                        PrepUpdate();
     virtual void                Update() override;  // Update this menu only.
     void                        UpdateFull();       // Update full menu hierarchy from this menu.
+    GtkSalMenu*                 GetTopLevel();
 
     void CreateMenuBarWidget();
     void DestroyMenuBarWidget();
diff --git a/vcl/unx/gtk/gloactiongroup.cxx b/vcl/unx/gtk/gloactiongroup.cxx
index 04d3a4c..663f1bb 100644
--- a/vcl/unx/gtk/gloactiongroup.cxx
+++ b/vcl/unx/gtk/gloactiongroup.cxx
@@ -101,7 +101,6 @@ struct GLOActionGroupPrivate
 {
     GHashTable  *table;    /* string -> GLOAction */
     GtkSalFrame *frame;    /* Frame to which GActionGroup is associated. */
-    GtkSalMenu  *topmenu;  /* TopLevel Menu to which GActionGroup is associated. */
 };
 
 static void g_lo_action_group_iface_init (GActionGroupInterface *);
@@ -191,19 +190,13 @@ g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
                                           const gchar    *action_name,
                                           GVariant       *state)
 {
+    gboolean bState = g_variant_get_boolean (state);
+    SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
 
-    GtkSalMenu* pSalMenu = group->priv->topmenu;
-    SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " for menu " << pSalMenu);
-
-    if (pSalMenu != nullptr) {
-        gboolean bState = g_variant_get_boolean (state);
-        SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
-
-        if (bState)
-            pSalMenu->Activate (action_name);
-        else
-            pSalMenu->Deactivate (action_name);
-    }
+    if (bState)
+        GtkSalMenu::Activate(action_name);
+    else
+        GtkSalMenu::Deactivate(action_name);
 }
 
 static void
@@ -261,20 +254,9 @@ g_lo_action_group_activate (GActionGroup *group,
                             const gchar  *action_name,
                             GVariant     *parameter)
 {
-    GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
-    GtkSalMenu* pSalMenu = lo_group->priv->topmenu;
-
-    if ( parameter != nullptr )
-        g_action_group_change_action_state( group, action_name, parameter );
-
-    SAL_INFO("vcl.unity", "g_lo_action_group_activate for menu " << pSalMenu);
-
-    if ( pSalMenu != nullptr )
-    {
-        GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
-        SAL_INFO("vcl.unity", "g_lo_action_group_activate dispatching action " << action << " named " << action_name << " on menu " << pSalMenu);
-        pSalMenu->DispatchCommand( action->item_id, action_name );
-    }
+    if (parameter != nullptr)
+        g_action_group_change_action_state(group, action_name, parameter);
+    GtkSalMenu::DispatchCommand(action_name);
 }
 
 void
@@ -304,7 +286,6 @@ g_lo_action_group_insert_stateful (GLOActionGroup     *group,
     {
         if (old_action != nullptr)
             g_lo_action_group_remove (group, action_name);
-//            g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
 
         GLOAction* action = g_lo_action_new();
 
@@ -349,17 +330,6 @@ g_lo_action_group_init (GLOActionGroup *group)
     group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, g_object_unref);
     group->priv->frame = nullptr;
-    group->priv->topmenu = nullptr;
-}
-
-void
-g_lo_action_group_set_top_menu (GLOActionGroup *group,
-                                gpointer top_menu)
-{
-    group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
-                                                 G_TYPE_LO_ACTION_GROUP,
-                                                 GLOActionGroupPrivate);
-    group->priv->topmenu = static_cast<GtkSalMenu*>(top_menu);
 }
 
 static void
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
index 7540f46..c503234 100644
--- a/vcl/unx/gtk/gtksalmenu.cxx
+++ b/vcl/unx/gtk/gtksalmenu.cxx
@@ -28,54 +28,17 @@
 #include <window.h>
 #include <svids.hrc>
 
-// FIXME Copied from framework/inc/framework/menuconfiguration.hxx to
-// avoid circular dependency between modules. It should be in a common
-// header (probably in vcl).
-const sal_uInt16 START_ITEMID_WINDOWLIST    = 4600;
-const sal_uInt16 END_ITEMID_WINDOWLIST      = 4699;
-
 static bool bUnityMode = false;
 
 /*
- * This function generates the proper command name for all actions, including
- * duplicated or special ones.
+ * This function generates a unique command name for each menu item
  */
-static gchar* GetCommandForItem( GtkSalMenuItem* pSalMenuItem, gchar* aCurrentCommand, GActionGroup* pActionGroup )
+static gchar* GetCommandForItem(GtkSalMenuItem* pSalMenuItem)
 {
-    gchar* aCommand = nullptr;
-
-    sal_uInt16 nId = pSalMenuItem->mnId;
-    Menu* pMenu = pSalMenuItem->mpVCLMenu;
-
-    // If item belongs to window list, generate a command with "window-(id)" format.
-    if ( ( nId >= START_ITEMID_WINDOWLIST ) && ( nId <= END_ITEMID_WINDOWLIST ) )
-        aCommand = g_strdup_printf( "window-%d", nId );
-    else
-    {
-        if ( !pMenu )
-            return nullptr;
-
-        OUString aMenuCommand = pMenu->GetItemCommand(nId);
-        if (aMenuCommand.isEmpty())
-            aMenuCommand = "slot:" + OUString::number(nId);
-        gchar* aCommandStr = g_strdup( OUStringToOString( aMenuCommand, RTL_TEXTENCODING_UTF8 ).getStr() );
-        aCommand = g_strdup( aCommandStr );
-
-        // Some items could have duplicated commands. A new one should be generated.
-        for ( sal_uInt16 i = 1; ; i++ )
-        {
-            if ( !g_action_group_has_action( pActionGroup, aCommand )
-                    || ( aCurrentCommand && g_strcmp0( aCurrentCommand, aCommand ) == 0 ) )
-                break;
-
-            g_free( aCommand );
-            aCommand = g_strdup_printf("dup:%d:%s", i, aCommandStr);
-        }
-
-        g_free( aCommandStr );
-    }
-
-    return aCommand;
+    OString aCommand("window-");
+    aCommand = aCommand + OString::number(reinterpret_cast<unsigned long>(pSalMenuItem->mpParentMenu));
+    aCommand = aCommand + "-" + OString::number(pSalMenuItem->mnId);
+    return g_strdup(aCommand.getStr());
 }
 
 bool GtkSalMenu::PrepUpdate()
@@ -278,7 +241,7 @@ void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries)
             pOldCommandList = g_list_append( pOldCommandList, aCurrentCommand );
 
         // Get the new command for the item.
-        gchar* aNativeCommand = GetCommandForItem( pSalMenuItem, aCurrentCommand, mpActionGroup );
+        gchar* aNativeCommand = GetCommandForItem(pSalMenuItem);
 
         // Force updating of native menu labels.
         NativeSetItemText( nSection, nItemPos, aText );
@@ -409,8 +372,6 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& rRec
     aPos = FloatingWindow::ImplConvertToAbsPos(xParent, aPos);
 
     GLOActionGroup* pActionGroup = g_lo_action_group_new(static_cast<gpointer>(mpFrame));
-    g_lo_action_group_set_top_menu(pActionGroup, static_cast<gpointer>(this));
-
     mpActionGroup = G_ACTION_GROUP(pActionGroup);
     mpMenuModel = G_MENU_MODEL(g_lo_menu_new());
     // Generate the main menu structure, populates mpMenuModel
@@ -678,7 +639,6 @@ void GtkSalMenu::SetFrame(const SalFrame* pFrame)
     if ( pActionGroup )
     {
         g_lo_action_group_clear( pActionGroup );
-        g_lo_action_group_set_top_menu(pActionGroup, static_cast<gpointer>(this));
         mpActionGroup = G_ACTION_GROUP( pActionGroup );
     }
 
@@ -883,73 +843,42 @@ bool GtkSalMenu::NativeSetItemCommand( unsigned nSection,
     return bSubMenuAddedOrRemoved;
 }
 
-GtkSalMenu* GtkSalMenu::GetMenuForItemCommand(gchar* aCommand, int& rDupsToSkip, gboolean bGetSubmenu)
+GtkSalMenu* GtkSalMenu::GetTopLevel()
 {
-    SolarMutexGuard aGuard;
-    GtkSalMenu* pMenu = nullptr;
-    for ( size_t nPos = 0; nPos < maItems.size(); nPos++ )
-    {
-        GtkSalMenuItem *pSalItem = maItems[ nPos ];
-
-        OUString aItemCommand = mpVCLMenu->GetItemCommand( pSalItem->mnId );
-        // Do not join the following two lines, or the OString will be destroyed
-        // immediately, and the gchar* pointed to by aItemCommandStr will be
-        // freed before it can be used - fdo#69090
-        OString aItemCommandOStr = OUStringToOString( aItemCommand, RTL_TEXTENCODING_UTF8 );
-        gchar* aItemCommandStr = const_cast<gchar*>(aItemCommandOStr.getStr());
-
-        bool bFound = g_strcmp0( aItemCommandStr, aCommand ) == 0;
-        if (bFound && rDupsToSkip)
-        {
-            --rDupsToSkip;
-            bFound = false;
-        }
-        if (bFound)
-        {
-            pMenu = bGetSubmenu ? pSalItem->mpSubMenu : this;
-            break;
-        }
-        else
-        {
-            if ( pSalItem->mpSubMenu != nullptr )
-                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand(aCommand, rDupsToSkip, bGetSubmenu);
-
-            if ( pMenu != nullptr )
-               break;
-        }
-    }
-
+    GtkSalMenu *pMenu = this;
+    while (pMenu->mpParentSalMenu)
+        pMenu = pMenu->mpParentSalMenu;
     return pMenu;
 }
 
+typedef std::pair<GtkSalMenu*, sal_uInt16> MenuAndId;
+
 namespace
 {
-    const gchar* DetermineDupIndex(const gchar *aCommand, int& rDupsToSkip)
+    MenuAndId decode_command(const gchar *action_name)
     {
-        if (g_str_has_prefix(aCommand, "dup:"))
-        {
-            aCommand = aCommand + strlen("dup:");
-            gchar *endptr;
-            rDupsToSkip = g_ascii_strtoll(aCommand, &endptr, 10);
-            aCommand = endptr+1;
-        }
-        else
-            rDupsToSkip = 0;
+        OString sCommand(action_name);
 
-        return aCommand;
+        sal_Int32 nIndex = 0;
+        OString sWindow = sCommand.getToken(0, '-', nIndex);
+        OString sGtkSalMenu = sCommand.getToken(0, '-', nIndex);
+        OString sItemId = sCommand.getToken(0, '-', nIndex);
+
+        GtkSalMenu* pSalSubMenu = reinterpret_cast<GtkSalMenu*>(sGtkSalMenu.toInt64());
+
+        assert(sWindow == "window" && pSalSubMenu);
+
+        return MenuAndId(pSalSubMenu, sItemId.toInt32());
     }
 }
 
-void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
+void GtkSalMenu::DispatchCommand(const gchar *pCommand)
 {
     SolarMutexGuard aGuard;
-
-    int nDupsToSkip;
-    aCommand = DetermineDupIndex(aCommand, nDupsToSkip);
-
-    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand(const_cast<gchar*>(aCommand), nDupsToSkip, FALSE);
-    Menu* pSubMenu = ( pSalSubMenu != nullptr ) ? pSalSubMenu->GetMenu() : nullptr;
-    mpVCLMenu->HandleMenuCommandEvent(pSubMenu, itemId);
+    MenuAndId aMenuAndId = decode_command(pCommand);
+    GtkSalMenu* pSalSubMenu = aMenuAndId.first;
+    GtkSalMenu* pTopLevel = pSalSubMenu->GetTopLevel();
+    pTopLevel->GetMenu()->HandleMenuCommandEvent(pSalSubMenu->GetMenu(), aMenuAndId.second);
 }
 
 void GtkSalMenu::ActivateAllSubmenus(Menu* pMenuBar)
@@ -967,29 +896,20 @@ void GtkSalMenu::ActivateAllSubmenus(Menu* pMenuBar)
     }
 }
 
-void GtkSalMenu::Activate( const gchar* aMenuCommand )
+void GtkSalMenu::Activate(const gchar* pCommand)
 {
-    int nDupsToSkip;
-    aMenuCommand = DetermineDupIndex(aMenuCommand, nDupsToSkip);
-
-    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand(const_cast<gchar*>(aMenuCommand), nDupsToSkip, TRUE);
-
-    if ( pSalSubMenu != nullptr ) {
-        mpVCLMenu->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu );
-        pSalSubMenu->Update();
-    }
+    MenuAndId aMenuAndId = decode_command(pCommand);
+    GtkSalMenu* pSalSubMenu = aMenuAndId.first;
+    GtkSalMenu* pTopLevel = pSalSubMenu->GetTopLevel();
+    pTopLevel->GetMenu()->HandleMenuActivateEvent(pSalSubMenu->GetMenu());
 }
 
-void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
+void GtkSalMenu::Deactivate(const gchar* pCommand)
 {
-    int nDupsToSkip;
-    aMenuCommand = DetermineDupIndex(aMenuCommand, nDupsToSkip);
-
-    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand(const_cast<gchar*>(aMenuCommand), nDupsToSkip, TRUE);
-
-    if ( pSalSubMenu != nullptr ) {
-        mpVCLMenu->HandleMenuDeActivateEvent( pSalSubMenu->mpVCLMenu );
-    }
+    MenuAndId aMenuAndId = decode_command(pCommand);
+    GtkSalMenu* pSalSubMenu = aMenuAndId.first;
+    GtkSalMenu* pTopLevel = pSalSubMenu->GetTopLevel();
+    pTopLevel->GetMenu()->HandleMenuDeActivateEvent(pSalSubMenu->GetMenu());
 }
 
 void GtkSalMenu::EnableUnity(bool bEnable)
commit d4c7f26971cb20f1a0b8a184cd6a00129a838dac
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri May 6 11:01:32 2016 +0100

    gtk3: separate the two different usages of Activate
    
    Change-Id: Ic7442209efac40bd0cd034ff006e87128b0bea35

diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 240f22f..2e182e6 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -99,7 +99,11 @@ public:
     void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const vcl::KeyCode& rKeyCode, const OUString& rKeyName );
 
     void                        DispatchCommand( gint itemId, const gchar* aCommand );
-    void                        Activate( const gchar* aMenuCommand = nullptr );
+    void                        ActivateAllSubmenus()
+    {
+        ActivateAllSubmenus(mpVCLMenu);
+    }
+    void                        Activate( const gchar* aMenuCommand );
     void                        Deactivate( const gchar* aMenuCommand );
     void                        EnableUnity(bool bEnable);
     bool                        PrepUpdate();
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 05348b4..ff40971 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -500,7 +500,7 @@ void GtkSalFrame::EnsureDbusMenuSynced()
     GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*>(GetMenu());
     if(m_pLastSyncedDbusMenu != pSalMenu) {
         m_pLastSyncedDbusMenu = pSalMenu;
-        static_cast<GtkSalMenu*>(pSalMenu)->Activate();
+        static_cast<GtkSalMenu*>(pSalMenu)->ActivateAllSubmenus();
     }
 }
 #endif
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
index 44e5559..7540f46 100644
--- a/vcl/unx/gtk/gtksalmenu.cxx
+++ b/vcl/unx/gtk/gtksalmenu.cxx
@@ -969,11 +969,6 @@ void GtkSalMenu::ActivateAllSubmenus(Menu* pMenuBar)
 
 void GtkSalMenu::Activate( const gchar* aMenuCommand )
 {
-    if ( !aMenuCommand ) {
-        ActivateAllSubmenus(mpVCLMenu);
-        return;
-    }
-
     int nDupsToSkip;
     aMenuCommand = DetermineDupIndex(aMenuCommand, nDupsToSkip);
 
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index b06e5c9..9f0dcfb 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -504,7 +504,7 @@ void GtkSalFrame::EnsureDbusMenuSynced()
     GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*>(GetMenu());
     if(m_pLastSyncedDbusMenu != pSalMenu) {
         m_pLastSyncedDbusMenu = pSalMenu;
-        static_cast<GtkSalMenu*>(pSalMenu)->Activate();
+        static_cast<GtkSalMenu*>(pSalMenu)->ActivateAllSubmenus();
     }
 }
 #endif


More information about the Libreoffice-commits mailing list