framework/source/uielement/menubarmanager.cxx |    7 +++-
 include/vcl/helper.hxx                        |    3 +
 include/vcl/menu.hxx                          |   11 ++++++
 vcl/source/window/menu.cxx                    |   17 ++++++++++
 vcl/unx/gtk/window/gtksalmenu.cxx             |   43 ++++++++++++++++++++++++++
 5 files changed, 80 insertions(+), 1 deletion(-)

New commits:
commit eda624641b34a7d4315388c8ec1aebe44f63982e
Author: Bjoern Michaelsen <bjoern.michael...@canonical.com>
Date:   Sun May 18 14:28:39 2014 +0200

    lp#1296715: refresh invalidated menus
    
    - so we need to be a StatusListener in framework after all
    - we ware updating all menus for now, instead of just one
    - this would have a hugh performance hit when there is much change to the 
menu
    - thus we just invalidate the menu and update with all changes after 100ms 
once
    
    Change-Id: I48cda968cf0ae1eae0421b3424bb3e5830817e84

diff --git a/framework/source/uielement/menubarmanager.cxx 
b/framework/source/uielement/menubarmanager.cxx
index de31c3c..3412251 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -67,6 +67,7 @@
 #include <toolkit/helper/vclunohelper.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/window.hxx>
+#include <vcl/menu.hxx>
 #include <vcl/settings.hxx>
 #include <osl/mutex.hxx>
 #include <osl/file.hxx>
@@ -430,6 +431,10 @@ throw ( RuntimeException, std::exception )
 
     SolarMutexGuard aSolarGuard;
     {
+        vcl::MenuInvalidator aInvalidator;
+        aInvalidator.Invalidated();
+    }
+    {
         if ( m_bDisposed )
             return;
 
@@ -914,9 +919,9 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu )
 
                                 if ( !bPopupMenu )
                                 {
-                                    // We need only an update to reflect the 
current state
                                     xMenuItemDispatch->addStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
                                     xMenuItemDispatch->removeStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
+                                    xMenuItemDispatch->addStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
                                 }
                             }
                             else if ( !bPopupMenu )
diff --git a/include/vcl/helper.hxx b/include/vcl/helper.hxx
index cc368dd..49c4197 100644
--- a/include/vcl/helper.hxx
+++ b/include/vcl/helper.hxx
@@ -23,6 +23,7 @@
 #include <list>
 
 #include <vcl/dllapi.h>
+#include <vcl/vclevent.hxx>
 
 #include <rtl/ustring.hxx>
 
@@ -54,6 +55,8 @@ enum whichOfficePath { InstallationRootPath, UserPath, 
ConfigPath };
 OUString VCL_DLLPUBLIC getOfficePath( enum whichOfficePath ePath );
 } // namespace
 
+
+bool VCL_DLLPUBLIC GetMenuInvalidateListeners();
 #endif // INCLUDED_VCL_HELPER_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 9f31b20..ac3c84b 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -359,6 +359,17 @@ public:
 };
 
 
+namespace vcl
+{
+    class VCL_DLLPUBLIC MenuInvalidator
+    {
+        public:
+            MenuInvalidator();
+            VclEventListeners2* GetMenuInvalidateListeners();
+            void Invalidated();
+    };
+}
+
 // - MenuBar -
 
 
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 9a7e73b..73e5668 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -6130,4 +6130,21 @@ ImplMenuDelData::~ImplMenuDelData()
         const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this );
 }
 
+namespace vcl
+{
+    MenuInvalidator::MenuInvalidator() {};
+
+    static VclEventListeners2* pMenuInvalidateListeners = NULL;
+    VclEventListeners2* MenuInvalidator::GetMenuInvalidateListeners()
+    {
+        if(!pMenuInvalidateListeners)
+            pMenuInvalidateListeners = new VclEventListeners2();
+        return pMenuInvalidateListeners;
+    }
+    void MenuInvalidator::Invalidated()
+    {
+        VclSimpleEvent aEvent(0);
+        GetMenuInvalidateListeners()->callListeners(&aEvent);
+    };
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx 
b/vcl/unx/gtk/window/gtksalmenu.cxx
index 6143e6c..dcbcd78 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -11,6 +11,8 @@
 
 #ifdef ENABLE_GMENU_INTEGRATION
 
+#include <generic/gendata.hxx>
+#include <unx/saldisp.hxx>
 #include <unx/gtk/glomenu.h>
 #include <unx/gtk/gloactiongroup.h>
 #include <vcl/menu.hxx>
@@ -448,9 +450,50 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, 
SalMenu* pSubMenu, unsig
     pItem->mpSubMenu = pGtkSubMenu;
 }
 
+static bool bInvalidMenus = false;
+static gboolean RefreshMenusUnity(gpointer)
+{
+    SalDisplay* pSalDisplay = GetGenericData()->GetSalDisplay();
+    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();
+        }
+    }
+    bInvalidMenus = false;
+    return FALSE;
+}
+
+static long RefreshMenusUnity(void*, void*)
+{
+    if(!bInvalidMenus) {
+        g_timeout_add(10, &RefreshMenusUnity, NULL);
+        bInvalidMenus = true;
+    }
+    return 0;
+}
+
+static Link* getRefreshLinkInstance()
+{
+    static Link* pLink = NULL;
+    if(!pLink) {
+        pLink = new Link(NULL, &RefreshMenusUnity);
+    }
+    return pLink;
+}
+
 void GtkSalMenu::SetFrame( const SalFrame* pFrame )
 {
     SolarMutexGuard aGuard;
+    {
+        vcl::MenuInvalidator aInvalidator;
+        
aInvalidator.GetMenuInvalidateListeners()->addListener(*getRefreshLinkInstance());
+    }
 
     assert(mbMenuBar);
     SAL_INFO("vcl.unity", "GtkSalMenu set to frame");
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to