desktop/qa/desktop_lib/test_desktop_lib.cxx | 25 +++++++++++++++---------- sfx2/source/appl/app.cxx | 11 ++++++++++- sfx2/source/appl/appdata.cxx | 25 +++++++++++++++++++++++++ sfx2/source/inc/appdata.hxx | 3 +++ 4 files changed, 53 insertions(+), 11 deletions(-)
New commits: commit ef980f0b22c0cd55d9d15dbb929859d305532436 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Wed Jul 23 15:58:48 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Jul 29 14:36:52 2025 +0200 Keep ViewShells sorted in most recently used order SfxViewShell::GetCurrent() is the current shell. Tt would be convenient to have the list that GetFirst/GetNext work with, in MRU order to be consistent with that, so it can be used to get the most recently current viewshell that matches a specific criteria. Also keep ViewFrames in MRU order for consistency with MRU ViewShell ordering. Change-Id: I15126242a4895bb90d8bcf34d91e917a217f4204 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188334 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 251f965a0fcc..8d27eae32b82 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -562,8 +562,9 @@ void DesktopLOKTest::testCreateView() // Test getViewIds(). std::vector<int> aViewIds(2); CPPUNIT_ASSERT(pDocument->m_pDocumentClass->getViewIds(pDocument, aViewIds.data(), aViewIds.size())); - CPPUNIT_ASSERT_EQUAL(nId0, aViewIds[0]); - CPPUNIT_ASSERT_EQUAL(nId1, aViewIds[1]); + // The expectation is that the most recently used shell is at the start + CPPUNIT_ASSERT_EQUAL(nId1, aViewIds[0]); + CPPUNIT_ASSERT_EQUAL(nId0, aViewIds[1]); // Make sure the created view is the active one, then switch to the old // one. @@ -3748,8 +3749,9 @@ void DesktopLOKTest::testMultiDocuments() // Validate the views of document 1. std::vector<int> aViewIdsDoc1(2); CPPUNIT_ASSERT(pDocument1->m_pDocumentClass->getViewIds(pDocument1, aViewIdsDoc1.data(), aViewIdsDoc1.size())); - CPPUNIT_ASSERT_EQUAL(nDoc1View0, aViewIdsDoc1[0]); - CPPUNIT_ASSERT_EQUAL(nDoc1View1, aViewIdsDoc1[1]); + // The expectation is that the most recently used shell is at the start + CPPUNIT_ASSERT_EQUAL(nDoc1View1, aViewIdsDoc1[0]); + CPPUNIT_ASSERT_EQUAL(nDoc1View0, aViewIdsDoc1[1]); CPPUNIT_ASSERT_EQUAL(nDoc1View1, pDocument1->m_pDocumentClass->getView(pDocument1)); CPPUNIT_ASSERT_EQUAL(nDocId1, SfxLokHelper::getDocumentIdOfView(nDoc1View1)); @@ -3777,8 +3779,9 @@ void DesktopLOKTest::testMultiDocuments() // Validate the views of document 2. std::vector<int> aViewIdsDoc2(2); CPPUNIT_ASSERT(pDocument2->m_pDocumentClass->getViewIds(pDocument2, aViewIdsDoc2.data(), aViewIdsDoc2.size())); - CPPUNIT_ASSERT_EQUAL(nDoc2View0, aViewIdsDoc2[0]); - CPPUNIT_ASSERT_EQUAL(nDoc2View1, aViewIdsDoc2[1]); + // The expectation is that the most recently used shell is at the start + CPPUNIT_ASSERT_EQUAL(nDoc2View1, aViewIdsDoc2[0]); + CPPUNIT_ASSERT_EQUAL(nDoc2View0, aViewIdsDoc2[1]); CPPUNIT_ASSERT_EQUAL(nDoc2View1, pDocument2->m_pDocumentClass->getView(pDocument2)); CPPUNIT_ASSERT_EQUAL(nDocId2, SfxLokHelper::getDocumentIdOfView(nDoc2View1)); @@ -3792,8 +3795,9 @@ void DesktopLOKTest::testMultiDocuments() // The views of document1 should be unchanged. CPPUNIT_ASSERT(pDocument1->m_pDocumentClass->getViewIds(pDocument1, aViewIdsDoc1.data(), aViewIdsDoc1.size())); - CPPUNIT_ASSERT_EQUAL(nDoc1View0, aViewIdsDoc1[0]); - CPPUNIT_ASSERT_EQUAL(nDoc1View1, aViewIdsDoc1[1]); + // The expectation is that the most recently used shell is at the start + CPPUNIT_ASSERT_EQUAL(nDoc1View1, aViewIdsDoc1[0]); + CPPUNIT_ASSERT_EQUAL(nDoc1View0, aViewIdsDoc1[1]); // Switch views in the first doc. CPPUNIT_ASSERT_EQUAL(nDocId1, SfxLokHelper::getDocumentIdOfView(nDoc1View0)); pDocument1->m_pDocumentClass->setView(pDocument1, nDoc1View0); @@ -3804,8 +3808,9 @@ void DesktopLOKTest::testMultiDocuments() // The views of document2 should be unchanged. CPPUNIT_ASSERT(pDocument2->m_pDocumentClass->getViewIds(pDocument2, aViewIdsDoc2.data(), aViewIdsDoc2.size())); - CPPUNIT_ASSERT_EQUAL(nDoc2View0, aViewIdsDoc2[0]); - CPPUNIT_ASSERT_EQUAL(nDoc2View1, aViewIdsDoc2[1]); + // The expectation is that the most recently used shell is at the start + CPPUNIT_ASSERT_EQUAL(nDoc2View1, aViewIdsDoc2[0]); + CPPUNIT_ASSERT_EQUAL(nDoc2View0, aViewIdsDoc2[1]); // Switch views in the second doc. CPPUNIT_ASSERT_EQUAL(nDocId2, SfxLokHelper::getDocumentIdOfView(nDoc2View0)); pDocument2->m_pDocumentClass->setView(pDocument2, nDoc2View0); diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx index b2a932c16e67..3b585aeba6e6 100644 --- a/sfx2/source/appl/app.cxx +++ b/sfx2/source/appl/app.cxx @@ -258,6 +258,15 @@ void SfxApplication::SetViewFrame_Impl( SfxViewFrame *pFrame ) if( pFrame ) { + // Keep SfxViewFrame::Current() consistent with SfxViewFrame::First + pImpl->MoveFrameToFirstFrame(*pFrame); + SfxViewShell* pViewShell = pFrame->GetViewShell(); + if (pViewShell) + { + // Keep SfxViewShell::Current() consistent with SfxViewShell::First + pImpl->MoveShellToFirstShell(*pViewShell); + } + pFrame->DoActivate( bTaskActivate ); if ( bTaskActivate && pFrame->GetObjectShell() ) { @@ -274,7 +283,7 @@ void SfxApplication::SetViewFrame_Impl( SfxViewFrame *pFrame ) pProgress->SetState( pProgress->GetState() ); } - if ( pImpl->pViewFrame->GetViewShell() ) + if (pViewShell) { SfxDispatcher* pDisp = pImpl->pViewFrame->GetDispatcher(); pDisp->Flush(); diff --git a/sfx2/source/appl/appdata.cxx b/sfx2/source/appl/appdata.cxx index 70be13869689..ab18e7f7eaae 100644 --- a/sfx2/source/appl/appdata.cxx +++ b/sfx2/source/appl/appdata.cxx @@ -125,4 +125,29 @@ void SfxAppData_Impl::OnApplicationBasicManagerCreated( BasicManager& _rBasicMan #endif } +void SfxAppData_Impl::MoveShellToFirstShell(SfxViewShell& rShell) +{ + // Move associated ViewShell to the top of the ViewShells stack + // so the ViewShells are in order of most recently active + // ViewFrames. SfxViewShell::Current() should be equal to + // SfxViewShell::GetFirst(false) if SfxViewShell::Current() is + // not-null. + const auto shellIt = std::find(maViewShells.begin(), maViewShells.end(), &rShell); + if (shellIt != maViewShells.end() && shellIt != maViewShells.begin()) + { + maViewShells.erase(shellIt); + maViewShells.insert(maViewShells.begin(), &rShell); + } +} + +void SfxAppData_Impl::MoveFrameToFirstFrame(SfxViewFrame& rFrame) +{ + const auto frameIt = std::find(maViewFrames.begin(), maViewFrames.end(), &rFrame); + if (frameIt != maViewFrames.end() && frameIt != maViewFrames.begin()) + { + maViewFrames.erase(frameIt); + maViewFrames.insert(maViewFrames.begin(), &rFrame); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/inc/appdata.hxx b/sfx2/source/inc/appdata.hxx index 400dcae776d6..2c6d87946070 100644 --- a/sfx2/source/inc/appdata.hxx +++ b/sfx2/source/inc/appdata.hxx @@ -129,6 +129,9 @@ public: BasicManager is created before the application's BasicManager exists. */ void OnApplicationBasicManagerCreated( BasicManager& _rManager ); + + void MoveFrameToFirstFrame(SfxViewFrame& rFrame); + void MoveShellToFirstShell(SfxViewShell& rShell); }; class SfxDdeTriggerTopic_Impl final : public DdeTopic