compilerplugins/clang/badstatics.cxx | 1 include/sfx2/notebookbar/SfxNotebookBar.hxx | 3 sfx2/source/notebookbar/SfxNotebookBar.cxx | 89 ++++++++++++++++++---------- 3 files changed, 64 insertions(+), 29 deletions(-)
New commits: commit b9e5543be78b0b124bc087840f13ae1bfd2b155b Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Sat Nov 4 12:05:16 2023 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Mon Nov 6 09:56:27 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/+/158896 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/compilerplugins/clang/badstatics.cxx b/compilerplugins/clang/badstatics.cxx index 98375f212dd2..47670d10282b 100644 --- a/compilerplugins/clang/badstatics.cxx +++ b/compilerplugins/clang/badstatics.cxx @@ -213,6 +213,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 ac27619832b9..5acd8d39a99a 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()) @@ -352,15 +371,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 ); @@ -373,26 +396,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 @@ -403,20 +412,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(), @@ -424,8 +442,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()); @@ -442,6 +468,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();