compilerplugins/clang/badstatics.cxx        |    1 
 include/sfx2/notebookbar/SfxNotebookBar.hxx |    3 
 sfx2/source/appl/appserv.cxx                |    4 -
 sfx2/source/control/dispatch.cxx            |    3 
 sfx2/source/notebookbar/SfxNotebookBar.cxx  |   89 ++++++++++++++++++----------
 5 files changed, 69 insertions(+), 31 deletions(-)

New commits:
commit b9159cf17ba61cb78c45f7223027f3e47126643b
Author:     Szymon Kłos <[email protected]>
AuthorDate: Sat Nov 4 15:08:14 2023 +0100
Commit:     Szymon Kłos <[email protected]>
CommitDate: Mon Nov 6 10:04:39 2023 +0100

    lok: notebookbar: query SID_NOTEBOOKBAR only when requested to switch UI
    
    commit 5bd2931b57a6cb4ac1f39d7ddae874ac693cfab0
    tdf#102063 Notebookbar wont appear on launch
    
    introduced some Query hack to SfxDispatcher::Update_Impl what
    causes many updates on lots of different actions.
    It breaks multi-view state of notebookbar in LOK case,
    so don't do that. It should be reviewed for regular case too.
    
    Change-Id: I8f26bddc6cff991c56a1172893d83b90fb225acd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158937
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <[email protected]>

diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index 5b0ef2ca491f..d58b62a9bf3b 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -805,7 +805,7 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
 
                 aCurrentMode = comphelper::getString( aAppNode.getNodeValue( 
"Active" ) );
 
-                if ( aCurrentMode == aNewName )
+                if ( !comphelper::LibreOfficeKit::isActive() && aCurrentMode 
== aNewName )
                 {
                     bDone = true;
                     break;
@@ -931,6 +931,8 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
                     // Show/Hide the Notebookbar
                     const SfxStringItem pItem(SID_NOTEBOOKBAR, aNewName);
                     pViewFrame->GetDispatcher()->ExecuteList(SID_NOTEBOOKBAR, 
SfxCallMode::SYNCHRON, {&pItem});
+                    const SfxPoolItem *pNbItem;
+                    pViewFrame->GetDispatcher()->QueryState(SID_NOTEBOOKBAR, 
pNbItem);
 
                     // Show toolbars
                     for ( const OUString& rName : 
std::as_const(aMandatoryToolbars) )
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 6a492bffda7e..9134f8da574d 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -1120,7 +1120,8 @@ void SfxDispatcher::Update_Impl( bool bForce )
     if ( xLayoutManager.is() )
         xLayoutManager->unlock();
 
-    if ( SfxViewShell::Current() && SfxViewShell::Current()->GetDispatcher() )
+    if ( !comphelper::LibreOfficeKit::isActive() &&
+        SfxViewShell::Current() && SfxViewShell::Current()->GetDispatcher() )
     {
         const SfxPoolItem *pItem;
         SfxViewShell::Current()->GetDispatcher()->QueryState(SID_NOTEBOOKBAR, 
pItem);
commit 6bf428d354349995f7a20e6ce38a47c238911abe
Author:     Szymon Kłos <[email protected]>
AuthorDate: Sat Nov 4 12:05:16 2023 +0100
Commit:     Szymon Kłos <[email protected]>
CommitDate: Mon Nov 6 10:04:31 2023 +0100

    lok: notebookbar: handle multiple sessions
    
    This fixes regression from commit db5a78c8ab1eae30e442151f07b0dc4dcd017550
    lok: notebookbar: don't recreate toolbars too often
    
    When we had 2 sessions with notebookbar and one of them switched
    to compact mode - other session's notebookbar didn't work.
    
    Before previous change we recreated notebookbar and its welded wrapper
    on every StateMethod call for LOK case. So when it become destroyed
    we made it working again. But now we need to introduce better management
    and not rely on single instence we get from SystemWindow.
    
    Also it's bad idea to rely 100% on SfxNotebookBar::IsActive in LOK
    case as when other view will turn notebookbar off, but QueryState
    will be trigerred in our session - we will think that it should be
    destroyed (it reads config state which is shared between views).
    So trust only "true" value (it happens after calling SID_TOOLBAR_MODE),
    but destroy notebookbar only after explicit call of
    SfxNotebookBar::CloseMethod. It seems to have good result when tested
    with multiple views in Online. Maybe we can track Notebookbar state
    per view later to make things simpler in LOK case.
    
    Change-Id: Ie739c6441ca05884b0ef20bff23751467706b562
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158936
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <[email protected]>

diff --git a/compilerplugins/clang/badstatics.cxx 
b/compilerplugins/clang/badstatics.cxx
index f22dabac9b48..328218086453 100644
--- a/compilerplugins/clang/badstatics.cxx
+++ b/compilerplugins/clang/badstatics.cxx
@@ -211,6 +211,7 @@ public:
                 || name == "s_aLOKWeldBuildersMap" // LOK only, similar case 
as above
                 || name == "s_aLOKPopupsMap" // LOK only, similar case as above
                 || name == "m_pNotebookBarWeldedWrapper" // LOK only, warning 
about map's key, no VCL cleanup performed
+                || name == "m_pNotebookBarInstance" // LOK only case, when 
notebookbar is closed - VclPtr instance is removed
                 || name == "gStaticManager" // vcl/source/graphic/Manager.cxx 
- stores non-owning pointers
                 || name == "aThreadedInterpreterPool"    // 
ScInterpreterContext(Pool), not owning
                 || name == "aNonThreadedInterpreterPool" // 
ScInterpreterContext(Pool), not owning
diff --git a/include/sfx2/notebookbar/SfxNotebookBar.hxx 
b/include/sfx2/notebookbar/SfxNotebookBar.hxx
index 96f5805f50e0..7bf34d1cbf7e 100644
--- a/include/sfx2/notebookbar/SfxNotebookBar.hxx
+++ b/include/sfx2/notebookbar/SfxNotebookBar.hxx
@@ -12,6 +12,7 @@
 
 #include <sfx2/dllapi.h>
 #include <rtl/ustring.hxx>
+#include <vcl/notebookbar/notebookbar.hxx>
 #include <vcl/WeldedTabbedNotebookbar.hxx>
 #include <vcl/EnumContext.hxx>
 
@@ -76,8 +77,10 @@ private:
 
     static std::map<const SfxViewShell*, 
std::shared_ptr<WeldedTabbedNotebookbar>>
         m_pNotebookBarWeldedWrapper;
+    static std::map<const SfxViewShell*, VclPtr<NotebookBar>> 
m_pNotebookBarInstance;
 
     static void ResetActiveToolbarModeToDefault(vcl::EnumContext::Application 
eApp);
+    static void RemoveCurrentLOKWrapper();
 
     DECL_DLLPRIVATE_STATIC_LINK(SfxNotebookBar, VclDisposeHdl, const 
SfxViewShell*, void);
 };
diff --git a/sfx2/source/notebookbar/SfxNotebookBar.cxx 
b/sfx2/source/notebookbar/SfxNotebookBar.cxx
index e9e85de271bd..8e9c2c9ca494 100644
--- a/sfx2/source/notebookbar/SfxNotebookBar.cxx
+++ b/sfx2/source/notebookbar/SfxNotebookBar.cxx
@@ -11,7 +11,6 @@
 #include <sfx2/viewsh.hxx>
 #include <sfx2/dispatch.hxx>
 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
-#include <vcl/notebookbar/notebookbar.hxx>
 #include <vcl/syswin.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/sfxsids.hrc>
@@ -43,6 +42,7 @@ const char MERGE_NOTEBOOKBAR_URL[] = "URL";
 bool SfxNotebookBar::m_bLock = false;
 bool SfxNotebookBar::m_bHide = false;
 std::map<const SfxViewShell*, std::shared_ptr<WeldedTabbedNotebookbar>> 
SfxNotebookBar::m_pNotebookBarWeldedWrapper;
+std::map<const SfxViewShell*, VclPtr<NotebookBar>> 
SfxNotebookBar::m_pNotebookBarInstance;
 
 static void NotebookbarAddonValues(
     std::vector<Image>& aImageValues,
@@ -195,6 +195,19 @@ static utl::OConfigurationNode 
lcl_getCurrentImplConfigNode(const Reference<css:
     return utl::OConfigurationNode();
 }
 
+void SfxNotebookBar::RemoveCurrentLOKWrapper()
+{
+    const SfxViewShell* pViewShell = SfxViewShell::Current();
+    auto aFound = m_pNotebookBarInstance.find(pViewShell);
+    if (aFound != m_pNotebookBarInstance.end())
+    {
+        // Calls STATIC_LINK SfxNotebookBar -> VclDisposeHdl
+        // which clears also m_pNotebookBarWeldedWrapper
+        aFound->second.disposeAndClear();
+        m_pNotebookBarInstance.erase(aFound);
+    }
+}
+
 void SfxNotebookBar::CloseMethod(SfxBindings& rBindings)
 {
     SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
@@ -203,6 +216,12 @@ void SfxNotebookBar::CloseMethod(SfxBindings& rBindings)
 
 void SfxNotebookBar::CloseMethod(SystemWindow* pSysWindow)
 {
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        RemoveCurrentLOKWrapper();
+        return;
+    }
+
     if (pSysWindow)
     {
         if(pSysWindow->GetNotebookBar())
@@ -356,15 +375,19 @@ bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
             return false;
     }
 
+    const SfxViewShell* pViewShell = SfxViewShell::Current();
+    bool hasWeldedWrapper = m_pNotebookBarWeldedWrapper.find(pViewShell) != 
m_pNotebookBarWeldedWrapper.end();
+
     if (IsActive())
     {
         css::uno::Reference<css::uno::XComponentContext> xContext = 
comphelper::getProcessComponentContext();
         const Reference<frame::XModuleManager> xModuleManager  = 
frame::ModuleManager::create( xContext );
         OUString aModuleName = xModuleManager->identify( xFrame );
         vcl::EnumContext::Application eApp = 
vcl::EnumContext::GetApplicationEnum( aModuleName );
+        bool bIsLOK = comphelper::LibreOfficeKit::isActive();
 
         OUString sFile;
-        if (comphelper::LibreOfficeKit::isActive())
+        if (bIsLOK)
             sFile = "notebookbar_online.ui";
         else
             sFile = lcl_getNotebookbarFileName( eApp );
@@ -377,26 +400,12 @@ bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
 
         bool bChangedFile = sNewFile != sCurrentFile;
 
-        const SfxViewShell* pViewShell = SfxViewShell::Current();
-        bool hasWeldedWrapper = m_pNotebookBarWeldedWrapper.find(pViewShell) 
!= m_pNotebookBarWeldedWrapper.end();
-
-        if ((!sFile.isEmpty() && bChangedFile) || !pNotebookBar || 
!pNotebookBar->IsVisible()
-            || bReloadNotebookbar || (comphelper::LibreOfficeKit::isActive() 
&& !hasWeldedWrapper))
+        if ((!bIsLOK && (
+                (!sFile.isEmpty() && bChangedFile) ||
+                (!pNotebookBar || !pNotebookBar->IsVisible()) ||
+                bReloadNotebookbar)
+            ) || (bIsLOK && !hasWeldedWrapper))
         {
-            // Notebookbar was loaded too early what caused:
-            //   * in LOK: Paste Special feature was incorrectly initialized
-            // Skip first request so Notebookbar will be initialized after 
document was loaded
-            static std::map<const void*, bool> bSkippedFirstInit;
-            if (comphelper::LibreOfficeKit::isActive() && eApp == 
vcl::EnumContext::Application::Writer
-                && bSkippedFirstInit.find(pViewShell) == 
bSkippedFirstInit.end())
-            {
-                bSkippedFirstInit[pViewShell] = true;
-                ResetActiveToolbarModeToDefault(eApp);
-                return false;
-            }
-
-            RemoveListeners(pSysWindow);
-
             OUString aBuf = rUIFile + sFile;
 
             //Addons For Notebookbar
@@ -407,20 +416,29 @@ bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
             aNotebookBarAddonsItem.aAddonValues = aExtensionValues;
             aNotebookBarAddonsItem.aImageValues = aImageValues;
 
-            // setup if necessary
-            if (comphelper::LibreOfficeKit::isActive())
+            if (bIsLOK)
             {
+                // Notebookbar was loaded too early what caused:
+                //   * in LOK: Paste Special feature was incorrectly 
initialized
+                // Skip first request so Notebookbar will be initialized after 
document was loaded
+                static std::map<const void*, bool> bSkippedFirstInit;
+                if (eApp == vcl::EnumContext::Application::Writer
+                    && bSkippedFirstInit.find(pViewShell) == 
bSkippedFirstInit.end())
+                {
+                    bSkippedFirstInit[pViewShell] = true;
+                    ResetActiveToolbarModeToDefault(eApp);
+                    return false;
+                }
+
                 // update the current LOK language and locale for the dialog 
tunneling
                 
comphelper::LibreOfficeKit::setLanguageTag(pViewShell->GetLOKLanguageTag());
                 
comphelper::LibreOfficeKit::setLocale(pViewShell->GetLOKLocale());
-            }
 
-            pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , 
bReloadNotebookbar);
-            pNotebookBar = pSysWindow->GetNotebookBar();
-            pNotebookBar->Show();
+                pNotebookBar = VclPtr<NotebookBar>::Create(pSysWindow, 
"NotebookBar", aBuf, xFrame, aNotebookBarAddonsItem);
+                m_pNotebookBarInstance.emplace(std::make_pair(pViewShell, 
pNotebookBar));
+
+                assert(pNotebookBar->IsWelded());
 
-            if ((!hasWeldedWrapper || bReloadNotebookbar) && 
pNotebookBar->IsWelded())
-            {
                 sal_uInt64 nWindowId = 
reinterpret_cast<sal_uInt64>(pViewShell);
                 m_pNotebookBarWeldedWrapper.emplace(std::make_pair(pViewShell,
                         new 
WeldedTabbedNotebookbar(pNotebookBar->GetMainContainer(),
@@ -428,8 +446,16 @@ bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
                                                     xFrame,
                                                     nWindowId)));
                 pNotebookBar->SetDisposeCallback(LINK(nullptr, SfxNotebookBar, 
VclDisposeHdl), pViewShell);
+
+                return true;
             }
 
+            RemoveListeners(pSysWindow);
+
+            pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , 
bReloadNotebookbar);
+            pNotebookBar = pSysWindow->GetNotebookBar();
+            pNotebookBar->Show();
+
             pNotebookBar->GetParent()->Resize();
 
             utl::OConfigurationTreeRoot aRoot(lcl_getCurrentImplConfigRoot());
@@ -446,6 +472,11 @@ bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
 
         return true;
     }
+    else if (comphelper::LibreOfficeKit::isActive())
+    {
+        // don't do anything to not close notebookbar of other session
+        return hasWeldedWrapper;
+    }
     else if (auto pNotebookBar = pSysWindow->GetNotebookBar())
     {
         vcl::Window* pParent = pNotebookBar->GetParent();

Reply via email to