sw/inc/viewsh.hxx                    |   41 +++++++++++++++++++++----
 sw/source/core/frmedt/feshview.cxx   |    2 -
 sw/source/core/layout/layact.cxx     |    2 -
 sw/source/core/view/viewsh.cxx       |   56 ++++++++++++++++++++++++++++++++---
 sw/source/uibase/docvw/edtdd.cxx     |    2 -
 sw/source/uibase/docvw/edtwin3.cxx   |    4 +-
 sw/source/uibase/inc/wrtsh.hxx       |    2 -
 sw/source/uibase/shells/basesh.cxx   |    4 +-
 sw/source/uibase/shells/textsh.cxx   |    6 +--
 sw/source/uibase/uiview/view2.cxx    |    4 +-
 sw/source/uibase/uiview/viewmdi.cxx  |    4 +-
 sw/source/uibase/uiview/viewport.cxx |    2 -
 sw/source/uibase/utlui/unotools.cxx  |    2 -
 sw/source/uibase/wrtsh/wrtsh1.cxx    |    2 -
 14 files changed, 105 insertions(+), 28 deletions(-)

New commits:
commit 21298817ad59e34baf85f22403e4fd8b774183c7
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue May 23 13:10:22 2023 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed May 24 10:33:08 2023 +0200

    categorize the reasons writer calls "LockPaint"
    
    and bubble to a new InvalidateAll the collected
    reasons for that whole document Invalidate
    
    https: //github.com/CollaboraOnline/online/issues/6379
    Change-Id: Id71c59f9cafebe42085337ee1e9591eb9f1162d2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152162
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152174
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 1114478ed395..5d2e57952f4f 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -66,6 +66,25 @@ class SdrPaintWindow;
 class SwAccessibleMap;
 enum class Orientation;
 
+enum class LockPaintReason
+{
+    ViewLayout = 1,
+    OuterResize,
+    Undo,
+    Redo,
+    OutlineFolding,
+    EndSdrCreate,
+    SwLayIdle,
+    InvalidateLayout,
+    StartDrag,
+    DataChanged,
+    InsertFrame,
+    GotoPage,
+    InsertGraphic,
+    SetZoom,
+    ExampleFrame
+};
+
 namespace vcl
 {
     typedef OutputDevice RenderContext;
@@ -170,6 +189,8 @@ class SW_DLLPUBLIC SwViewShell : public 
sw::Ring<SwViewShell>
 
     SAL_DLLPRIVATE void ImplApplyViewOptions( const SwViewOption &rOpt );
 
+    SAL_DLLPRIVATE void InvalidateAll(const std::vector<LockPaintReason>& 
rReasons);
+
 protected:
     static ShellResource*      spShellRes;      ///< Resources for the Shell.
     static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > spCareDialog;  
  ///< Avoid this window.
@@ -180,6 +201,7 @@ protected:
 
     sal_uInt16 mnStartAction; ///< != 0 if at least one Action is active.
     sal_uInt16 mnLockPaint;   ///< != 0 if Paint is locked.
+    std::vector<LockPaintReason> maLockPaintReasons;
     bool      mbSelectAll; ///< Special select all mode: whole document 
selected, even if doc starts with table.
 
     /// The virtual device we paint to will end up on the screen.
@@ -471,10 +493,10 @@ public:
     bool IsViewLocked() const { return mbViewLocked; }
     void LockView( bool b )   { mbViewLocked = b;    }
 
-    inline void LockPaint();
+    inline void LockPaint(LockPaintReason eReason);
            void ImplLockPaint();
-    inline void UnlockPaint( bool bVirDev = false );
-           void ImplUnlockPaint( bool bVirDev );
+    inline void UnlockPaint(bool bVirDev = false );
+           void ImplUnlockPaint( const std::vector<LockPaintReason>& rReasons, 
bool bVirDev );
            bool IsPaintLocked() const { return mnLockPaint != 0; }
 
     // Get/set DrawView and PageView.
@@ -604,6 +626,7 @@ inline void SwViewShell::StartAction()
     if ( !mnStartAction++ )
         ImplStartAction();
 }
+
 inline void SwViewShell::EndAction( const bool bIdleEnd )
 {
     if( 0 == (mnStartAction - 1) )
@@ -611,16 +634,22 @@ inline void SwViewShell::EndAction( const bool bIdleEnd )
     --mnStartAction;
 }
 
-inline void SwViewShell::LockPaint()
+inline void SwViewShell::LockPaint(LockPaintReason eReason)
 {
+    maLockPaintReasons.push_back(eReason);
     if ( !mnLockPaint++ )
         ImplLockPaint();
 }
-inline void SwViewShell::UnlockPaint( bool bVirDev )
+
+inline void SwViewShell::UnlockPaint(bool bVirDev )
 {
     if ( 0 == --mnLockPaint )
-        ImplUnlockPaint( bVirDev );
+    {
+        ImplUnlockPaint(maLockPaintReasons, bVirDev);
+        maLockPaintReasons.clear();
+    }
 }
+
 inline const SfxItemPool& SwViewShell::GetAttrPool() const
 {
     return const_cast<SwViewShell*>(this)->GetAttrPool();
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 14b97a620cca..61f2a8ae30eb 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -1928,7 +1928,7 @@ bool SwFEShell::ImpEndCreate()
         return true;
     }
 
-    LockPaint();
+    LockPaint(LockPaintReason::EndSdrCreate);
     StartAllAction();
 
     Imp()->GetDrawView()->UnmarkAll();
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index be803a3b00c1..f0ac091d16ea 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -2356,7 +2356,7 @@ SwLayIdle::SwLayIdle( SwRootFrame *pRt, SwViewShellImp 
*pI ) :
                     pViewImp->DeletePaintRegion();
 
                     // Cause a repaint with virtual device.
-                    rSh.LockPaint();
+                    rSh.LockPaint(LockPaintReason::SwLayIdle);
                     bUnlock = true;
                 }
 
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 13ffa8720488..c4c410efe02d 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -480,7 +480,7 @@ void SwViewShell::ImplLockPaint()
     Imp()->LockPaint();
 }
 
-void SwViewShell::ImplUnlockPaint( bool bVirDev )
+void SwViewShell::ImplUnlockPaint(const std::vector<LockPaintReason>& 
rReasons, bool bVirDev)
 {
     CurrShell aCurr( this );
     if ( GetWin() && GetWin()->IsVisible() )
@@ -522,7 +522,7 @@ void SwViewShell::ImplUnlockPaint( bool bVirDev )
             {
                 Imp()->UnlockPaint();
                 GetWin()->EnablePaint( true );
-                GetWin()->Invalidate( InvalidateFlags::Children );
+                InvalidateAll(rReasons);
             }
             pVout.disposeAndClear();
         }
@@ -530,13 +530,61 @@ void SwViewShell::ImplUnlockPaint( bool bVirDev )
         {
             Imp()->UnlockPaint();
             GetWin()->EnablePaint( true );
-            GetWin()->Invalidate( InvalidateFlags::Children );
+            InvalidateAll(rReasons);
         }
     }
     else
         Imp()->UnlockPaint();
 }
 
+namespace
+{
+    std::string_view to_string(LockPaintReason eReason)
+    {
+        switch(eReason)
+        {
+            case LockPaintReason::ViewLayout:
+                return "ViewLayout";
+            case LockPaintReason::OuterResize:
+                return "OuterResize";
+            case LockPaintReason::Undo:
+                return "Undo";
+            case LockPaintReason::Redo:
+                return "Redo";
+            case LockPaintReason::OutlineFolding:
+                return "OutlineFolding";
+            case LockPaintReason::EndSdrCreate:
+                return "EndSdrCreate";
+            case LockPaintReason::SwLayIdle:
+                return "SwLayIdle";
+            case LockPaintReason::InvalidateLayout:
+                return "InvalidateLayout";
+            case LockPaintReason::StartDrag:
+                return "StartDrag";
+            case LockPaintReason::DataChanged:
+                return "DataChanged";
+            case LockPaintReason::InsertFrame:
+                return "InsertFrame";
+            case LockPaintReason::GotoPage:
+                return "GotoPage";
+            case LockPaintReason::InsertGraphic:
+                return "InsertGraphic";
+            case LockPaintReason::SetZoom:
+                return "SetZoom";
+            case LockPaintReason::ExampleFrame:
+                return "ExampleFram";
+        }
+        return "";
+    };
+}
+
+void SwViewShell::InvalidateAll(const std::vector<LockPaintReason>& rReasons)
+{
+    for (const auto& reason : rReasons)
+        SAL_INFO("sw.core", "InvalidateAll because of: " << to_string(reason));
+    GetWin()->Invalidate(InvalidateFlags::Children);
+}
+
 bool SwViewShell::AddPaintRect( const SwRect & rRect )
 {
     bool bRet = false;
@@ -2125,7 +2173,7 @@ void SwViewShell::InvalidateLayout( bool bSizeChanged )
         return;
     }
 
-    LockPaint();
+    LockPaint(LockPaintReason::InvalidateLayout);
     StartAction();
 
     SwPageFrame *pPg = static_cast<SwPageFrame*>(GetLayout()->Lower());
diff --git a/sw/source/uibase/docvw/edtdd.cxx b/sw/source/uibase/docvw/edtdd.cxx
index 8f86aa1d310a..c983d6dabf5c 100644
--- a/sw/source/uibase/docvw/edtdd.cxx
+++ b/sw/source/uibase/docvw/edtdd.cxx
@@ -105,7 +105,7 @@ void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const 
Point& rPosPixel )
     else if( !g_bFrameDrag && m_rView.GetDocShell()->IsReadOnly() &&
             OBJCNT_NONE != rSh.GetObjCntType( aDocPos, pObj ))
     {
-        rSh.LockPaint();
+        rSh.LockPaint(LockPaintReason::StartDrag);
         if( rSh.SelectObj( aDocPos, 0, pObj ))
             bStart = bDelSelect = true;
         else
diff --git a/sw/source/uibase/docvw/edtwin3.cxx 
b/sw/source/uibase/docvw/edtwin3.cxx
index d417b08b0510..2b9d1a7f1e03 100644
--- a/sw/source/uibase/docvw/edtwin3.cxx
+++ b/sw/source/uibase/docvw/edtwin3.cxx
@@ -144,7 +144,7 @@ void SwEditWin::DataChanged( const DataChangedEvent& rDCEvt 
)
         // from the settings.
         if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
         {
-            pSh->LockPaint();
+            pSh->LockPaint(LockPaintReason::DataChanged);
             bUnlockPaint = true;
             pSh->DeleteReplacementBitmaps();
             GetView().InvalidateBorder();               //Scrollbar work
@@ -155,7 +155,7 @@ void SwEditWin::DataChanged( const DataChangedEvent& rDCEvt 
)
     case DataChangedEventType::DISPLAY:
     case DataChangedEventType::FONTS:
     case DataChangedEventType::FONTSUBSTITUTION:
-        pSh->LockPaint();
+        pSh->LockPaint(LockPaintReason::DataChanged);
         bUnlockPaint = true;
         GetView().GetDocShell()->UpdateFontList();  //e.g. printer change
         pSh->InvalidateLayout(true);
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 801e52bef7ab..736c0ac363ff 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -694,7 +694,7 @@ public:
                     
m_pWrtSh->GetViewOptions()->IsShowOutlineContentVisibilityButton())
             {
                 m_pWrtSh->LockView(true);
-                m_pWrtSh->LockPaint();
+                m_pWrtSh->LockPaint(LockPaintReason::OutlineFolding);
                 m_pWrtSh->MakeAllFoldedOutlineContentVisible();
                 m_bScrollToCursor = bScrollToCursor;
                 m_bDone = true;
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index abd24060f3f4..576d16005ebc 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -630,7 +630,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
             if (rUndoRedo.GetLastUndoInfo(nullptr, &nUndoId, 
&rWrtShell.GetView()))
             {
                 for (SwViewShell& rShell : rWrtShell.GetRingContainer())
-                    rShell.LockPaint();
+                    rShell.LockPaint(LockPaintReason::Undo);
 
                 sal_uInt16 nUndoOffset = 0;
                 if (comphelper::LibreOfficeKit::isActive() && !bRepair && nCnt 
== 1)
@@ -666,7 +666,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
             if (rUndoRedo.GetFirstRedoInfo(nullptr, &nUndoId, 
&rWrtShell.GetView()))
             {
                 for (SwViewShell& rShell : rWrtShell.GetRingContainer())
-                    rShell.LockPaint();
+                    rShell.LockPaint(LockPaintReason::Redo);
                 rWrtShell.Do( SwWrtShell::REDO, nCnt );
                 for (SwViewShell& rShell : rWrtShell.GetRingContainer())
                     rShell.UnlockPaint();
diff --git a/sw/source/uibase/shells/textsh.cxx 
b/sw/source/uibase/shells/textsh.cxx
index d3266cd13f29..807ee76859e9 100644
--- a/sw/source/uibase/shells/textsh.cxx
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -454,7 +454,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq)
             aStartPos.AdjustX(-constTwips_4cm);
             aStartPos.AdjustY(-constTwips_2cm);
             Size aSize(2 * constTwips_4cm, 2 * constTwips_2cm);
-            GetShell().LockPaint();
+            GetShell().LockPaint(LockPaintReason::InsertFrame);
             GetShell().StartAllAction();
             SwFlyFrameAttrMgr aMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, 
nullptr );
             if(nCols > 1)
@@ -511,7 +511,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq)
                 }
             }
 
-            GetShell().LockPaint();
+            GetShell().LockPaint(LockPaintReason::InsertFrame);
             GetShell().StartAllAction();
 
             aMgr.InsertFlyFrame(eAnchor, aPos, aSize);
@@ -534,7 +534,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq)
             {
                 //local variable necessary at least after call of 
.AutoCaption() because this could be deleted at this point
                 SwWrtShell& rShell = GetShell();
-                rShell.LockPaint();
+                rShell.LockPaint(LockPaintReason::InsertFrame);
                 rShell.StartAllAction();
                 rShell.StartUndo(SwUndoId::INSERT);
 
diff --git a/sw/source/uibase/uiview/view2.cxx 
b/sw/source/uibase/uiview/view2.cxx
index baff544cb7f8..36fd4386ddc2 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -533,7 +533,7 @@ bool SwView::InsertGraphicDlg( SfxRequest& rReq )
 #endif
 
         SwWrtShell& rSh = GetWrtShell();
-        rSh.LockPaint();
+        rSh.LockPaint(LockPaintReason::InsertGraphic);
         rSh.StartAction();
 
         SwRewriter aRewriter;
@@ -681,7 +681,7 @@ void SwView::Execute(SfxRequest &rReq)
                     nPage++;
                 if (nPage != nOldPage)
                 {
-                    m_pWrtShell->LockPaint();
+                    m_pWrtShell->LockPaint(LockPaintReason::GotoPage);
                     if (IsDrawMode())
                         LeaveDrawCreate();
                     m_pWrtShell->EnterStdMode();
diff --git a/sw/source/uibase/uiview/viewmdi.cxx 
b/sw/source/uibase/uiview/viewmdi.cxx
index f2c9ad63034a..9eea1d290a46 100644
--- a/sw/source/uibase/uiview/viewmdi.cxx
+++ b/sw/source/uibase/uiview/viewmdi.cxx
@@ -89,7 +89,7 @@ void SwView::SetZoom_( const Size &rEditSize, SvxZoomType 
eZoomType,
 {
     bool bUnLockView = !m_pWrtShell->IsViewLocked();
     m_pWrtShell->LockView( true );
-    m_pWrtShell->LockPaint();
+    m_pWrtShell->LockPaint(LockPaintReason::SetZoom);
 
     { // start of SwActContext scope
     SwActContext aActContext(m_pWrtShell.get());
@@ -225,7 +225,7 @@ void SwView::SetViewLayout( sal_uInt16 nColumns, bool 
bBookMode, bool bViewOnly
 {
     const bool bUnLockView = !m_pWrtShell->IsViewLocked();
     m_pWrtShell->LockView( true );
-    m_pWrtShell->LockPaint();
+    m_pWrtShell->LockPaint(LockPaintReason::ViewLayout);
 
     {
 
diff --git a/sw/source/uibase/uiview/viewport.cxx 
b/sw/source/uibase/uiview/viewport.cxx
index 2c66c52a0c96..6727e6f76980 100644
--- a/sw/source/uibase/uiview/viewport.cxx
+++ b/sw/source/uibase/uiview/viewport.cxx
@@ -1065,7 +1065,7 @@ void SwView::OuterResizePixel( const Point &rOfst, const 
Size &rSize )
 
     bool bUnLockView = !m_pWrtShell->IsViewLocked();
     m_pWrtShell->LockView( true );
-    m_pWrtShell->LockPaint();
+    m_pWrtShell->LockPaint(LockPaintReason::OuterResize);
 
     do {
         ++nCnt;
diff --git a/sw/source/uibase/utlui/unotools.cxx 
b/sw/source/uibase/utlui/unotools.cxx
index 9ba9e642f3b6..4f520f50525f 100644
--- a/sw/source/uibase/utlui/unotools.cxx
+++ b/sw/source/uibase/utlui/unotools.cxx
@@ -443,7 +443,7 @@ void SwOneExampleFrame::ClearDocument()
     {
         SwDoc* pDoc = pCursor->GetDoc();
         SwEditShell* pSh = pDoc->GetEditShell();
-        pSh->LockPaint();
+        pSh->LockPaint(LockPaintReason::ExampleFrame);
         pSh->StartAllAction();
         pSh->KillPams();
         pSh->ClearMark();
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 4b9e12fa561b..15e683c368c7 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1113,7 +1113,7 @@ void 
SwWrtShell::InsertContentControl(SwContentControlType eType)
             SwRewriter aRewriter;
             aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC_DEFNAME));
             StartUndo(SwUndoId::INSERT, &aRewriter);
-            LockPaint();
+            LockPaint(LockPaintReason::InsertGraphic);
             StartAction();
             InsertGraphic(OUString(), OUString(), aBitmap, nullptr, 
RndStdIds::FLY_AS_CHAR);
 

Reply via email to