[Libreoffice-commits] core.git: sfx2/source sw/qa sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Tue Nov 24 22:05:58 UTC 2020
sfx2/source/view/viewsh.cxx | 14 ++++-
sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt |binary
sw/qa/extras/tiledrendering/tiledrendering.cxx | 33 ++++++++++++
sw/source/uibase/docvw/edtwin2.cxx | 11 ++++
4 files changed, 56 insertions(+), 2 deletions(-)
New commits:
commit 0f65b4b6f33891a724bee5356aa5549c76fa0ce3
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Nov 24 17:26:32 2020 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Nov 24 23:05:13 2020 +0100
sw tiled rendering: fix paint->invalidation loop when paint is started by vcl
SwViewShell::PaintTile() already calls
comphelper::LibreOfficeKit::setTiledPainting(), so by the time it would
rearch SwViewShell::Paint(), callbacks (e.g. invalidations) are ignored
during paint.
Do the same for SwEditWin::Paint(), where we processed invalidations
during paint, potentially leading to paint->invalidation loops.
Change-Id: I8280f5c2571beeae6c0f2986d275dde3c2d33161
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106542
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index d35253d1342a..2da4bc1e81bd 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1463,8 +1463,18 @@ void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) c
if (!comphelper::LibreOfficeKit::isActive())
return;
- if (comphelper::LibreOfficeKit::isTiledPainting() && nType != LOK_CALLBACK_FORM_FIELD_BUTTON)
- return;
+ if (comphelper::LibreOfficeKit::isTiledPainting())
+ {
+ switch (nType)
+ {
+ case LOK_CALLBACK_FORM_FIELD_BUTTON:
+ case LOK_CALLBACK_TEXT_SELECTION:
+ break;
+ default:
+ // Reject e.g. invalidate during paint.
+ return;
+ }
+ }
if (pImpl->m_bTiledSearching)
{
diff --git a/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt b/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt
new file mode 100644
index 000000000000..b42c5cc51588
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index dc57ef1e451a..afb261b4d4bc 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -144,6 +144,7 @@ public:
void testDropDownFormFieldButtonEditing();
void testDropDownFormFieldButtonNoSelection();
void testDropDownFormFieldButtonNoItem();
+ void testTablePaintInvalidate();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -215,6 +216,7 @@ public:
CPPUNIT_TEST(testDropDownFormFieldButtonEditing);
CPPUNIT_TEST(testDropDownFormFieldButtonNoSelection);
CPPUNIT_TEST(testDropDownFormFieldButtonNoItem);
+ CPPUNIT_TEST(testTablePaintInvalidate);
CPPUNIT_TEST_SUITE_END();
private:
@@ -2836,6 +2838,37 @@ void SwTiledRenderingTest::testDropDownFormFieldButtonNoItem()
}
}
+void SwTiledRenderingTest::testTablePaintInvalidate()
+{
+ // Load a document with a table in it.
+ SwXTextDocument* pXTextDocument = createDoc("table-paint-invalidate.odt");
+ SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+ pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+ // Enter the table.
+ pWrtShell->Down(/*bSelect=*/false);
+ Scheduler::ProcessEventsToIdle();
+ m_nInvalidations = 0;
+
+ // Paint a tile.
+ size_t nCanvasWidth = 256;
+ size_t nCanvasHeight = 256;
+ std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+ ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+ pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+ pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+ Fraction(1.0), Point(), aPixmap.data());
+ pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, m_aInvalidation.getX(),
+ m_aInvalidation.getY(), /*nTileWidth=*/1000,
+ /*nTileHeight=*/1000);
+ Scheduler::ProcessEventsToIdle();
+
+ // Without the accompanying fix in place, this test would have failed with
+ // - Expected: 0
+ // - Actual : 5
+ // i.e. paint generated an invalidation, which caused a loop.
+ CPPUNIT_ASSERT_EQUAL(0, m_nInvalidations);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx
index fb7f965838e2..ae168908de6f 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -51,6 +51,7 @@
#include <txtfrm.hxx>
#include <ndtxt.hxx>
#include <FrameControlsManager.hxx>
+#include <comphelper/lok.hxx>
static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon )
{
@@ -432,7 +433,17 @@ void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle
else
{
pWrtShell->setOutputToWindow(true);
+ bool bTiledPainting = false;
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ bTiledPainting = comphelper::LibreOfficeKit::isTiledPainting();
+ comphelper::LibreOfficeKit::setTiledPainting(true);
+ }
pWrtShell->Paint(rRenderContext, rRect);
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ comphelper::LibreOfficeKit::setTiledPainting(bTiledPainting);
+ }
pWrtShell->setOutputToWindow(false);
}
More information about the Libreoffice-commits
mailing list