Blame SOURCES/0001-tdf-97665-Let-s-hope-that-over-activation-isn-t-real.patch

f325b2
From fcab9d2bcef3997790f3ae68521444cbaa0c5b29 Mon Sep 17 00:00:00 2001
f325b2
From: Maxim Monastirsky <momonasmon@gmail.com>
f325b2
Date: Sun, 7 Feb 2016 17:53:40 +0200
f325b2
Subject: [PATCH] tdf#97665 Let's hope that over activation isn't really needed
f325b2
f325b2
- MenuBarManager::Activate has a check for duplicate activation,
f325b2
  which makes the second activation attempt fail. Removing this
f325b2
  check or deactivating after each activation will likely affect
f325b2
  performance even more, but on the other hand should solve
f325b2
  lp#1296715, which was the main reason of the over activation
f325b2
  in the first place. So let's activate only one menu at a time,
f325b2
  and do full activation only on the initial update.
f325b2
f325b2
- Unfortunately the HUD activation callback doesn't work, so
f325b2
  we still have to keep active status listener for all menu
f325b2
  items. (Which is BTW against the recommendation in
f325b2
  XPopupMenuController::updatePopupMenu IDL doc. Fortunately
f325b2
  the performance problem hardly noticeable on modern hw.)
f325b2
f325b2
Reviewed-on: https://gerrit.libreoffice.org/22369
f325b2
Tested-by: Jenkins <ci@libreoffice.org>
f325b2
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
f325b2
(cherry picked from commit 2abdcfd641883f246fe78f2fbe38499c9382c059)
f325b2
f325b2
Change-Id: I96affa72412f3f38160fdca4b6efd20ca68d059f
f325b2
---
f325b2
 framework/inc/uielement/menubarmanager.hxx         |  4 +-
f325b2
 .../source/uielement/generictoolbarcontroller.cxx  |  2 +-
f325b2
 framework/source/uielement/menubarmanager.cxx      | 13 ++---
f325b2
 include/vcl/menu.hxx                               |  9 +---
f325b2
 vcl/inc/salmenu.hxx                                |  1 +
f325b2
 vcl/inc/unx/gtk/gtksalmenu.hxx                     |  4 +-
f325b2
 vcl/source/window/menu.cxx                         | 20 +++-----
f325b2
 vcl/unx/gtk/window/gloactiongroup.cxx              |  2 +-
f325b2
 vcl/unx/gtk/window/gtksalmenu.cxx                  | 59 ++++++----------------
f325b2
 9 files changed, 38 insertions(+), 76 deletions(-)
f325b2
f325b2
diff --git a/framework/inc/uielement/menubarmanager.hxx b/framework/inc/uielement/menubarmanager.hxx
f325b2
index b72d515..99f0df0 100644
f325b2
--- a/framework/inc/uielement/menubarmanager.hxx
f325b2
+++ b/framework/inc/uielement/menubarmanager.hxx
f325b2
@@ -95,7 +95,8 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener
f325b2
             const OUString& aModuleIdentifier,
f325b2
             Menu* pMenu,
f325b2
             bool bDelete,
f325b2
-            bool bDeleteChildren );
f325b2
+            bool bDeleteChildren,
f325b2
+            bool bHasMenuBar = true );
f325b2
 
f325b2
         virtual ~MenuBarManager();
f325b2
 
f325b2
@@ -217,6 +218,7 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener
f325b2
         bool                                                                               m_bRetrieveImages : 1,
f325b2
                                                                                                m_bAcceleratorCfg : 1;
f325b2
         bool                                                                               m_bModuleIdentified;
f325b2
+        bool                                                                            m_bHasMenuBar;
f325b2
         OUString                                                                        m_aMenuItemCommand;
f325b2
         OUString                                                                        m_aModuleIdentifier;
f325b2
         Menu*                                                                                  m_pVCLMenu;
f325b2
diff --git a/framework/source/uielement/generictoolbarcontroller.cxx b/framework/source/uielement/generictoolbarcontroller.cxx
f325b2
index 183da37..6e83c54 100644
f325b2
--- a/framework/source/uielement/generictoolbarcontroller.cxx
f325b2
+++ b/framework/source/uielement/generictoolbarcontroller.cxx
f325b2
@@ -348,7 +348,7 @@ MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::Runtime
f325b2
         Reference< XDispatchProvider > xDispatch;
f325b2
         Reference< XURLTransformer > xURLTransformer = URLTransformer::create( m_xContext );
f325b2
         pMenu = new Toolbarmenu();
f325b2
-        m_xMenuManager.set( new MenuBarManager( m_xContext, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, true, true ) );
f325b2
+        m_xMenuManager.set( new MenuBarManager( m_xContext, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, true, true, false ) );
f325b2
         if (m_xMenuManager.is())
f325b2
         {
f325b2
             MenuBarManager& rMgr = dynamic_cast<MenuBarManager&>(*m_xMenuManager.get());
f325b2
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
f325b2
index 13e145f..2096408 100644
f325b2
--- a/framework/source/uielement/menubarmanager.cxx
f325b2
+++ b/framework/source/uielement/menubarmanager.cxx
f325b2
@@ -135,12 +135,13 @@ MenuBarManager::MenuBarManager(
f325b2
     const Reference< XURLTransformer >& _xURLTransformer,
f325b2
     const Reference< XDispatchProvider >& rDispatchProvider,
f325b2
     const OUString& rModuleIdentifier,
f325b2
-    Menu* pMenu, bool bDelete, bool bDeleteChildren ):
f325b2
+    Menu* pMenu, bool bDelete, bool bDeleteChildren, bool bHasMenuBar ):
f325b2
     OWeakObject()
f325b2
     , m_bDisposed( false )
f325b2
     , m_bRetrieveImages( false )
f325b2
     , m_bAcceleratorCfg( false )
f325b2
     , m_bModuleIdentified( false )
f325b2
+    , m_bHasMenuBar( bHasMenuBar )
f325b2
     , m_aListenerContainer( m_mutex )
f325b2
     , m_xContext(rxContext)
f325b2
     , m_xURLTransformer(_xURLTransformer)
f325b2
@@ -163,6 +164,7 @@ MenuBarManager::MenuBarManager(
f325b2
     , m_bRetrieveImages( true )
f325b2
     , m_bAcceleratorCfg( false )
f325b2
     , m_bModuleIdentified( false )
f325b2
+    , m_bHasMenuBar( true )
f325b2
     , m_aListenerContainer( m_mutex )
f325b2
     , m_xContext(rxContext)
f325b2
     , m_xURLTransformer(_xURLTransformer)
f325b2
@@ -392,9 +394,6 @@ throw ( RuntimeException, std::exception )
f325b2
 
f325b2
     SolarMutexGuard aSolarGuard;
f325b2
     {
f325b2
-        vcl::MenuInvalidator::Invalidated();
f325b2
-    }
f325b2
-    {
f325b2
         if ( m_bDisposed )
f325b2
             return;
f325b2
 
f325b2
@@ -492,6 +491,8 @@ throw ( RuntimeException, std::exception )
f325b2
                 pMenuItemHandler->xMenuItemDispatch.clear();
f325b2
             }
f325b2
         }
f325b2
+        if ( m_bHasMenuBar && !m_bActive )
f325b2
+            m_pVCLMenu->UpdateNativeMenu();
f325b2
     }
f325b2
 }
f325b2
 
f325b2
@@ -896,8 +897,8 @@ IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool )
f325b2
                                 if ( !bPopupMenu )
f325b2
                                 {
f325b2
                                     xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
f325b2
-                                    xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
f325b2
-                                    xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
f325b2
+                                    if ( !m_bHasMenuBar )
f325b2
+                                        xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
f325b2
                                 }
f325b2
                             }
f325b2
                             else if ( !bPopupMenu )
f325b2
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
f325b2
index 2a4abcf..a44f2a8 100644
f325b2
--- a/include/vcl/menu.hxx
f325b2
+++ b/include/vcl/menu.hxx
f325b2
@@ -308,6 +308,8 @@ public:
f325b2
     void RemoveDisabledEntries( bool bCheckPopups = true, bool bRemoveEmptyPopups = false );
f325b2
     bool HasValidEntries( bool bCheckPopups = true );
f325b2
 
f325b2
+    void UpdateNativeMenu();
f325b2
+
f325b2
     void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
f325b2
     OUString GetItemText( sal_uInt16 nItemId ) const;
f325b2
 
f325b2
@@ -413,13 +415,6 @@ public:
f325b2
 };
f325b2
 
f325b2
 
f325b2
-namespace vcl { namespace MenuInvalidator {
f325b2
-
f325b2
-VCL_DLLPUBLIC VclEventListeners2* GetMenuInvalidateListeners();
f325b2
-VCL_DLLPUBLIC void Invalidated();
f325b2
-
f325b2
-}}
f325b2
-
f325b2
 class VCL_DLLPUBLIC MenuBar : public Menu
f325b2
 {
f325b2
     Link<> maCloseHdl;
f325b2
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
f325b2
index aaea364..182958a 100644
f325b2
--- a/vcl/inc/salmenu.hxx
f325b2
+++ b/vcl/inc/salmenu.hxx
f325b2
@@ -80,6 +80,7 @@ public:
f325b2
     virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, FloatWinPopupFlags nFlags);
f325b2
     virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure
f325b2
     virtual void RemoveMenuBarButton( sal_uInt16 nId );
f325b2
+    virtual void Update() {}
f325b2
 
f325b2
     // TODO: implement show/hide for the Win/Mac VCL native backends
f325b2
     virtual void ShowItem( unsigned nPos, bool bShow ) { EnableItem( nPos, bShow ); }
f325b2
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
f325b2
index e74de22..a8f289c 100644
f325b2
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
f325b2
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
f325b2
@@ -97,11 +97,11 @@ public:
f325b2
     void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const vcl::KeyCode& rKeyCode, const OUString& rKeyName );
f325b2
 
f325b2
     void                        DispatchCommand( gint itemId, const gchar* aCommand );
f325b2
-    void                        Activate();
f325b2
+    void                        Activate( const gchar* aMenuCommand = nullptr );
f325b2
     void                        Deactivate( const gchar* aMenuCommand );
f325b2
     void                        Display( bool bVisible );
f325b2
     bool                        PrepUpdate();
f325b2
-    void                        Update();           // Update this menu only.
f325b2
+    virtual void                Update() override;  // Update this menu only.
f325b2
     void                        UpdateFull();       // Update full menu hierarchy from this menu.
f325b2
 };
f325b2
 
f325b2
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
f325b2
index cb83637..70e5ea1 100644
f325b2
--- a/vcl/source/window/menu.cxx
f325b2
+++ b/vcl/source/window/menu.cxx
f325b2
@@ -2295,6 +2295,12 @@ sal_uLong Menu::DeactivateMenuBar(sal_uLong nFocusId)
f325b2
     return nFocusId;
f325b2
 }
f325b2
 
f325b2
+void Menu::UpdateNativeMenu()
f325b2
+{
f325b2
+    if ( ImplGetSalMenu() )
f325b2
+        ImplGetSalMenu()->Update();
f325b2
+}
f325b2
+
f325b2
 void Menu::MenuBarKeyInput(const KeyEvent&)
f325b2
 {
f325b2
 }
f325b2
@@ -3200,18 +3206,4 @@ ImplMenuDelData::~ImplMenuDelData()
f325b2
         const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this );
f325b2
 }
f325b2
 
f325b2
-namespace vcl { namespace MenuInvalidator {
f325b2
-    static VclEventListeners2* pMenuInvalidateListeners = NULL;
f325b2
-    VclEventListeners2* GetMenuInvalidateListeners()
f325b2
-    {
f325b2
-        if(!pMenuInvalidateListeners)
f325b2
-            pMenuInvalidateListeners = new VclEventListeners2();
f325b2
-        return pMenuInvalidateListeners;
f325b2
-    }
f325b2
-    void Invalidated()
f325b2
-    {
f325b2
-        VclSimpleEvent aEvent(0);
f325b2
-        GetMenuInvalidateListeners()->callListeners(&aEvent);
f325b2
-    };
f325b2
-} }
f325b2
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
f325b2
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
f325b2
index 23307fd..2066abd 100644
f325b2
--- a/vcl/unx/gtk/window/gloactiongroup.cxx
f325b2
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
f325b2
@@ -201,7 +201,7 @@ g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
f325b2
         SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
f325b2
 
f325b2
         if (bState)
f325b2
-            pSalMenu->Activate();
f325b2
+            pSalMenu->Activate (action_name);
f325b2
         else
f325b2
             pSalMenu->Deactivate (action_name);
f325b2
     }
f325b2
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
f325b2
index 4a18999..b07b8e5 100644
f325b2
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
f325b2
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
f325b2
@@ -371,51 +371,9 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig
f325b2
     pItem->mpSubMenu = pGtkSubMenu;
f325b2
 }
f325b2
 
f325b2
-static bool bInvalidMenus = false;
f325b2
-static gboolean RefreshMenusUnity(gpointer)
f325b2
-{
f325b2
-    SolarMutexGuard g;
f325b2
-
f325b2
-    SalDisplay* pSalDisplay = vcl_sal::getSalDisplay(GetGenericData());
f325b2
-    std::list< SalFrame* >::const_iterator pSalFrame = pSalDisplay->getFrames().begin();
f325b2
-    std::list< SalFrame* >::const_iterator pEndSalFrame = pSalDisplay->getFrames().end();
f325b2
-    for(; pSalFrame != pEndSalFrame; ++pSalFrame) {
f325b2
-        const GtkSalFrame* pGtkSalFrame = static_cast< const GtkSalFrame* >( *pSalFrame );
f325b2
-        GtkSalFrame* pFrameNonConst = const_cast<GtkSalFrame*>(pGtkSalFrame);
f325b2
-        GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*>(pFrameNonConst->GetMenu());
f325b2
-        if(pSalMenu) {
f325b2
-            pSalMenu->Activate();
f325b2
-            pSalMenu->UpdateFull();
f325b2
-        }
f325b2
-    }
f325b2
-    bInvalidMenus = false;
f325b2
-    return FALSE;
f325b2
-}
f325b2
-
f325b2
-static long RefreshMenusUnity(void*, void*)
f325b2
-{
f325b2
-    if(!bInvalidMenus) {
f325b2
-        g_timeout_add(10, &RefreshMenusUnity, NULL);
f325b2
-        bInvalidMenus = true;
f325b2
-    }
f325b2
-    return 0;
f325b2
-}
f325b2
-
f325b2
-static Link<>* getRefreshLinkInstance()
f325b2
-{
f325b2
-    static Link<>* pLink = NULL;
f325b2
-    if(!pLink) {
f325b2
-        pLink = new Link<>(NULL, &RefreshMenusUnity);
f325b2
-    }
f325b2
-    return pLink;
f325b2
-}
f325b2
-
f325b2
 void GtkSalMenu::SetFrame( const SalFrame* pFrame )
f325b2
 {
f325b2
     SolarMutexGuard aGuard;
f325b2
-    {
f325b2
-        vcl::MenuInvalidator::GetMenuInvalidateListeners()->addListener(*getRefreshLinkInstance());
f325b2
-    }
f325b2
 
f325b2
     assert(mbMenuBar);
f325b2
     SAL_INFO("vcl.unity", "GtkSalMenu set to frame");
f325b2
@@ -671,6 +629,7 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
f325b2
 void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar)
f325b2
 {
f325b2
     pMenuBar->HandleMenuActivateEvent(mpVCLMenu);
f325b2
+    pMenuBar->HandleMenuDeActivateEvent(mpVCLMenu);
f325b2
     for ( sal_uInt16 nPos = 0; nPos < maItems.size(); nPos++ )
f325b2
     {
f325b2
         GtkSalMenuItem *pSalItem = maItems[ nPos ];
f325b2
@@ -682,11 +641,23 @@ void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar)
f325b2
     }
f325b2
 }
f325b2
 
f325b2
-void GtkSalMenu::Activate()
f325b2
+void GtkSalMenu::Activate( const gchar* aMenuCommand )
f325b2
 {
f325b2
     if ( !mbMenuBar )
f325b2
         return;
f325b2
-    ActivateAllSubmenus(static_cast<MenuBar*>(mpVCLMenu));
f325b2
+
f325b2
+    if ( !aMenuCommand ) {
f325b2
+        ActivateAllSubmenus( static_cast< MenuBar* >( mpVCLMenu ) );
f325b2
+        return;
f325b2
+    }
f325b2
+
f325b2
+    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast<gchar*>(aMenuCommand), TRUE );
f325b2
+
f325b2
+    if ( pSalSubMenu != nullptr ) {
f325b2
+        MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu );
f325b2
+        pMenuBar->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu );
f325b2
+        pSalSubMenu->Update();
f325b2
+    }
f325b2
 }
f325b2
 
f325b2
 void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
f325b2
-- 
f325b2
2.7.1
f325b2