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

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