sw/qa/extras/tiledrendering/tiledrendering2.cxx |   17 +++++++++++++++++
 sw/qa/inc/swtestviewcallback.hxx                |    1 +
 sw/qa/unit/swtestviewcallback.cxx               |    5 +++++
 sw/source/uibase/app/swmodul1.cxx               |   12 +++++++++++-
 4 files changed, 34 insertions(+), 1 deletion(-)

New commits:
commit f0d38305d7eec27a5fa6846a5e02529b982a2f49
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Mar 14 10:23:11 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Mar 14 14:25:19 2025 +0100

    cool#11347 sw lok: avoid view jump on showing formatting marks
    
    Open a document with a few pages, set zoom level to 50%, press page down
    a number of times, scrool to the top, show formatting marks: view jumps
    back from the top to the page where the cursor is, which used to not
    happen in the past.
    
    This went wrong in commit 9400c0cf10bc14963a994ec0c0caeeb22a7c2513
    (tdf#132274 follow-up fix to Writer zoom options, 2024-10-09), because
    of the unconditional call to SwView::SetZoom() in lcl_SetUIPrefs():
            #0  desktop::CallbackFlushHandler::queue (this=0x417f3f80, type=5, 
aCallbackData=...) at desktop/source/lib/init.cxx:1795
            #1  0x00007ff83caebe78 in 
desktop::CallbackFlushHandler::libreOfficeKitViewCallback (this=0x417f3f80, 
nType=5, pPayload="true")
                at desktop/source/lib/init.cxx:1704
            #2  0x00007ff838d1cf7a in SfxViewShell::libreOfficeKitViewCallback 
(this=0x41fb88a0, nType=5, pPayload="true") at sfx2/source/view/viewsh.cxx:3352
            #3  0x00007ff82125482b in SwCursorShell::ShowCursor 
(this=0x41fbfd60) at sw/source/core/crsr/crsrsh.cxx:2819
            #4  0x00007ff8227fb198 in SwView::SetZoom (this=0x41fb88a0, 
eZoomType=SvxZoomType::PERCENT, nFactor=100, bViewOnly=true)
                at sw/source/uibase/uiview/viewmdi.cxx:77
            #5  0x00007ff822431a46 in lcl_SetUIPrefs (rPref=..., 
pView=0x41fb88a0, pSh=0x41fbfd60) at sw/source/uibase/app/swmodul1.cxx:103
            #6  0x00007ff822431fd7 in SwModule::ApplyUsrPref (this=0x4194ff40, 
rUsrPref=..., pActView=0x41fb88a0, nDest=SvViewOpt::DestText)
                at sw/source/uibase/app/swmodul1.cxx:197
            #7  0x00007ff8227d37a1 in SwView::ExecViewOptions (this=0x41fb88a0, 
rReq=...) at sw/source/uibase/uiview/view0.cxx:766
    Investigating how "set zoom" works, notice that SwView::SetZoom_()
    stores both the zoom type and the zoom factor in SwMasterUsrPref. (User
    profile settings.)
    
    Fix the problem by checking what's the current zoom type/factor in
    lcl_SetUIPrefs(), and only call SetZoom() if needed, to avoid
    invalidating the (unchanged) cursor, which would lead to a view jump.
    
    online.git's
    cypress_test/integration_tests/desktop/writer/scrolling_spec.js 'Check
    if we jump the view on change of formatting mark' can be re-enabled
    after this.
    
    Change-Id: Id3777db91cbfa5b32f7e4488bb27b1fb8a081599
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182913
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/tiledrendering/tiledrendering2.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering2.cxx
index 1b9eeaa28682..5055dbdf8024 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering2.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering2.cxx
@@ -667,6 +667,23 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesStates)
     
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(FN_TRACK_CHANGES_IN_ALL_VIEWS), 
pItem->Which());
     CPPUNIT_ASSERT(dynamic_cast<SfxBoolItem*>(pItem.get())->GetValue());
 }
+
+CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testControlCodesCursor)
+{
+    // Given a document with hidden formatting marks:
+    SwXTextDocument* pXTextDocument = createDoc();
+    CPPUNIT_ASSERT(pXTextDocument);
+    SwTestViewCallback aView1;
+    aView1.m_bCursorVisible = false;
+
+    // When showing formatting marks:
+    dispatchCommand(mxComponent, ".uno:ControlCodes", {});
+
+    // Then make sure this doesn't result in a LOK_CALLBACK_CURSOR_VISIBLE 
callback:
+    // Without the accompanying fix in place, this test would have failed, the 
view jumped to the
+    // cursor when showing formatting marks.
+    CPPUNIT_ASSERT(!aView1.m_bCursorVisible);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/inc/swtestviewcallback.hxx b/sw/qa/inc/swtestviewcallback.hxx
index a82772c07b70..f31467112571 100644
--- a/sw/qa/inc/swtestviewcallback.hxx
+++ b/sw/qa/inc/swtestviewcallback.hxx
@@ -54,6 +54,7 @@ public:
     std::vector<OString> m_aStateChanges;
     TestLokCallbackWrapper m_callbackWrapper;
     OString m_aExportFile;
+    bool m_bCursorVisible = false;
 
     SwTestViewCallback(SfxViewShell* pViewShell = nullptr,
                        std::function<void(SwTestViewCallback&)> const& 
rBeforeInstallFunc = {});
diff --git a/sw/qa/unit/swtestviewcallback.cxx 
b/sw/qa/unit/swtestviewcallback.cxx
index b378723603a0..adc83737e3de 100644
--- a/sw/qa/unit/swtestviewcallback.cxx
+++ b/sw/qa/unit/swtestviewcallback.cxx
@@ -199,6 +199,11 @@ void SwTestViewCallback::callbackImpl(int nType, const 
char* pPayload)
             m_aExportFile = aPayload;
             break;
         }
+        case LOK_CALLBACK_CURSOR_VISIBLE:
+        {
+            m_bCursorVisible = aPayload == "true";
+            break;
+        }
     }
 }
 
diff --git a/sw/source/uibase/app/swmodul1.cxx 
b/sw/source/uibase/app/swmodul1.cxx
index 96bde7096a1b..35b53b37faf0 100644
--- a/sw/source/uibase/app/swmodul1.cxx
+++ b/sw/source/uibase/app/swmodul1.cxx
@@ -100,7 +100,17 @@ static void lcl_SetUIPrefs(const SwViewOption &rPref, 
SwView* pView, SwViewShell
         pView->CreateTab();
     else
         pView->KillTab();
-    pView->SetZoom(rPref.GetZoomType(), rPref.GetZoom(), true);
+
+    bool bWeb = dynamic_cast<const SwWebView*>(pView) != nullptr;
+    SwModule* pModule = SwModule::get();
+    auto pUsrPref = const_cast<SwMasterUsrPref*>(pModule->GetUsrPref(bWeb));
+    if (rPref.GetZoomType() != pUsrPref->GetZoomType() || rPref.GetZoom() != 
pUsrPref->GetZoom())
+    {
+        // The current zoom is different, then set the new type and value. See 
how
+        // SwView::SetZoom_() stores these applied values in SwMasterUsrPref.
+        pView->SetZoom(rPref.GetZoomType(), rPref.GetZoom(), true);
+    }
+
     pView->GetPostItMgr()->PrepareView(true);
 }
 

Reply via email to