3006956
From b265bcddde36bea2f5b31ce5df407301cbfe82b5 Mon Sep 17 00:00:00 2001
3006956
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
3006956
Date: Tue, 23 Feb 2016 15:57:11 +0000
3006956
Subject: [PATCH 8/8] gtk3: implement native context menus
3006956
3006956
This reuses lots of the unity machinery which is similar
3006956
to the mac concept of a single toplevel menubar.
3006956
3006956
So to drive popup menus, part of this is a rework that does away with the idea
3006956
that the "menubar" is the controller of the hierarchy, and instead the top
3006956
element becomes the controller
3006956
3006956
Change-Id: I4336391718844bc73cfc47c1043f99f0e3b812d8
3006956
(cherry picked from commit a0c700b1493c7b51540d1e77b44d1edd9bf920f0)
3006956
---
3006956
 vcl/inc/unx/gtk/gloactiongroup.h |   3 +
3006956
 vcl/inc/unx/gtk/gtksalmenu.hxx   |   9 +-
3006956
 vcl/unx/gtk/gloactiongroup.cxx   |  43 ++++----
3006956
 vcl/unx/gtk/gtksalmenu.cxx       | 228 +++++++++++++++++++++++++++++----------
3006956
 4 files changed, 203 insertions(+), 80 deletions(-)
3006956
3006956
diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
3006956
index 080b679..ec6bd39 100644
3006956
--- a/vcl/inc/unx/gtk/gloactiongroup.h
3006956
+++ b/vcl/inc/unx/gtk/gloactiongroup.h
3006956
@@ -46,6 +46,9 @@ GType               g_lo_action_group_get_type              (void) G_GNUC_CONST;
3006956
 
3006956
 GLOActionGroup *    g_lo_action_group_new                   (gpointer           frame);
3006956
 
3006956
+void                g_lo_action_group_set_top_menu          (GLOActionGroup     *group,
3006956
+                                                             gpointer           top_menu);
3006956
+
3006956
 void                g_lo_action_group_insert                (GLOActionGroup     *group,
3006956
                                                              const gchar        *action_name,
3006956
                                                              gint                item_id,
3006956
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
3006956
index 1d58b7a..d95d25c 100644
3006956
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
3006956
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
3006956
@@ -43,16 +43,17 @@ private:
3006956
     std::vector< GtkSalMenuItem* >  maItems;
3006956
 
3006956
     bool                            mbMenuBar;
3006956
+    bool                            mbMenuVisibility;
3006956
     Menu*                           mpVCLMenu;
3006956
     GtkSalMenu*                     mpParentSalMenu;
3006956
-    const GtkSalFrame*              mpFrame;
3006956
+    GtkSalFrame*                    mpFrame;
3006956
 
3006956
     // GMenuModel and GActionGroup attributes
3006956
     GMenuModel*                     mpMenuModel;
3006956
     GActionGroup*                   mpActionGroup;
3006956
 
3006956
     GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu );
3006956
-    void                        ImplUpdate( gboolean bRecurse );
3006956
+    void                        ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries);
3006956
     void                        ActivateAllSubmenus(Menu* pMenuBar);
3006956
 
3006956
 public:
3006956
@@ -77,7 +78,7 @@ public:
3006956
 
3006956
     void                        SetMenu( Menu* pMenu ) { mpVCLMenu = pMenu; }
3006956
     Menu*                       GetMenu() { return mpVCLMenu; }
3006956
-    void                        SetMenuModel( GMenuModel* pMenuModel ) { mpMenuModel = pMenuModel; }
3006956
+    void                        SetMenuModel(GMenuModel* pMenuModel);
3006956
     unsigned                    GetItemCount() { return maItems.size(); }
3006956
     GtkSalMenuItem*             GetItemAtPos( unsigned nPos ) { return maItems[ nPos ]; }
3006956
     void                        SetActionGroup( GActionGroup* pActionGroup ) { mpActionGroup = pActionGroup; }
3006956
@@ -102,6 +103,8 @@ public:
3006956
     bool                        PrepUpdate();
3006956
     virtual void                Update() override;  // Update this menu only.
3006956
     void                        UpdateFull();       // Update full menu hierarchy from this menu.
3006956
+
3006956
+    virtual bool                ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, FloatWinPopupFlags nFlags) override;
3006956
 };
3006956
 
3006956
 class GtkSalMenuItem : public SalMenuItem
3006956
diff --git a/vcl/unx/gtk/gloactiongroup.cxx b/vcl/unx/gtk/gloactiongroup.cxx
3006956
index e710809..110e0dc 100644
3006956
--- a/vcl/unx/gtk/gloactiongroup.cxx
3006956
+++ b/vcl/unx/gtk/gloactiongroup.cxx
3006956
@@ -100,8 +100,9 @@ g_lo_action_class_init (GLOActionClass *klass)
3006956
 
3006956
 struct _GLOActionGroupPrivate
3006956
 {
3006956
-    GHashTable  *table;  /* string -> GLOAction */
3006956
-    GtkSalFrame *frame;  /* Frame to which GActionGroup is associated. */
3006956
+    GHashTable  *table;    /* string -> GLOAction */
3006956
+    GtkSalFrame *frame;    /* Frame to which GActionGroup is associated. */
3006956
+    GtkSalMenu  *topmenu;  /* TopLevel Menu to which GActionGroup is associated. */
3006956
 };
3006956
 
3006956
 static void g_lo_action_group_iface_init (GActionGroupInterface *);
3006956
@@ -187,13 +188,7 @@ g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
3006956
                                           GVariant       *state)
3006956
 {
3006956
 
3006956
-    GtkSalFrame* pFrame = group->priv->frame;
3006956
-    SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " for frame " << pFrame);
3006956
-
3006956
-    if (pFrame == nullptr)
3006956
-        return;
3006956
-
3006956
-    GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*> (pFrame->GetMenu());
3006956
+    GtkSalMenu* pSalMenu = group->priv->topmenu;
3006956
     SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " for menu " << pSalMenu);
3006956
 
3006956
     if (pSalMenu != nullptr) {
3006956
@@ -263,23 +258,18 @@ g_lo_action_group_activate (GActionGroup *group,
3006956
                             GVariant     *parameter)
3006956
 {
3006956
     GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
3006956
-    GtkSalFrame *pFrame = lo_group->priv->frame;
3006956
-    SAL_INFO("vcl.unity", "g_lo_action_group_activate on group " << group << " for frame " << pFrame << " with parameter " << parameter);
3006956
+    GtkSalMenu* pSalMenu = lo_group->priv->topmenu;
3006956
 
3006956
     if ( parameter != nullptr )
3006956
         g_action_group_change_action_state( group, action_name, parameter );
3006956
 
3006956
-    if ( pFrame != nullptr )
3006956
-    {
3006956
-        GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
3006956
-        SAL_INFO("vcl.unity", "g_lo_action_group_activate for menu " << pSalMenu);
3006956
+    SAL_INFO("vcl.unity", "g_lo_action_group_activate for menu " << pSalMenu);
3006956
 
3006956
-        if ( pSalMenu != nullptr )
3006956
-        {
3006956
-            GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
3006956
-            SAL_INFO("vcl.unity", "g_lo_action_group_activate dispatching action " << action << " named " << action_name << " on menu " << pSalMenu);
3006956
-            pSalMenu->DispatchCommand( action->item_id, action_name );
3006956
-        }
3006956
+    if ( pSalMenu != nullptr )
3006956
+    {
3006956
+        GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
3006956
+        SAL_INFO("vcl.unity", "g_lo_action_group_activate dispatching action " << action << " named " << action_name << " on menu " << pSalMenu);
3006956
+        pSalMenu->DispatchCommand( action->item_id, action_name );
3006956
     }
3006956
 }
3006956
 
3006956
@@ -355,6 +345,17 @@ g_lo_action_group_init (GLOActionGroup *group)
3006956
     group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
3006956
                                                   g_free, g_object_unref);
3006956
     group->priv->frame = nullptr;
3006956
+    group->priv->topmenu = nullptr;
3006956
+}
3006956
+
3006956
+void
3006956
+g_lo_action_group_set_top_menu (GLOActionGroup *group,
3006956
+                                gpointer top_menu)
3006956
+{
3006956
+    group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
3006956
+                                                 G_TYPE_LO_ACTION_GROUP,
3006956
+                                                 GLOActionGroupPrivate);
3006956
+    group->priv->topmenu = static_cast<GtkSalMenu*>(top_menu);
3006956
 }
3006956
 
3006956
 static void
3006956
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
3006956
index 346e42d..7bc9232 100644
3006956
--- a/vcl/unx/gtk/gtksalmenu.cxx
3006956
+++ b/vcl/unx/gtk/gtksalmenu.cxx
3006956
@@ -16,6 +16,7 @@
3006956
 #include <unx/gtk/gtkdata.hxx>
3006956
 #include <unx/gtk/glomenu.h>
3006956
 #include <unx/gtk/gloactiongroup.h>
3006956
+#include <vcl/floatwin.hxx>
3006956
 #include <vcl/menu.hxx>
3006956
 #include <unx/gtk/gtkinst.hxx>
3006956
 
3006956
@@ -24,6 +25,7 @@
3006956
 #endif
3006956
 
3006956
 #include <sal/log.hxx>
3006956
+#include <window.h>
3006956
 
3006956
 // FIXME Copied from framework/inc/framework/menuconfiguration.hxx to
3006956
 // avoid circular dependency between modules. It should be in a common
3006956
@@ -31,8 +33,6 @@
3006956
 const sal_uInt16 START_ITEMID_WINDOWLIST    = 4600;
3006956
 const sal_uInt16 END_ITEMID_WINDOWLIST      = 4699;
3006956
 
3006956
-static bool bMenuVisibility = false;
3006956
-
3006956
 /*
3006956
  * This function generates the proper command name for all actions, including
3006956
  * duplicated or special ones.
3006956
@@ -77,20 +77,17 @@ static gchar* GetCommandForItem( GtkSalMenuItem* pSalMenuItem, gchar* aCurrentCo
3006956
 
3006956
 bool GtkSalMenu::PrepUpdate()
3006956
 {
3006956
-    const GtkSalFrame* pFrame = GetFrame();
3006956
-    if (pFrame)
3006956
-    {
3006956
-        GtkSalFrame* pNonConstFrame = const_cast<GtkSalFrame*>(pFrame);
3006956
-        GtkSalMenu* pSalMenu = this;
3006956
-
3006956
-        if ( !pNonConstFrame->GetMenu() )
3006956
-            pNonConstFrame->SetMenu( pSalMenu );
3006956
+    bool bMenuVisibility;
3006956
 
3006956
-        if ( bMenuVisibility && mpMenuModel && mpActionGroup )
3006956
-            return true;
3006956
-    }
3006956
+    //get top level visibility
3006956
+    const GtkSalMenu* pMenu = this;
3006956
+    do
3006956
+    {
3006956
+        bMenuVisibility = pMenu->mbMenuVisibility;
3006956
+        pMenu = pMenu->mpParentSalMenu;
3006956
+    } while (pMenu);
3006956
 
3006956
-    return false;
3006956
+    return bMenuVisibility && mpMenuModel && mpActionGroup;
3006956
 }
3006956
 
3006956
 /*
3006956
@@ -114,14 +111,58 @@ void RemoveSpareItemsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, un
3006956
     }
3006956
 }
3006956
 
3006956
-void RemoveSpareSectionsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, unsigned nLastSection )
3006956
+void RemoveDisabledItemsFromNativeMenu(GLOMenu* pMenu, GList** pOldCommandList,
3006956
+                                       sal_Int32 nSection, GActionGroup* pActionGroup)
3006956
+{
3006956
+    while (nSection >= 0)
3006956
+    {
3006956
+        sal_Int32 nSectionItems = g_lo_menu_get_n_items_from_section( pMenu, nSection );
3006956
+        while (nSectionItems--)
3006956
+        {
3006956
+            gchar* pCommand = g_lo_menu_get_command_from_item_in_section(pMenu, nSection, nSectionItems);
3006956
+            // remove disabled entries
3006956
+            bool bRemove = g_action_group_get_action_enabled(pActionGroup, pCommand) == false;
3006956
+            if (!bRemove)
3006956
+            {
3006956
+                //also remove any empty submenus
3006956
+                GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section(pMenu, nSection, nSectionItems);
3006956
+                if (pSubMenuModel)
3006956
+                {
3006956
+                    gint nSubMenuSections = g_menu_model_get_n_items(G_MENU_MODEL(pSubMenuModel));
3006956
+                    bRemove = (nSubMenuSections == 0 ||
3006956
+                              (nSubMenuSections == 1 && g_lo_menu_get_n_items_from_section(pSubMenuModel, 0) == 0));
3006956
+                }
3006956
+            }
3006956
+
3006956
+            if (bRemove)
3006956
+            {
3006956
+                //but tdf#86850 Always display clipboard functions
3006956
+                bRemove = g_strcmp0(pCommand, ".uno:Cut") &&
3006956
+                          g_strcmp0(pCommand, ".uno:Copy") &&
3006956
+                          g_strcmp0(pCommand, ".uno:Paste");
3006956
+            }
3006956
+
3006956
+            if (bRemove)
3006956
+            {
3006956
+                if (pCommand != nullptr && pOldCommandList != nullptr)
3006956
+                    *pOldCommandList = g_list_append(*pOldCommandList, g_strdup(pCommand));
3006956
+                g_lo_menu_remove_from_section(pMenu, nSection, nSectionItems);
3006956
+            }
3006956
+
3006956
+            g_free(pCommand);
3006956
+        }
3006956
+        --nSection;
3006956
+    }
3006956
+}
3006956
+
3006956
+void RemoveSpareSectionsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, sal_Int32 nLastSection )
3006956
 {
3006956
     if ( pMenu == nullptr || pOldCommandList == nullptr )
3006956
         return;
3006956
 
3006956
     sal_Int32 n = g_menu_model_get_n_items( G_MENU_MODEL( pMenu ) ) - 1;
3006956
 
3006956
-    for ( ; n > (sal_Int32) nLastSection; n-- )
3006956
+    for ( ; n > nLastSection; n--)
3006956
     {
3006956
         RemoveSpareItemsFromNativeMenu( pMenu, pOldCommandList, n, 0 );
3006956
         g_lo_menu_remove( pMenu, n );
3006956
@@ -173,7 +214,7 @@ void RemoveUnusedCommands( GLOActionGroup* pActionGroup, GList* pOldCommandList,
3006956
     }
3006956
 }
3006956
 
3006956
-void GtkSalMenu::ImplUpdate( gboolean bRecurse )
3006956
+void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries)
3006956
 {
3006956
     SolarMutexGuard aGuard;
3006956
 
3006956
@@ -277,7 +318,7 @@ void GtkSalMenu::ImplUpdate( gboolean bRecurse )
3006956
                 SAL_INFO("vcl.unity", "preparing submenu  " << pSubMenuModel << " to menu model " << G_MENU_MODEL(pSubMenuModel) << " and action group " << G_ACTION_GROUP(pActionGroup));
3006956
                 pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
3006956
                 pSubmenu->SetActionGroup( G_ACTION_GROUP( pActionGroup ) );
3006956
-                pSubmenu->ImplUpdate( bRecurse );
3006956
+                pSubmenu->ImplUpdate(bRecurse, bRemoveDisabledEntries);
3006956
             }
3006956
         }
3006956
 
3006956
@@ -287,6 +328,12 @@ void GtkSalMenu::ImplUpdate( gboolean bRecurse )
3006956
         ++validItems;
3006956
     }
3006956
 
3006956
+    if (bRemoveDisabledEntries)
3006956
+    {
3006956
+        // Delete disabled items in last section.
3006956
+        RemoveDisabledItemsFromNativeMenu(pLOMenu, &pOldCommandList, nSection, G_ACTION_GROUP(pActionGroup));
3006956
+    }
3006956
+
3006956
     // Delete extra items in last section.
3006956
     RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems );
3006956
 
3006956
@@ -299,12 +346,89 @@ void GtkSalMenu::ImplUpdate( gboolean bRecurse )
3006956
 
3006956
 void GtkSalMenu::Update()
3006956
 {
3006956
-    ImplUpdate( FALSE );
3006956
+    //find out if top level is a menubar or not, if not, then its a popup menu
3006956
+    //hierarchy and in those we hide (most) disabled entries
3006956
+    const GtkSalMenu* pMenu = this;
3006956
+    while (pMenu->mpParentSalMenu)
3006956
+        pMenu = pMenu->mpParentSalMenu;
3006956
+    ImplUpdate(false, !pMenu->mbMenuBar);
3006956
 }
3006956
 
3006956
 void GtkSalMenu::UpdateFull()
3006956
 {
3006956
-    ImplUpdate( TRUE );
3006956
+    //find out if top level is a menubar or not, if not, then its a popup menu
3006956
+    //hierarchy and in those we hide (most) disabled entries
3006956
+    const GtkSalMenu* pMenu = this;
3006956
+    while (pMenu->mpParentSalMenu)
3006956
+        pMenu = pMenu->mpParentSalMenu;
3006956
+    ImplUpdate(true, !pMenu->mbMenuBar);
3006956
+}
3006956
+
3006956
+bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& /*rRect*/,
3006956
+                                     FloatWinPopupFlags /*nFlags*/)
3006956
+{
3006956
+#if GTK_CHECK_VERSION(3,0,0)
3006956
+    guint nButton;
3006956
+    guint32 nTime;
3006956
+
3006956
+    //typically there is an event, and we can then distinguish if this was
3006956
+    //launched from the keyboard (gets auto-mnemoniced) or the mouse (which
3006956
+    //doesn't)
3006956
+    GdkEvent *pEvent = gtk_get_current_event();
3006956
+    if (pEvent)
3006956
+    {
3006956
+        gdk_event_get_button(pEvent, &nButton);
3006956
+        nTime = gdk_event_get_time(pEvent);
3006956
+    }
3006956
+    else
3006956
+    {
3006956
+        nButton = 0;
3006956
+        nTime = gtk_get_current_event_time();
3006956
+    }
3006956
+
3006956
+    Display(true);
3006956
+
3006956
+    mpFrame = static_cast<GtkSalFrame*>(pWin->ImplGetWindowImpl()->mpRealParent->ImplGetFrame());
3006956
+
3006956
+    GLOActionGroup* pActionGroup = g_lo_action_group_new(static_cast<gpointer>(mpFrame));
3006956
+    g_lo_action_group_set_top_menu(pActionGroup, static_cast<gpointer>(this));
3006956
+
3006956
+    mpActionGroup = G_ACTION_GROUP(pActionGroup);
3006956
+    mpMenuModel = G_MENU_MODEL(g_lo_menu_new());
3006956
+    // Generate the main menu structure, populates mpMenuModel
3006956
+    UpdateFull();
3006956
+
3006956
+    GtkWidget *pWidget = gtk_menu_new_from_model(mpMenuModel);
3006956
+    gtk_menu_attach_to_widget(GTK_MENU(pWidget), mpFrame->getMouseEventWidget(), nullptr);
3006956
+
3006956
+    gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", mpActionGroup);
3006956
+
3006956
+    //run in a sub main loop because we need to keep vcl PopupMenu alive to use
3006956
+    //it during DispatchCommand, returning now to the outer loop causes the
3006956
+    //launching PopupMenu to be destroyed, instead run the subloop here
3006956
+    //until the gtk menu is destroyed
3006956
+    GMainLoop* pLoop = g_main_loop_new(nullptr, true);
3006956
+    g_signal_connect_swapped(G_OBJECT(pWidget), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop);
3006956
+    gtk_menu_popup(GTK_MENU(pWidget), nullptr, nullptr, nullptr, nullptr, nButton, nTime);
3006956
+    if (g_main_loop_is_running(pLoop))
3006956
+    {
3006956
+        gdk_threads_leave();
3006956
+        g_main_loop_run(pLoop);
3006956
+        gdk_threads_enter();
3006956
+    }
3006956
+    g_main_loop_unref(pLoop);
3006956
+
3006956
+    gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", nullptr);
3006956
+
3006956
+    gtk_widget_destroy(pWidget);
3006956
+
3006956
+    g_object_unref(mpActionGroup);
3006956
+
3006956
+    return true;
3006956
+#else
3006956
+    (void)pWin;
3006956
+    return false;
3006956
+#endif
3006956
 }
3006956
 
3006956
 /*
3006956
@@ -313,6 +437,7 @@ void GtkSalMenu::UpdateFull()
3006956
 
3006956
 GtkSalMenu::GtkSalMenu( bool bMenuBar ) :
3006956
     mbMenuBar( bMenuBar ),
3006956
+    mbMenuVisibility( false ),
3006956
     mpVCLMenu( nullptr ),
3006956
     mpParentSalMenu( nullptr ),
3006956
     mpFrame( nullptr ),
3006956
@@ -321,25 +446,28 @@ GtkSalMenu::GtkSalMenu( bool bMenuBar ) :
3006956
 {
3006956
 }
3006956
 
3006956
+void GtkSalMenu::SetMenuModel(GMenuModel* pMenuModel)
3006956
+{
3006956
+    if (mpMenuModel)
3006956
+        g_object_unref(mpMenuModel);
3006956
+    mpMenuModel = pMenuModel;
3006956
+    if (mpMenuModel)
3006956
+        g_object_ref(mpMenuModel);
3006956
+}
3006956
+
3006956
 GtkSalMenu::~GtkSalMenu()
3006956
 {
3006956
     SolarMutexGuard aGuard;
3006956
 
3006956
-    if ( mbMenuBar )
3006956
-    {
3006956
-        if ( mpMenuModel )
3006956
-        {
3006956
-//            g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 );
3006956
-            g_object_unref( mpMenuModel );
3006956
-        }
3006956
-    }
3006956
+    if (mpMenuModel)
3006956
+        g_object_unref(mpMenuModel);
3006956
 
3006956
     maItems.clear();
3006956
 }
3006956
 
3006956
 bool GtkSalMenu::VisibleMenuBar()
3006956
 {
3006956
-    return bMenuVisibility;
3006956
+    return mbMenuBar && mbMenuVisibility;
3006956
 }
3006956
 
3006956
 void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
3006956
@@ -374,22 +502,21 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig
3006956
     pItem->mpSubMenu = pGtkSubMenu;
3006956
 }
3006956
 
3006956
-void GtkSalMenu::SetFrame( const SalFrame* pFrame )
3006956
+void GtkSalMenu::SetFrame(const SalFrame* pFrame)
3006956
 {
3006956
     SolarMutexGuard aGuard;
3006956
     assert(mbMenuBar);
3006956
     SAL_INFO("vcl.unity", "GtkSalMenu set to frame");
3006956
-    mpFrame = static_cast< const GtkSalFrame* >( pFrame );
3006956
-    GtkSalFrame* pFrameNonConst = const_cast<GtkSalFrame*>(mpFrame);
3006956
+    mpFrame = const_cast<GtkSalFrame*>(static_cast<const GtkSalFrame*>(pFrame));
3006956
 
3006956
     // if we had a menu on the GtkSalMenu we have to free it as we generate a
3006956
     // full menu anyway and we might need to reuse an existing model and
3006956
     // actiongroup
3006956
-    pFrameNonConst->SetMenu( this );
3006956
-    pFrameNonConst->EnsureAppMenuWatch();
3006956
+    mpFrame->SetMenu( this );
3006956
+    mpFrame->EnsureAppMenuWatch();
3006956
 
3006956
     // Clean menu model and action group if needed.
3006956
-    GtkWidget* pWidget = pFrameNonConst->getWindow();
3006956
+    GtkWidget* pWidget = mpFrame->getWindow();
3006956
     GdkWindow* gdkWindow = gtk_widget_get_window( pWidget );
3006956
 
3006956
     GLOMenu* pMenuModel = G_LO_MENU( g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) );
3006956
@@ -407,11 +534,12 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
3006956
     if ( pActionGroup )
3006956
     {
3006956
         g_lo_action_group_clear( pActionGroup );
3006956
+        g_lo_action_group_set_top_menu(pActionGroup, static_cast<gpointer>(this));
3006956
         mpActionGroup = G_ACTION_GROUP( pActionGroup );
3006956
     }
3006956
 
3006956
     // Generate the main menu structure.
3006956
-    if (bMenuVisibility)
3006956
+    if (mbMenuVisibility)
3006956
         UpdateFull();
3006956
 
3006956
     g_lo_menu_insert_section( pMenuModel, 0, nullptr, mpMenuModel );
3006956
@@ -618,14 +746,9 @@ GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand, gboolean bGetSub
3006956
 void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
3006956
 {
3006956
     SolarMutexGuard aGuard;
3006956
-    // Only the menubar is allowed to dispatch commands.
3006956
-    if ( !mbMenuBar )
3006956
-        return;
3006956
-
3006956
     GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast<gchar*>(aCommand), FALSE );
3006956
     Menu* pSubMenu = ( pSalSubMenu != nullptr ) ? pSalSubMenu->GetMenu() : nullptr;
3006956
-
3006956
-    mpVCLMenu->HandleMenuCommandEvent( pSubMenu, itemId );
3006956
+    mpVCLMenu->HandleMenuCommandEvent(pSubMenu, itemId);
3006956
 }
3006956
 
3006956
 void GtkSalMenu::ActivateAllSubmenus(Menu* pMenuBar)
3006956
@@ -645,9 +768,6 @@ void GtkSalMenu::ActivateAllSubmenus(Menu* pMenuBar)
3006956
 
3006956
 void GtkSalMenu::Activate( const gchar* aMenuCommand )
3006956
 {
3006956
-    if ( !mbMenuBar )
3006956
-        return;
3006956
-
3006956
     if ( !aMenuCommand ) {
3006956
         ActivateAllSubmenus(mpVCLMenu);
3006956
         return;
3006956
@@ -663,9 +783,6 @@ void GtkSalMenu::Activate( const gchar* aMenuCommand )
3006956
 
3006956
 void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
3006956
 {
3006956
-    if ( !mbMenuBar )
3006956
-        return;
3006956
-
3006956
     GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast<gchar*>(aMenuCommand), TRUE );
3006956
 
3006956
     if ( pSalSubMenu != nullptr ) {
3006956
@@ -675,15 +792,14 @@ void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
3006956
 
3006956
 void GtkSalMenu::Display( bool bVisible )
3006956
 {
3006956
-    if ( !mbMenuBar || mpVCLMenu == nullptr )
3006956
-        return;
3006956
+    mbMenuVisibility = bVisible;
3006956
 
3006956
-    bMenuVisibility = bVisible;
3006956
-
3006956
-    bool bVCLMenuVisible = !bVisible;
3006956
-
3006956
-    MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu );
3006956
-    pMenuBar->SetDisplayable( bVCLMenuVisible );
3006956
+    if (mbMenuBar)
3006956
+    {
3006956
+        bool bVCLMenuVisible = !bVisible;
3006956
+        MenuBar* pMenuBar = static_cast<MenuBar*>(mpVCLMenu);
3006956
+        pMenuBar->SetDisplayable(bVCLMenuVisible);
3006956
+    }
3006956
 }
3006956
 
3006956
 bool GtkSalMenu::IsItemVisible( unsigned nPos )
3006956
-- 
3006956
2.7.1
3006956