summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-09-14 19:47:47 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-09-14 19:47:48 +0200
commitbee4ff508a456a1552aacdf6fc838b8b7cffb9ec (patch)
treed6baf17acdef3893049b5d8cc31d884cc6d09f60
parentb9a27d5856f60688456762bfcc29c38670009254 (diff)
desktop lok: avoid unnecessary setPart() in paintPartTile()
If possible, switch views, not parts, that way started Impress text edits don't end as a side-effect. Change-Id: I3f18d4dda6bc24235bf1219416f153248a867fa4
-rw-r--r--desktop/qa/data/2slides.odpbin0 -> 10888 bytes
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx74
-rw-r--r--desktop/source/lib/init.cxx24
3 files changed, 98 insertions, 0 deletions
diff --git a/desktop/qa/data/2slides.odp b/desktop/qa/data/2slides.odp
new file mode 100644
index 000000000000..8be376f5b548
--- /dev/null
+++ b/desktop/qa/data/2slides.odp
Binary files differ
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 9e5832777c83..28d78bc09a90 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -99,6 +99,7 @@ public:
void testRedlineWriter();
void testTrackChanges();
void testRedlineCalc();
+ void testPaintPartTile();
CPPUNIT_TEST_SUITE(DesktopLOKTest);
CPPUNIT_TEST(testGetStyles);
@@ -129,6 +130,7 @@ public:
CPPUNIT_TEST(testRedlineWriter);
CPPUNIT_TEST(testTrackChanges);
CPPUNIT_TEST(testRedlineCalc);
+ CPPUNIT_TEST(testPaintPartTile);
CPPUNIT_TEST_SUITE_END();
uno::Reference<lang::XComponent> mxComponent;
@@ -1472,6 +1474,78 @@ void DesktopLOKTest::testRedlineCalc()
comphelper::LibreOfficeKit::setActive(false);
}
+class ViewCallback
+{
+public:
+ bool m_bTilesInvalidated;
+
+ ViewCallback()
+ : m_bTilesInvalidated(false)
+ {
+ }
+
+ static void callback(int nType, const char* pPayload, void* pData)
+ {
+ static_cast<ViewCallback*>(pData)->callbackImpl(nType, pPayload);
+ }
+
+ void callbackImpl(int nType, const char* /*pPayload*/)
+ {
+ switch (nType)
+ {
+ case LOK_CALLBACK_INVALIDATE_TILES:
+ {
+ m_bTilesInvalidated = true;
+ }
+ break;
+ }
+ }
+};
+
+void DesktopLOKTest::testPaintPartTile()
+{
+ // Load an impress doc of 2 slides.
+ comphelper::LibreOfficeKit::setActive();
+ LibLODocument_Impl* pDocument = loadDoc("2slides.odp");
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+ ViewCallback aView1;
+ pDocument->m_pDocumentClass->registerCallback(pDocument, &ViewCallback::callback, &aView1);
+ int nView1 = pDocument->m_pDocumentClass->getView(pDocument);
+
+ // Create a second view.
+ pDocument->m_pDocumentClass->createView(pDocument);
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+ ViewCallback aView2;
+ pDocument->m_pDocumentClass->registerCallback(pDocument, &ViewCallback::callback, &aView2);
+
+ // Go to the second slide in the second view.
+ pDocument->m_pDocumentClass->setPart(pDocument, 1);
+
+ // Switch back to the first view and start typing.
+ pDocument->m_pDocumentClass->setView(pDocument, nView1);
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 'x', 0);
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 'x', 0);
+
+ // Call paintPartTile() to paint the second part (in whichever view it finds suitable for this).
+ unsigned char pPixels[256 * 256 * 4];
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 256, 256, 0, 0, 256, 256);
+
+ // Type again.
+ Scheduler::ProcessEventsToIdle();
+ aView1.m_bTilesInvalidated = false;
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 'x', 0);
+ pDocument->m_pDocumentClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 'x', 0);
+ Scheduler::ProcessEventsToIdle();
+ // This failed: paintPartTile() (as a side-effect) ended the text edit of
+ // the first view, so there were no invalidations.
+ CPPUNIT_ASSERT(aView1.m_bTilesInvalidated);
+
+ mxComponent->dispose();
+ mxComponent.clear();
+ comphelper::LibreOfficeKit::setActive(false);
+}
CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 37a65d1e1939..18cb0532b57e 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1483,6 +1483,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight)
{
+ SolarMutexGuard aGuard;
SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " ["
<< nTileWidth << "x" << nTileHeight << "]@("
<< nTilePosX << ", " << nTilePosY << ") to ["
@@ -1500,8 +1501,27 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
// Text documents have a single coordinate system; don't change part.
int nOrigPart = 0;
const bool isText = (doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT);
+ int nOrigViewId = doc_getView(pThis);
+ int nViewId = nOrigViewId;
if (!isText)
{
+ // Check if just switching to an other view is enough, that has
+ // less side-effects.
+ if (nPart != doc_getPart(pThis))
+ {
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while (pViewShell)
+ {
+ if (pViewShell->getPart() == nPart)
+ {
+ nViewId = pViewShell->GetViewShellId();
+ doc_setView(pThis, nViewId);
+ break;
+ }
+ pViewShell = SfxViewShell::GetNext(*pViewShell);
+ }
+ }
+
nOrigPart = doc_getPart(pThis);
if (nPart != nOrigPart)
{
@@ -1515,6 +1535,10 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
{
doc_setPart(pThis, nOrigPart);
}
+ if (!isText && nViewId != nOrigViewId)
+ {
+ doc_setView(pThis, nOrigViewId);
+ }
}
catch (const std::exception&)
{