[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - desktop/source sfx2/source

Ashod Nakashian (via logerrit) logerrit at kemper.freedesktop.org
Wed Dec 4 14:16:22 UTC 2019


 desktop/source/lib/init.cxx    |   18 +-----------
 sfx2/source/view/lokhelper.cxx |   58 +++++++++++++++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 24 deletions(-)

New commits:
commit 303d1e5bd3565b94ca342b832146beee815d1392
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed Dec 4 08:19:22 2019 -0500
Commit:     Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Wed Dec 4 15:15:37 2019 +0100

    LOK: don't send LOK notifications while switching views
    
    Changing the active view is done for virtually every
    LOK API, and in some cases simply changing the view
    results in a flurry of notifications that themselves
    caues further API calls that need to change the view.
    
    This moves the disabling of callbacks during setView
    to SfxLokHelper to make sure no view gets any
    notifications. This is needed because even when
    we disable notifications for the current view,
    the _other_ view(s) can still get notified as they
    lose their frame.
    
    Change-Id: Ia88a58d6a1162e48c40f4c4ce73c40ecb2c1fb7e
    Reviewed-on: https://gerrit.libreoffice.org/84417
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 949f8fe0e93e..5597f5be9bb4 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -4623,28 +4623,14 @@ static void doc_destroyView(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis
     SfxLokHelper::destroyView(nId);
 }
 
-static void doc_setView(LibreOfficeKitDocument* pThis, int nId)
+static void doc_setView(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/, int nId)
 {
     comphelper::ProfileZone aZone("doc_setView");
 
     SolarMutexGuard aGuard;
     SetLastExceptionMsg();
 
-    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
-    const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nId);
-    if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
-        handlerIt->second->disableCallbacks();
-
-    try
-    {
-        SfxLokHelper::setView(nId);
-    }
-    catch (const std::exception&)
-    {
-    }
-
-    if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
-        handlerIt->second->enableCallbacks();
+    SfxLokHelper::setView(nId);
 }
 
 static int doc_getView(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/)
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index e9c7248941fd..65f8e5090972 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -30,6 +30,34 @@
 
 using namespace com::sun::star;
 
+/// Used to disable callbacks.
+/// Needed to avoid recursion when switching views,
+/// which can cause clients to invoke LOKit API and
+/// implicitly set the view, which might cause an
+/// infinite recursion if not detected and prevented.
+class DisableCallbacks
+{
+public:
+    DisableCallbacks()
+    {
+        assert(m_nDisabled >= 0 && "Expected non-negative DisabledCallbacks state when disabling.");
+        ++m_nDisabled;
+    }
+
+    ~DisableCallbacks()
+    {
+        assert(m_nDisabled > 0 && "Expected positive DisabledCallbacks state when re-enabling.");
+        --m_nDisabled;
+    }
+
+    static bool disabled() { return m_nDisabled != 0; }
+
+private:
+    static int m_nDisabled;
+};
+
+int DisableCallbacks::m_nDisabled = 0;
+
 int SfxLokHelper::createView()
 {
     SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
@@ -77,6 +105,8 @@ void SfxLokHelper::setView(int nId)
     {
         if (static_cast<sal_Int32>(pViewShell->GetViewShellId()) == nViewShellId)
         {
+            DisableCallbacks dc;
+
             // update the current LOK language for the dialog tunneling
             comphelper::LibreOfficeKit::setLanguageTag(pViewShell->GetLOKLanguageTag());
 
@@ -162,6 +192,9 @@ static OString lcl_escapeQuotes(const OString &rStr)
 
 void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload)
 {
+    if (DisableCallbacks::disabled())
+        return;
+
     OString aPayload = OString("{ \"viewId\": \"") + OString::number(SfxLokHelper::getView(pThisView)) +
                        "\", \"part\": \"" + OString::number(pThisView->getPart()) +
                        "\", \"" + rKey + "\": \"" + lcl_escapeQuotes(rPayload) + "\" }";
@@ -171,7 +204,7 @@ void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const*
 
 void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload)
 {
-    if (SfxLokHelper::getViewsCount() <= 1)
+    if (SfxLokHelper::getViewsCount() <= 1 || DisableCallbacks::disabled())
         return;
 
     SfxViewShell* pViewShell = SfxViewShell::GetFirst();
@@ -204,7 +237,7 @@ namespace {
 
 void SfxLokHelper::sendUnoStatus(const SfxViewShell* pShell, const SfxItemSet* pSet)
 {
-    if (!pShell || !pSet)
+    if (!pShell || !pSet || DisableCallbacks::disabled())
         return;
 
     boost::property_tree::ptree aTree;
@@ -239,7 +272,7 @@ void SfxLokHelper::notifyWindow(const SfxViewShell* pThisView,
 {
     assert(pThisView);
 
-    if (SfxLokHelper::getViewsCount() <= 0 || nLOKWindowId == 0)
+    if (SfxLokHelper::getViewsCount() <= 0 || nLOKWindowId == 0 || DisableCallbacks::disabled())
         return;
 
     OStringBuffer aPayload;
@@ -262,6 +295,9 @@ void SfxLokHelper::notifyWindow(const SfxViewShell* pThisView,
 
 void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, const OString& rPayload)
 {
+    if (DisableCallbacks::disabled())
+        return;
+
     OStringBuffer aBuf;
     aBuf.append(rPayload);
     if (comphelper::LibreOfficeKit::isPartInInvalidation())
@@ -274,10 +310,7 @@ void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, const OStri
 
 void SfxLokHelper::notifyDocumentSizeChanged(SfxViewShell const* pThisView, const OString& rPayload, vcl::ITiledRenderable* pDoc, bool bInvalidateAll)
 {
-    if (!comphelper::LibreOfficeKit::isActive())
-        return;
-
-    if (!pDoc)
+    if (!pDoc || !comphelper::LibreOfficeKit::isActive() || DisableCallbacks::disabled())
         return;
 
     if (bInvalidateAll)
@@ -294,7 +327,7 @@ void SfxLokHelper::notifyDocumentSizeChanged(SfxViewShell const* pThisView, cons
 
 void SfxLokHelper::notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc, bool bInvalidateAll)
 {
-    if (!comphelper::LibreOfficeKit::isActive())
+    if (!comphelper::LibreOfficeKit::isActive() || DisableCallbacks::disabled())
         return;
 
     SfxViewShell* pViewShell = SfxViewShell::GetFirst();
@@ -307,6 +340,9 @@ void SfxLokHelper::notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc
 
 void SfxLokHelper::notifyVisCursorInvalidation(OutlinerViewShell const* pThisView, const OString& rRectangle, bool bMispelledWord, const OString& rHyperlink)
 {
+    if (DisableCallbacks::disabled())
+        return;
+
     OString sPayload;
     if (comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
     {
@@ -325,6 +361,9 @@ void SfxLokHelper::notifyVisCursorInvalidation(OutlinerViewShell const* pThisVie
 
 void SfxLokHelper::notifyAllViews(int nType, const OString& rPayload)
 {
+    if (DisableCallbacks::disabled())
+        return;
+
     const auto payload = rPayload.getStr();
     SfxViewShell* pViewShell = SfxViewShell::GetFirst();
     while (pViewShell)
@@ -336,6 +375,9 @@ void SfxLokHelper::notifyAllViews(int nType, const OString& rPayload)
 
 void SfxLokHelper::notifyContextChange(SfxViewShell const* pViewShell, const OUString& aApplication, const OUString& aContext)
 {
+    if (DisableCallbacks::disabled())
+        return;
+
     OStringBuffer aBuffer;
     aBuffer.append(OUStringToOString(aApplication.replace(' ', '_'), RTL_TEXTENCODING_UTF8));
     aBuffer.append(' ');


More information about the Libreoffice-commits mailing list