summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-05-06 15:14:38 +0100
committerCaolán McNamara <caolanm@redhat.com>2016-05-06 15:48:59 +0100
commitd20e08a3ab819ac24f7ea49a98b4dd3683120857 (patch)
tree3d631a364377397b9313adb947918a6ec3f0c7b8
parentb41a5e899bcb567595f489fab37cbebcc5efacc0 (diff)
Resolves: tdf#98636 if the menubar hierarchy has been changed
then update the whole thing by re-calling SetFrame Change-Id: Ib16006a76ca04dc104232a056c43fda2b5b24074
-rw-r--r--vcl/inc/unx/gtk/gtksalmenu.hxx8
-rw-r--r--vcl/unx/gtk/gtksalmenu.cxx39
2 files changed, 46 insertions, 1 deletions
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 <unx/salmenu.h>
#include <unx/gtk/gtkframe.hxx>
+#include <vcl/idle.hxx>
#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)