desktop/qa/data/2slides.odp |binary desktop/qa/desktop_lib/test_desktop_lib.cxx | 74 ++++++++++++++++++++++++++++ desktop/source/lib/init.cxx | 24 +++++++++ 3 files changed, 98 insertions(+)
New commits: commit bee4ff508a456a1552aacdf6fc838b8b7cffb9ec Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Sep 14 19:47:47 2016 +0200 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 diff --git a/desktop/qa/data/2slides.odp b/desktop/qa/data/2slides.odp new file mode 100644 index 0000000..8be376f Binary files /dev/null and b/desktop/qa/data/2slides.odp differ diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 9e58327..28d78bc 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 37a65d1..18cb053 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&) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits