From a32e2cfcb4ea268e4f5a6e99a7047f669e9dfbaf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Thu, 11 Aug 2016 16:11:50 +0100
Subject: [PATCH] fix insensitive combobox never getting sensitive

---
 ...box-never-becomes-sensitive-if-it-st.patch | 132 ++++++++++++++++++
 libreoffice.spec                              |   1 +
 2 files changed, 133 insertions(+)
 create mode 100644 0001-gtk3-style-combobox-never-becomes-sensitive-if-it-st.patch

diff --git a/0001-gtk3-style-combobox-never-becomes-sensitive-if-it-st.patch b/0001-gtk3-style-combobox-never-becomes-sensitive-if-it-st.patch
new file mode 100644
index 0000000..ad06956
--- /dev/null
+++ b/0001-gtk3-style-combobox-never-becomes-sensitive-if-it-st.patch
@@ -0,0 +1,132 @@
+From 84ffcd0df7dbf9ddfbb3f9f165b172ab5271466d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Thu, 11 Aug 2016 14:47:56 +0100
+Subject: [PATCH] gtk3: style combobox never becomes sensitive if it starts
+ insensitive
+
+Place cursor inside a protected section in writer, e.g. a table of contents.
+Save, and reload. The cursor starts inside the protected section.
+
+With the native gtk3 menubar the styles dropdown in the top left is
+grayed out. Moving the cursor outside the protected area does not
+make it active again.
+
+Under gen it works fine.
+
+*Extensive* debugging shows that there is a cache based on the numeric
+slots of commands to their dispatcher, e.g. SfxBindings::GetStateCache
+so if you SfxBindings::QueryState for a given uno command then it will
+look up what dispatcher to listen to by slot id.
+
+This StyleApply command appears in a number of places in LibreOffice,
+the toolbar as .uno:StyleApply, *but* .uno:StyleApply?A_Bunch_Of_Args
+elsewhere in the menus.
+
+In the gtk3 plugin it so happens that all the menu items are parsed
+and listeners set before the toolbar is created. While in the gen
+plugin the toolbar is created, and the menus are on-demand later.
+
+So under gen the dispatcher is created for ".uno:StyleApply" and
+other .uno:StyleApply?* go through that one. Under gtk3 the dispatcher
+is created for ".uno:StyleApply?A_Bunch_Of_Args".
+
+So, when SfxDispatchController_Impl::StateChanged is called, the
+aDispatchURL.Complete argument is ".uno:StyleApply?A_Bunch_Of_Args", but,
+because it was supplied as a cached result from the shared slot, some
+listeners have been added that want to listen to ".uno:StyleApply".
+The name doesn't match, so looking up the listeners listening to the
+command with argument finds nothing, so those listeners on the name
+without argument are not fired.
+
+Here I look up all the property names that the listeners were added to listen
+to (1 in all cases I've seen in casual testing) and if either the name with
+full args or no args matches then inform that listener that something has
+changed.
+
+Change-Id: Ib5858ccb16dce41e249ee911751053fd277551b8
+(cherry picked from commit d9bf3df8143779f0caea2094efa4891370038977)
+
+factor this status change code out
+
+no logic change intended
+
+Change-Id: I74e58f61fdb5d9684384dac5ba9803fc2d411ca7
+(cherry picked from commit f2a60c783a8099f07b05f25301833f405c161d59)
+---
+ include/sfx2/unoctitm.hxx        |  2 ++
+ sfx2/source/control/unoctitm.cxx | 39 +++++++++++++++++++++++++--------------
+ 2 files changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/include/sfx2/unoctitm.hxx b/include/sfx2/unoctitm.hxx
+index 8d58738..423c629 100644
+--- a/include/sfx2/unoctitm.hxx
++++ b/include/sfx2/unoctitm.hxx
+@@ -126,6 +126,8 @@ class SfxDispatchController_Impl : public SfxControllerItem
+                                              css::uno::Sequence< css::beans::PropertyValue >& rArgs );
+     static SfxMapUnit   GetCoreMetric( SfxItemPool& rPool, sal_uInt16 nSlot );
+ 
++    void                sendStatusChanged(const OUString& rURL, const css::frame::FeatureStateEvent& rEvent);
++
+ public:
+                         SfxDispatchController_Impl( SfxOfficeDispatch*                 pDisp,
+                                                     SfxBindings*                       pBind,
+diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
+index a2eaff9..7ed25a4 100644
+--- a/sfx2/source/control/unoctitm.cxx
++++ b/sfx2/source/control/unoctitm.cxx
+@@ -826,6 +826,25 @@ void SAL_CALL SfxDispatchController_Impl::addStatusListener(const css::uno::Refe
+     aListener->statusChanged( aEvent );
+ }
+ 
++void SfxDispatchController_Impl::sendStatusChanged(const OUString& rURL, const css::frame::FeatureStateEvent& rEvent)
++{
++    ::cppu::OInterfaceContainerHelper* pContnr = pDispatch->GetListeners().getContainer(rURL);
++    if (!pContnr)
++        return;
++    ::cppu::OInterfaceIteratorHelper aIt(*pContnr);
++    while (aIt.hasMoreElements())
++    {
++        try
++        {
++            static_cast<css::frame::XStatusListener*>(aIt.next())->statusChanged(rEvent);
++        }
++        catch (const css::uno::RuntimeException&)
++        {
++            aIt.remove();
++        }
++    }
++}
++
+ void SfxDispatchController_Impl::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState, SfxSlotServer* pSlotServ )
+ {
+     if ( !pDispatch )
+@@ -904,20 +923,12 @@ void SfxDispatchController_Impl::StateChanged( sal_uInt16 nSID, SfxItemState eSt
+                     pDispatcher->GetFrame()->GetObjectShell(), aEvent);
+         }
+ 
+-        ::cppu::OInterfaceContainerHelper* pContnr = pDispatch->GetListeners().getContainer ( aDispatchURL.Complete );
+-        if (pContnr) {
+-            ::cppu::OInterfaceIteratorHelper aIt( *pContnr );
+-            while( aIt.hasMoreElements() )
+-            {
+-                try
+-                {
+-                    static_cast< css::frame::XStatusListener *>(aIt.next())->statusChanged( aEvent );
+-                }
+-                catch (const css::uno::RuntimeException&)
+-                {
+-                    aIt.remove();
+-                }
+-            }
++        Sequence< OUString > seqNames = pDispatch->GetListeners().getContainedTypes();
++        sal_Int32 nLength = seqNames.getLength();
++        for (sal_Int32 i = 0; i < nLength; ++i)
++        {
++            if (seqNames[i] == aDispatchURL.Main || seqNames[i] == aDispatchURL.Complete)
++                sendStatusChanged(seqNames[i], aEvent);
+         }
+     }
+ }
+-- 
+2.7.4
+
diff --git a/libreoffice.spec b/libreoffice.spec
index f469069..50690d4 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -243,6 +243,7 @@ Patch13: 0001-rhbz-1351292-correctly-set-edit-mode.patch
 Patch14: 0001-Related-rhbz-1351369-gtk3-clipboards-have-to-live-to.patch
 Patch15: 0001-Related-rhbz-1065807-recover-using-xdg-templates-and.patch
 Patch16: 0001-curl-7.50.0-has-CURL-as-typedef-struct-Curl_easy.patch
+Patch17: 0001-gtk3-style-combobox-never-becomes-sensitive-if-it-st.patch
 
 %if 0%{?rhel}
 # not upstreamed