Kaydet (Commit) ba3d6d8a authored tarafından Miklos Vajna's avatar Miklos Vajna

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.

Change-Id: I6d16f24d13143dc263a89317fbc38111e652c0ac
üst c6fc963c
...@@ -77,6 +77,7 @@ public: ...@@ -77,6 +77,7 @@ public:
void testCreateViewGraphicSelection(); void testCreateViewGraphicSelection();
void testCreateViewTextCursor(); void testCreateViewTextCursor();
void testTdf102223(); void testTdf102223();
void testPostKeyEventInvalidation();
CPPUNIT_TEST_SUITE(SdTiledRenderingTest); CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback); CPPUNIT_TEST(testRegisterCallback);
...@@ -105,6 +106,7 @@ public: ...@@ -105,6 +106,7 @@ public:
CPPUNIT_TEST(testCreateViewGraphicSelection); CPPUNIT_TEST(testCreateViewGraphicSelection);
CPPUNIT_TEST(testCreateViewTextCursor); CPPUNIT_TEST(testCreateViewTextCursor);
CPPUNIT_TEST(testTdf102223); CPPUNIT_TEST(testTdf102223);
CPPUNIT_TEST(testPostKeyEventInvalidation);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
...@@ -1289,6 +1291,51 @@ void SdTiledRenderingTest::testTdf102223() ...@@ -1289,6 +1291,51 @@ void SdTiledRenderingTest::testTdf102223()
comphelper::LibreOfficeKit::setActive(false); 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_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <svx/fmshell.hxx> #include <svx/fmshell.hxx>
#include <sfx2/dispatch.hxx> #include <sfx2/dispatch.hxx>
#include <comphelper/lok.hxx>
#include "app.hrc" #include "app.hrc"
#include "strings.hrc" #include "strings.hrc"
...@@ -80,7 +81,15 @@ void DrawViewShell::MakeVisible(const Rectangle& rRect, vcl::Window& rWin) ...@@ -80,7 +81,15 @@ void DrawViewShell::MakeVisible(const Rectangle& rRect, vcl::Window& rWin)
// visible area // visible area
Size aVisSizePixel(rWin.GetOutputSizePixel()); 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))); Rectangle aVisArea(rWin.PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
if (bTiledRendering)
rWin.Pop();
Size aVisAreaSize(aVisArea.GetSize()); Size aVisAreaSize(aVisArea.GetSize());
if (!aVisArea.IsInside(rRect) && !SlideShow::IsRunning( GetViewShellBase() ) ) if (!aVisArea.IsInside(rRect) && !SlideShow::IsRunning( GetViewShellBase() ) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment