diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2016-02-07 17:53:40 +0200 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2016-02-15 12:08:07 +0000 |
commit | 2abdcfd641883f246fe78f2fbe38499c9382c059 (patch) | |
tree | afbe57205258c7371f732389deb33c33cd49d639 | |
parent | 7347248254595c082682180f7a1cfe768f5509a6 (diff) |
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.)
Change-Id: I96affa72412f3f38160fdca4b6efd20ca68d059f
Reviewed-on: https://gerrit.libreoffice.org/22369
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
-rw-r--r-- | framework/source/uielement/menubarmanager.cxx | 11 | ||||
-rw-r--r-- | include/vcl/menu.hxx | 9 | ||||
-rw-r--r-- | vcl/inc/salmenu.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtksalmenu.hxx | 4 | ||||
-rw-r--r-- | vcl/source/window/menu.cxx | 46 | ||||
-rw-r--r-- | vcl/unx/gtk/gloactiongroup.cxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk/gtkdata.cxx | 18 | ||||
-rw-r--r-- | vcl/unx/gtk/gtksalmenu.cxx | 62 |
8 files changed, 31 insertions, 122 deletions
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx index 871881728f53..d5ae1d6ea4bd 100644 --- a/framework/source/uielement/menubarmanager.cxx +++ b/framework/source/uielement/menubarmanager.cxx @@ -385,10 +385,6 @@ throw ( RuntimeException, std::exception ) OUString aFeatureURL = Event.FeatureURL.Complete; SolarMutexGuard aSolarGuard; - if ( m_bHasMenuBar ) - { - vcl::MenuInvalidator::Invalidated(); - } { if ( m_bDisposed ) return; @@ -487,6 +483,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 e28fbd9f9060..34847988207f 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -310,6 +310,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; @@ -404,13 +406,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 fba86a1fed59..d7930bbc39fe 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -77,6 +77,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 998a9257d699..18a2b4d27959 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -94,11 +94,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 3be6868a9117..b6b1ce5db7f9 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -2309,6 +2309,12 @@ bool Menu::HasValidEntries( bool bCheckPopups ) return bValidEntries; } +void Menu::UpdateNativeMenu() +{ + if ( ImplGetSalMenu() ) + ImplGetSalMenu()->Update(); +} + void Menu::MenuBarKeyInput(const KeyEvent&) { } @@ -3221,44 +3227,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 838538801ca7..e710809ca6cb 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 e6121f7cba76..fa65259e8601 100644 --- a/vcl/unx/gtk/gtkdata.cxx +++ b/vcl/unx/gtk/gtkdata.cxx @@ -1027,22 +1027,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 d8211eb5b865..7b9f7eda6cdd 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 ); @@ -674,6 +629,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 ]; @@ -685,11 +641,23 @@ 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; + } + + GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast<gchar*>(aMenuCommand), TRUE ); + + if ( pSalSubMenu != nullptr ) { + MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu ); + pMenuBar->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu ); + pSalSubMenu->Update(); + } } void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) |