From d20e08a3ab819ac24f7ea49a98b4dd3683120857 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Fri, 6 May 2016 15:14:38 +0100 Subject: Resolves: tdf#98636 if the menubar hierarchy has been changed then update the whole thing by re-calling SetFrame Change-Id: Ib16006a76ca04dc104232a056c43fda2b5b24074 --- vcl/inc/unx/gtk/gtksalmenu.hxx | 8 +++++++- vcl/unx/gtk/gtksalmenu.cxx | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index a5dc4146bdec..11ed51f85f77 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -20,6 +20,7 @@ #include #include +#include #if ENABLE_DBUS && ENABLE_GIO && \ (GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 36) @@ -42,8 +43,10 @@ class GtkSalMenu : public SalMenu { private: std::vector< GtkSalMenuItem* > maItems; + Idle maUpdateMenuBarIdle; bool mbMenuBar; + bool mbNeedsUpdate; GtkWidget* mpMenuBarWidget; GtkWidget* mpCloseButton; Menu* mpVCLMenu; @@ -57,6 +60,8 @@ private: void ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries); void ActivateAllSubmenus(Menu* pMenuBar); + DECL_LINK_TYPED(MenuBarHierarchyChangeHandler, Idle*, void); + public: GtkSalMenu( bool bMenuBar ); virtual ~GtkSalMenu(); @@ -104,8 +109,9 @@ public: bool PrepUpdate(); virtual void Update() override; // Update this menu only. // Update full menu hierarchy from this menu. - void UpdateFull () { ActivateAllSubmenus(mpVCLMenu); } + void UpdateFull () { if (mbNeedsUpdate) ActivateAllSubmenus(mpVCLMenu); } GtkSalMenu* GetTopLevel(); + void SetNeedsUpdate(); void CreateMenuBarWidget(); void DestroyMenuBarWidget(); diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx index fc3092aeb44a..b6deecf000d6 100644 --- a/vcl/unx/gtk/gtksalmenu.cxx +++ b/vcl/unx/gtk/gtksalmenu.cxx @@ -182,6 +182,13 @@ void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries) if( !PrepUpdate() ) return; + if (mbNeedsUpdate) + { + mbNeedsUpdate = false; + if (mbMenuBar) + maUpdateMenuBarIdle.Stop(); + } + Menu* pVCLMenu = mpVCLMenu; GLOMenu* pLOMenu = G_LO_MENU( mpMenuModel ); GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); @@ -409,6 +416,7 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& rRec GtkSalMenu::GtkSalMenu( bool bMenuBar ) : mbMenuBar( bMenuBar ), + mbNeedsUpdate( false ), mpMenuBarWidget( nullptr ), mpCloseButton( nullptr ), mpVCLMenu( nullptr ), @@ -417,6 +425,32 @@ GtkSalMenu::GtkSalMenu( bool bMenuBar ) : mpMenuModel( nullptr ), mpActionGroup( nullptr ) { + //typically this only gets called after the menu has been customized on the + //next idle slot, in the normal case of a new menubar SetFrame is called + //directly long before this idle would get called. + maUpdateMenuBarIdle.SetPriority(SchedulerPriority::HIGHEST); + maUpdateMenuBarIdle.SetIdleHdl(LINK(this, GtkSalMenu, MenuBarHierarchyChangeHandler)); + maUpdateMenuBarIdle.SetDebugName("Native Gtk Menu Update Idle"); +} + +IMPL_LINK_NOARG_TYPED(GtkSalMenu, MenuBarHierarchyChangeHandler, Idle *, void) +{ + SAL_WARN_IF(!mpFrame, "vcl.gtk", "MenuBar layout changed, but no frame for some reason!"); + if (!mpFrame) + return; + SetFrame(mpFrame); +} + +void GtkSalMenu::SetNeedsUpdate() +{ + GtkSalMenu* pMenu = this; + while (pMenu && !pMenu->mbNeedsUpdate) + { + pMenu->mbNeedsUpdate = true; + if (mbMenuBar) + maUpdateMenuBarIdle.Start(); + pMenu = pMenu->mpParentSalMenu; + } } void GtkSalMenu::SetMenuModel(GMenuModel* pMenuModel) @@ -460,12 +494,15 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) maItems.insert( maItems.begin() + nPos, pItem ); pItem->mpParentMenu = this; + + SetNeedsUpdate(); } void GtkSalMenu::RemoveItem( unsigned nPos ) { SolarMutexGuard aGuard; maItems.erase( maItems.begin() + nPos ); + SetNeedsUpdate(); } void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned ) @@ -479,6 +516,8 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig pGtkSubMenu->mpParentSalMenu = this; pItem->mpSubMenu = pGtkSubMenu; + + SetNeedsUpdate(); } #if GTK_CHECK_VERSION(3,0,0) -- cgit v1.2.3