From 537847e0e517af42fd5c803016aeaaee6ea0c636 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 22 Sep 2016 15:27:40 +0200 Subject: sd lok: fix pixel-to-logic conversion in DrawViewShell::MakeVisible() The problem, as seen by the user is that during shape text edit, sometimes just traveling with the cursor causes invalidations, which is unexpected. What happens is sd::Window::KeyInput() invokes sd::DrawViewShell::MakeVisible(), which does a pixel-to-logic conversion, but because the map mode is in general disabled in the LOK case, nothing happens. Then a bit later aVisArea.IsInside(rRect) fails, as it compares pixel and logic units, which results in sd::ViewOverlayManager::UpdateTags() scheduling an async call to sd::ViewOverlayManager::UpdateTagsHdl(), which at the end causes a full invalidation in sd::SmartTagSet::remove(). Fix the situation by temporarily enabling map mode, so we don't detect a visible cursor area as a non-visible one. (cherry picked from commit ba3d6d8a39d31316923d2326059c07b0a7e3c05e) Conflicts: sd/qa/unit/tiledrendering/tiledrendering.cxx Change-Id: I6d16f24d13143dc263a89317fbc38111e652c0ac --- sd/qa/unit/tiledrendering/data/2slides.odp | Bin 0 -> 10984 bytes sd/qa/unit/tiledrendering/tiledrendering.cxx | 48 +++++++++++++++++++++++++++ sd/source/ui/view/drviewsh.cxx | 9 +++++ 3 files changed, 57 insertions(+) create mode 100644 sd/qa/unit/tiledrendering/data/2slides.odp (limited to 'sd') diff --git a/sd/qa/unit/tiledrendering/data/2slides.odp b/sd/qa/unit/tiledrendering/data/2slides.odp new file mode 100644 index 000000000000..baa42ba9fca5 Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/2slides.odp differ diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 4c92622aac13..796367bd69fd 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -72,6 +72,7 @@ public: void testUndoLimiting(); void testCreateViewGraphicSelection(); void testCreateViewTextCursor(); + void testPostKeyEventInvalidation(); CPPUNIT_TEST_SUITE(SdTiledRenderingTest); CPPUNIT_TEST(testRegisterCallback); @@ -99,6 +100,7 @@ public: CPPUNIT_TEST(testUndoLimiting); CPPUNIT_TEST(testCreateViewGraphicSelection); CPPUNIT_TEST(testCreateViewTextCursor); + CPPUNIT_TEST(testPostKeyEventInvalidation); CPPUNIT_TEST_SUITE_END(); private: @@ -1238,6 +1240,52 @@ void SdTiledRenderingTest::testCreateViewTextCursor() comphelper::LibreOfficeKit::setActive(false); } +void SdTiledRenderingTest::testPostKeyEventInvalidation() +{ + // Load a document and begin text edit on the first slide. + comphelper::LibreOfficeKit::setActive(); + SdXImpressDocument* pXImpressDocument = createDoc("2slides.odp"); + CPPUNIT_ASSERT_EQUAL(0, pXImpressDocument->getPart()); + ViewCallback aView1; + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + SdrView* pView = pViewShell->GetView(); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F2); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_F2); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT(pView->GetTextEditObject()); + + // Create a second view and begin text edit there as well, in parallel. + SfxLokHelper::createView(); + pXImpressDocument->initializeForTiledRendering({}); + ViewCallback aView2; + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2); + pXImpressDocument->setPart(1); + sd::ViewShell* pViewShell2 = pXImpressDocument->GetDocShell()->GetViewShell(); + SdrView* pView2 = pViewShell2->GetView(); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F2); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_F2); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT(pView2->GetTextEditObject()); + + // Now go left with the cursor in the second view an watch for + // invalidations. + aView2.m_bTilesInvalidated = false; + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_LEFT); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_LEFT); + Scheduler::ProcessEventsToIdle(); + // This failed: moving the cursor caused unexpected invalidation. + CPPUNIT_ASSERT(!aView2.m_bTilesInvalidated); + + mxComponent->dispose(); + mxComponent.clear(); + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sd/source/ui/view/drviewsh.cxx b/sd/source/ui/view/drviewsh.cxx index 8c043e3c0ae7..f61f6e266573 100644 --- a/sd/source/ui/view/drviewsh.cxx +++ b/sd/source/ui/view/drviewsh.cxx @@ -25,6 +25,7 @@ #include #include +#include #include "app.hrc" #include "strings.hrc" @@ -70,7 +71,15 @@ void DrawViewShell::MakeVisible(const Rectangle& rRect, vcl::Window& rWin) // visible area Size aVisSizePixel(rWin.GetOutputSizePixel()); + bool bTiledRendering = comphelper::LibreOfficeKit::isActive() && !rWin.IsMapModeEnabled(); + if (bTiledRendering) + { + rWin.Push(PushFlags::MAPMODE); + rWin.EnableMapMode(); + } Rectangle aVisArea(rWin.PixelToLogic(Rectangle(Point(0,0), aVisSizePixel))); + if (bTiledRendering) + rWin.Pop(); Size aVisAreaSize(aVisArea.GetSize()); if (!aVisArea.IsInside(rRect) && !SlideShow::IsRunning( GetViewShellBase() ) ) -- cgit