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

Reply via email to