You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
12 KiB
330 lines
12 KiB
From e51b78efcdd8e55727fb3b75165b11a30bf6a83a Mon Sep 17 00:00:00 2001
|
|
From: Maxim Monastirsky <momonasmon@gmail.com>
|
|
Date: Sun, 7 Feb 2016 17:53:40 +0200
|
|
Subject: [PATCH] tdf#97665 Let's hope that over activation isn't really needed
|
|
|
|
- MenuBarManager::Activate has a check for duplicate activation,
|
|
which makes the second activation attempt fail. Removing this
|
|
check or deactivating after each activation will likely affect
|
|
performance even more, but on the other hand should solve
|
|
lp#1296715, which was the main reason of the over activation
|
|
in the first place. So let's activate only one menu at a time,
|
|
and do full activation only on the initial update.
|
|
|
|
- Unfortunately the HUD activation callback doesn't work, so
|
|
we still have to keep active status listener for all menu
|
|
items. (Which is BTW against the recommendation in
|
|
XPopupMenuController::updatePopupMenu IDL doc. Fortunately
|
|
the performance problem hardly noticeable on modern hw.)
|
|
|
|
Reviewed-on: https://gerrit.libreoffice.org/22369
|
|
Tested-by: Jenkins <ci@libreoffice.org>
|
|
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
|
|
(cherry picked from commit 2abdcfd641883f246fe78f2fbe38499c9382c059)
|
|
|
|
Change-Id: I96affa72412f3f38160fdca4b6efd20ca68d059f
|
|
---
|
|
framework/source/uielement/menubarmanager.cxx | 11 ++---
|
|
include/vcl/menu.hxx | 9 +---
|
|
vcl/inc/salmenu.hxx | 1 +
|
|
vcl/inc/unx/gtk/gtksalmenu.hxx | 4 +-
|
|
vcl/source/window/menu.cxx | 46 +++----------------
|
|
vcl/unx/gtk/gloactiongroup.cxx | 2 +-
|
|
vcl/unx/gtk/gtkdata.cxx | 18 --------
|
|
vcl/unx/gtk/gtksalmenu.cxx | 64 +++++++--------------------
|
|
8 files changed, 33 insertions(+), 122 deletions(-)
|
|
|
|
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
|
|
index 6bb58db..fc80c3e 100644
|
|
--- a/framework/source/uielement/menubarmanager.cxx
|
|
+++ b/framework/source/uielement/menubarmanager.cxx
|
|
@@ -386,10 +386,6 @@ throw ( RuntimeException, std::exception )
|
|
OUString aFeatureURL = Event.FeatureURL.Complete;
|
|
|
|
SolarMutexGuard aSolarGuard;
|
|
- if ( m_bHasMenuBar )
|
|
- {
|
|
- vcl::MenuInvalidator::Invalidated();
|
|
- }
|
|
{
|
|
if ( m_bDisposed )
|
|
return;
|
|
@@ -488,6 +484,8 @@ throw ( RuntimeException, std::exception )
|
|
pMenuItemHandler->xMenuItemDispatch.clear();
|
|
}
|
|
}
|
|
+ if ( m_bHasMenuBar && !m_bActive )
|
|
+ m_pVCLMenu->UpdateNativeMenu();
|
|
}
|
|
}
|
|
|
|
@@ -893,9 +891,8 @@ IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool )
|
|
if ( !bPopupMenu )
|
|
{
|
|
xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
|
|
- xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
|
|
- if ( m_bHasMenuBar )
|
|
- xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
|
|
+ if ( !m_bHasMenuBar )
|
|
+ xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
|
|
}
|
|
}
|
|
else if ( !bPopupMenu )
|
|
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
|
|
index ade703b..0d6e16a 100644
|
|
--- a/include/vcl/menu.hxx
|
|
+++ b/include/vcl/menu.hxx
|
|
@@ -313,6 +313,8 @@ public:
|
|
void RemoveDisabledEntries( bool bCheckPopups = true, bool bRemoveEmptyPopups = false );
|
|
bool HasValidEntries( bool bCheckPopups = true );
|
|
|
|
+ void UpdateNativeMenu();
|
|
+
|
|
void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
|
|
OUString GetItemText( sal_uInt16 nItemId ) const;
|
|
|
|
@@ -407,13 +409,6 @@ public:
|
|
};
|
|
|
|
|
|
-namespace vcl { namespace MenuInvalidator {
|
|
-
|
|
-VCL_DLLPUBLIC void AddMenuInvalidateListener(const Link<LinkParamNone*,void>&);
|
|
-VCL_DLLPUBLIC void Invalidated();
|
|
-
|
|
-}}
|
|
-
|
|
class VCL_DLLPUBLIC MenuBar : public Menu
|
|
{
|
|
Link<void*,void> maCloseHdl;
|
|
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
|
|
index 287e19e..468994a 100644
|
|
--- a/vcl/inc/salmenu.hxx
|
|
+++ b/vcl/inc/salmenu.hxx
|
|
@@ -80,6 +80,7 @@ public:
|
|
virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, FloatWinPopupFlags nFlags);
|
|
virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure
|
|
virtual void RemoveMenuBarButton( sal_uInt16 nId );
|
|
+ virtual void Update() {}
|
|
|
|
// TODO: implement show/hide for the Win/Mac VCL native backends
|
|
virtual void ShowItem( unsigned nPos, bool bShow ) { EnableItem( nPos, bShow ); }
|
|
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
|
|
index 011c3e4..93259f1 100644
|
|
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
|
|
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
|
|
@@ -96,11 +96,11 @@ public:
|
|
void NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const vcl::KeyCode& rKeyCode, const OUString& rKeyName );
|
|
|
|
void DispatchCommand( gint itemId, const gchar* aCommand );
|
|
- void Activate();
|
|
+ void Activate( const gchar* aMenuCommand = nullptr );
|
|
void Deactivate( const gchar* aMenuCommand );
|
|
void Display( bool bVisible );
|
|
bool PrepUpdate();
|
|
- void Update(); // Update this menu only.
|
|
+ virtual void Update() override; // Update this menu only.
|
|
void UpdateFull(); // Update full menu hierarchy from this menu.
|
|
};
|
|
|
|
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
|
|
index 3a6e54c..4aa7d41 100644
|
|
--- a/vcl/source/window/menu.cxx
|
|
+++ b/vcl/source/window/menu.cxx
|
|
@@ -2314,6 +2314,12 @@ sal_uLong Menu::DeactivateMenuBar(sal_uLong nFocusId)
|
|
return nFocusId;
|
|
}
|
|
|
|
+void Menu::UpdateNativeMenu()
|
|
+{
|
|
+ if ( ImplGetSalMenu() )
|
|
+ ImplGetSalMenu()->Update();
|
|
+}
|
|
+
|
|
void Menu::MenuBarKeyInput(const KeyEvent&)
|
|
{
|
|
}
|
|
@@ -3251,44 +3257,4 @@ ImplMenuDelData::~ImplMenuDelData()
|
|
const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this );
|
|
}
|
|
|
|
-namespace vcl { namespace MenuInvalidator {
|
|
-
|
|
-struct MenuInvalidateListeners : public vcl::DeletionNotifier
|
|
-{
|
|
- std::vector<Link<LinkParamNone*,void>> m_aListeners;
|
|
-};
|
|
-
|
|
-static MenuInvalidateListeners* pMenuInvalidateListeners = nullptr;
|
|
-
|
|
-void AddMenuInvalidateListener(const Link<LinkParamNone*,void>& rLink)
|
|
-{
|
|
- if(!pMenuInvalidateListeners)
|
|
- pMenuInvalidateListeners = new MenuInvalidateListeners();
|
|
- // ensure uniqueness
|
|
- auto& rListeners = pMenuInvalidateListeners->m_aListeners;
|
|
- if (std::find(rListeners.begin(), rListeners.end(), rLink) == rListeners.end())
|
|
- rListeners.push_back( rLink );
|
|
-}
|
|
-
|
|
-void Invalidated()
|
|
-{
|
|
- if(!pMenuInvalidateListeners)
|
|
- return;
|
|
-
|
|
- vcl::DeletionListener aDel( pMenuInvalidateListeners );
|
|
-
|
|
- auto& rYieldListeners = pMenuInvalidateListeners->m_aListeners;
|
|
- // Copy the list, because this can be destroyed when calling a Link...
|
|
- std::vector<Link<LinkParamNone*,void>> aCopy( rYieldListeners );
|
|
- for( Link<LinkParamNone*,void>& rLink : aCopy )
|
|
- {
|
|
- if (aDel.isDeleted()) break;
|
|
- // check this hasn't been removed in some re-enterancy scenario fdo#47368
|
|
- if( std::find(rYieldListeners.begin(), rYieldListeners.end(), rLink) != rYieldListeners.end() )
|
|
- rLink.Call( nullptr );
|
|
- }
|
|
-};
|
|
-
|
|
-} } // namespace vcl::MenuInvalidator
|
|
-
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
diff --git a/vcl/unx/gtk/gloactiongroup.cxx b/vcl/unx/gtk/gloactiongroup.cxx
|
|
index 8385388..e710809 100644
|
|
--- a/vcl/unx/gtk/gloactiongroup.cxx
|
|
+++ b/vcl/unx/gtk/gloactiongroup.cxx
|
|
@@ -201,7 +201,7 @@ g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
|
|
SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
|
|
|
|
if (bState)
|
|
- pSalMenu->Activate();
|
|
+ pSalMenu->Activate (action_name);
|
|
else
|
|
pSalMenu->Deactivate (action_name);
|
|
}
|
|
diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
|
|
index b5c64e0..9ea6dc9 100644
|
|
--- a/vcl/unx/gtk/gtkdata.cxx
|
|
+++ b/vcl/unx/gtk/gtkdata.cxx
|
|
@@ -1030,22 +1030,4 @@ void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
|
|
SalGenericDisplay::deregisterFrame( pFrame );
|
|
}
|
|
|
|
-#if GTK_CHECK_VERSION(3,0,0)
|
|
-void GtkSalDisplay::RefreshMenusUnity()
|
|
-{
|
|
-#ifdef ENABLE_GMENU_INTEGRATION
|
|
- for(auto pSalFrame : m_aFrames) {
|
|
- auto pGtkSalFrame( static_cast<GtkSalFrame*>(pSalFrame));
|
|
- GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*>(pGtkSalFrame->GetMenu());
|
|
- if(pSalMenu) {
|
|
- pSalMenu->Activate();
|
|
- pSalMenu->UpdateFull();
|
|
- }
|
|
- }
|
|
-#else
|
|
- (void) this;
|
|
-#endif
|
|
-}
|
|
-#endif
|
|
-
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
|
|
index b6295fa..5c16c39 100644
|
|
--- a/vcl/unx/gtk/gtksalmenu.cxx
|
|
+++ b/vcl/unx/gtk/gtksalmenu.cxx
|
|
@@ -372,54 +372,9 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig
|
|
pItem->mpSubMenu = pGtkSubMenu;
|
|
}
|
|
|
|
-static bool bInvalidMenus = false;
|
|
-static gboolean RefreshMenusUnity(gpointer)
|
|
-{
|
|
- SolarMutexGuard g;
|
|
-#if GTK_CHECK_VERSION(3,0,0)
|
|
- GetGtkSalData()->GetGtkDisplay()->RefreshMenusUnity();
|
|
-#else
|
|
- SalDisplay* pSalDisplay = vcl_sal::getSalDisplay(GetGenericData());
|
|
- std::list< SalFrame* >::const_iterator pSalFrame = pSalDisplay->getFrames().begin();
|
|
- std::list< SalFrame* >::const_iterator pEndSalFrame = pSalDisplay->getFrames().end();
|
|
- for(; pSalFrame != pEndSalFrame; ++pSalFrame) {
|
|
- const GtkSalFrame* pGtkSalFrame = static_cast< const GtkSalFrame* >( *pSalFrame );
|
|
- GtkSalFrame* pFrameNonConst = const_cast<GtkSalFrame*>(pGtkSalFrame);
|
|
- GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*>(pFrameNonConst->GetMenu());
|
|
- if(pSalMenu) {
|
|
- pSalMenu->Activate();
|
|
- pSalMenu->UpdateFull();
|
|
- }
|
|
- }
|
|
-#endif
|
|
- bInvalidMenus = false;
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static void RefreshMenusUnity(void*, LinkParamNone*)
|
|
-{
|
|
- if(!bInvalidMenus) {
|
|
- g_timeout_add(10, &RefreshMenusUnity, nullptr);
|
|
- bInvalidMenus = true;
|
|
- }
|
|
-}
|
|
-
|
|
-static Link<LinkParamNone*,void>* getRefreshLinkInstance()
|
|
-{
|
|
- static Link<LinkParamNone*,void>* pLink = nullptr;
|
|
- if(!pLink) {
|
|
- pLink = new Link<LinkParamNone*,void>(nullptr, &RefreshMenusUnity);
|
|
- }
|
|
- return pLink;
|
|
-}
|
|
-
|
|
void GtkSalMenu::SetFrame( const SalFrame* pFrame )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
- {
|
|
- vcl::MenuInvalidator::AddMenuInvalidateListener(*getRefreshLinkInstance());
|
|
- }
|
|
-
|
|
assert(mbMenuBar);
|
|
SAL_INFO("vcl.unity", "GtkSalMenu set to frame");
|
|
mpFrame = static_cast< const GtkSalFrame* >( pFrame );
|
|
@@ -706,6 +661,7 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
|
|
void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar)
|
|
{
|
|
pMenuBar->HandleMenuActivateEvent(mpVCLMenu);
|
|
+ pMenuBar->HandleMenuDeActivateEvent(mpVCLMenu);
|
|
for ( size_t nPos = 0; nPos < maItems.size(); nPos++ )
|
|
{
|
|
GtkSalMenuItem *pSalItem = maItems[ nPos ];
|
|
@@ -717,11 +673,25 @@ void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar)
|
|
}
|
|
}
|
|
|
|
-void GtkSalMenu::Activate()
|
|
+void GtkSalMenu::Activate( const gchar* aMenuCommand )
|
|
{
|
|
if ( !mbMenuBar )
|
|
return;
|
|
- ActivateAllSubmenus(static_cast<MenuBar*>(mpVCLMenu));
|
|
+
|
|
+ if ( !aMenuCommand ) {
|
|
+ ActivateAllSubmenus( static_cast< MenuBar* >( mpVCLMenu ) );
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ int nDupsToSkip;
|
|
+ aMenuCommand = DetermineDupIndex(aMenuCommand, nDupsToSkip);
|
|
+ GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast<gchar*>(aMenuCommand), nDupsToSkip, TRUE );
|
|
+
|
|
+ if ( pSalSubMenu != nullptr ) {
|
|
+ MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu );
|
|
+ pMenuBar->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu );
|
|
+ pSalSubMenu->Update();
|
|
+ }
|
|
}
|
|
|
|
void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
|
|
--
|
|
2.5.0
|
|
|