include/vcl/ITiledRenderable.hxx | 45 +++++++++++++++++++++++++ include/vcl/window.hxx | 7 +++ sc/source/ui/inc/gridwin.hxx | 7 +++ sc/source/ui/unoobj/docuno.cxx | 43 +++++++++++------------ sc/source/ui/view/gridwin.cxx | 15 ++++++++ sd/qa/unit/tiledrendering/tiledrendering.cxx | 7 +++ sd/source/ui/inc/ViewShell.hxx | 6 --- sd/source/ui/inc/Window.hxx | 6 +++ sd/source/ui/unoidl/unomodel.cxx | 39 ++++++++++----------- sd/source/ui/view/sdwindow.cxx | 39 +++++++++++++++++++++ sd/source/ui/view/viewshel.cxx | 39 --------------------- sw/qa/extras/tiledrendering/tiledrendering.cxx | 44 +++++++++++++++++++----- sw/source/uibase/inc/edtwin.hxx | 6 +-- sw/source/uibase/uno/unotxdoc.cxx | 34 ++++++++++-------- 14 files changed, 219 insertions(+), 118 deletions(-)
New commits: commit 743aee0ad16449ba0ecf506e0a650b45b89628bc Author: Pranav Kant <pran...@collabora.co.uk> Date: Sat Feb 24 12:19:57 2018 +0530 lok: All mouse,key events async custom posting of mouse,key events on main thread This still bypasses vcl while keeping the processing of events on the main thread which is what we want. Change-Id: Ia7a6f5ef1ac546245715abe418d261b49df12d4c Reviewed-on: https://gerrit.libreoffice.org/50274 Reviewed-by: Aron Budea <aron.bu...@collabora.com> Tested-by: Aron Budea <aron.bu...@collabora.com> diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index b14ee48f341e..cea97828d7ed 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -14,6 +14,8 @@ #include <LibreOfficeKit/LibreOfficeKitTypes.h> #include <tools/gen.hxx> #include <svx/ruler.hxx> +#include <vcl/event.hxx> +#include <vcl/vclevent.hxx> #include <vcl/pointr.hxx> #include <vcl/ptrstyle.hxx> #include <vcl/virdev.hxx> @@ -88,6 +90,48 @@ protected: int mnTilePixelWidth, mnTilePixelHeight; int mnTileTwipWidth, mnTileTwipHeight; public: + struct LOKAsyncEventData + { + VclPtr<vcl::Window> mpWindow; + sal_uLong mnEvent; + MouseEvent maMouseEvent; + KeyEvent maKeyEvent; + }; + + static void LOKPostAsyncEvent(void* pEv, void*) + { + LOKAsyncEventData* pLOKEv = static_cast<LOKAsyncEventData*>(pEv); + switch (pLOKEv->mnEvent) + { + case VCLEVENT_WINDOW_KEYINPUT: + pLOKEv->mpWindow->KeyInput(pLOKEv->maKeyEvent); + break; + case VCLEVENT_WINDOW_KEYUP: + pLOKEv->mpWindow->KeyUp(pLOKEv->maKeyEvent); + break; + case VCLEVENT_WINDOW_MOUSEBUTTONDOWN: + pLOKEv->mpWindow->LogicMouseButtonDown(pLOKEv->maMouseEvent); + // Invoke the context menu + if (pLOKEv->maMouseEvent.GetButtons() & MOUSE_RIGHT) + { + const CommandEvent aCEvt(pLOKEv->maMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true, nullptr); + pLOKEv->mpWindow->Command(aCEvt); + } + break; + case VCLEVENT_WINDOW_MOUSEBUTTONUP: + pLOKEv->mpWindow->LogicMouseButtonUp(pLOKEv->maMouseEvent); + break; + case VCLEVENT_WINDOW_MOUSEMOVE: + pLOKEv->mpWindow->LogicMouseMove(pLOKEv->maMouseEvent); + break; + default: + assert(false); + break; + } + + delete pLOKEv; + } + virtual ~ITiledRenderable(); /** @@ -329,6 +373,7 @@ public: return OUString(); } + }; } // namespace vcl diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx index 910ce0344045..cfc9e2c71919 100644 --- a/include/vcl/window.hxx +++ b/include/vcl/window.hxx @@ -1222,6 +1222,13 @@ public: /// Dialog / window tunneling related methods. Size PaintActiveFloatingWindow(VirtualDevice& rDevice) const; + /// Same as MouseButtonDown(), but coordinates are in logic unit. used for LOK + virtual void LogicMouseButtonDown(const MouseEvent&) {}; + /// Same as MouseButtonUp(), but coordinates are in logic unit. used for LOK + virtual void LogicMouseButtonUp(const MouseEvent&) {}; + /// Same as MouseMove(), but coordinates are in logic unit. used for LOK + virtual void LogicMouseMove(const MouseEvent&) {}; + /** @name Accessibility */ ///@{ diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 607f1fbd1697..9830834a4bbd 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -438,6 +438,13 @@ public: long nTileHeight); void updateLibreOfficeKitCellCursor(SfxViewShell* pOtherShell) const; + /// Same as MouseButtonDown(), but coordinates are in logic unit. + virtual void LogicMouseButtonDown(const MouseEvent& rMouseEvent) override; + /// Same as MouseButtonUp(), but coordinates are in logic unit. + virtual void LogicMouseButtonUp(const MouseEvent& rMouseEvent) override; + /// Same as MouseMove(), but coordinates are in logic unit. + virtual void LogicMouseMove(const MouseEvent& rMouseEvent) override; + ScViewData* getViewData(); virtual FactoryFunction GetUITestFactory() const override; diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 7a1af69926f3..8638ac08406f 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -611,6 +611,7 @@ Size ScModelObj::getDocumentSize() return aSize; } + void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode) { SolarMutexGuard aGuard; @@ -619,21 +620,22 @@ void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode) if (!pWindow) return; - if (!pWindow->HasFocus()) - pWindow->GrabFocus(); - KeyEvent aEvent(nCharCode, nKeyCode, 0); + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = pWindow; switch (nType) { case LOK_KEYEVENT_KEYINPUT: - Application::PostKeyEvent(VCLEVENT_WINDOW_KEYINPUT, pWindow, &aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYINPUT; break; case LOK_KEYEVENT_KEYUP: - Application::PostKeyEvent(VCLEVENT_WINDOW_KEYUP, pWindow, &aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYUP; break; default: assert(false); - break; } + + pLOKEv->maKeyEvent = KeyEvent(nCharCode, nKeyCode, 0); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) @@ -668,34 +670,29 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt return; } - - // Calc operates in pixels... - Point aPos(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()); - MouseEvent aEvent(aPos, nCount, - MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); - + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = pGridWindow; switch (nType) { case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: - Application::PostMouseEvent(VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pGridWindow, &aEvent); - - // Invoke the context menu - if (nButtons & MOUSE_RIGHT) - { - const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr); - pGridWindow->Command(aCEvt); - } + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONDOWN; break; case LOK_MOUSEEVENT_MOUSEBUTTONUP: - Application::PostMouseEvent(VCLEVENT_WINDOW_MOUSEBUTTONUP, pGridWindow, &aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONUP; break; case LOK_MOUSEEVENT_MOUSEMOVE: - Application::PostMouseEvent(VCLEVENT_WINDOW_MOUSEMOVE, pGridWindow, &aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEMOVE; break; default: assert(false); - break; } + + // Calc operates in pixels... + const Point aPos(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()); + pLOKEv->maMouseEvent = MouseEvent(aPos, nCount, + MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void ScModelObj::setTextSelection(int nType, int nX, int nY) diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index e26a1c5f2d1f..0a4c69ceded8 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -1521,6 +1521,21 @@ bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, bool bAction ) return bNewPointer; } +void ScGridWindow::LogicMouseButtonDown(const MouseEvent& rMouseEvent) +{ + MouseButtonDown(rMouseEvent); +} + +void ScGridWindow::LogicMouseButtonUp(const MouseEvent& rMouseEvent) +{ + MouseButtonUp(rMouseEvent); +} + +void ScGridWindow::LogicMouseMove(const MouseEvent& rMouseEvent) +{ + MouseMove(rMouseEvent); +} + void ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt ) { nNestedButtonState = ScNestedButtonState::Down; diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 8b7a7ee89293..f2372fc711a7 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -343,6 +343,7 @@ void SdTiledRenderingTest::testRegisterCallback() void SdTiledRenderingTest::testPostKeyEvent() { + comphelper::LibreOfficeKit::setActive(); SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp"); sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); SdPage* pActualPage = pViewShell->GetActualPage(); @@ -357,6 +358,7 @@ void SdTiledRenderingTest::testPostKeyEvent() pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT(pView->GetTextEditObject()); EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); @@ -366,6 +368,7 @@ void SdTiledRenderingTest::testPostKeyEvent() rEditView.SetSelection(aWordSelection); // Did we enter the expected character? CPPUNIT_ASSERT_EQUAL(OUString("xx"), rEditView.GetSelected()); + comphelper::LibreOfficeKit::setActive(false); } void SdTiledRenderingTest::testPostMouseEvent() @@ -396,6 +399,7 @@ void SdTiledRenderingTest::testPostMouseEvent() pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, convertMm100ToTwip(aPosition.getX()), convertMm100ToTwip(aPosition.getY()), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); CPPUNIT_ASSERT(pView->GetTextEditObject()); // The new cursor position must be before the first word. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rEditView.GetSelection().nStartPos); @@ -1338,6 +1342,7 @@ void SdTiledRenderingTest::testTdf102223() pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, convertMm100ToTwip(aRect.getX() + 2), convertMm100ToTwip(aRect.getY() + 2), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); pView->SdrBeginTextEdit(pTableObject); CPPUNIT_ASSERT(pView->GetTextEditObject()); EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); @@ -1431,6 +1436,7 @@ void SdTiledRenderingTest::testTdf103083() pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, convertMm100ToTwip(aRect.getX() + 2), convertMm100ToTwip(aRect.getY() + 2), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); pView->SdrBeginTextEdit(pTextObject); CPPUNIT_ASSERT(pView->GetTextEditObject()); EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); @@ -1546,7 +1552,6 @@ void SdTiledRenderingTest::testTdf81754() pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); - Scheduler::ProcessEventsToIdle(); // now save, reload, and assert that we did not lose the edit diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index fa1a6962cece..075cb634389c 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -419,12 +419,6 @@ public: SdPage* pPage, const sal_Int32 nInsertPosition = -1); - /// Same as MouseButtonDown(), but coordinates are in logic unit. - void LogicMouseButtonDown(const MouseEvent& rMouseEvent); - /// Same as MouseButtonUp(), but coordinates are in logic unit. - void LogicMouseButtonUp(const MouseEvent& rMouseEvent); - /// Same as MouseMove(), but coordinates are in logic unit. - void LogicMouseMove(const MouseEvent& rMouseEvent); /// Allows adjusting the point or mark of the selection to a document coordinate. void SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark); /// Gets the currently selected text. diff --git a/sd/source/ui/inc/Window.hxx b/sd/source/ui/inc/Window.hxx index 5c3e08a9a4a6..a91a71ea70d3 100644 --- a/sd/source/ui/inc/Window.hxx +++ b/sd/source/ui/inc/Window.hxx @@ -192,6 +192,12 @@ protected: Selection GetSurroundingTextSelection() const override; /// @see OutputDevice::LogicInvalidate(). void LogicInvalidate(const Rectangle* pRectangle) override; + /// Same as MouseButtonDown(), but coordinates are in logic unit. + virtual void LogicMouseButtonDown(const MouseEvent& rMouseEvent) override; + /// Same as MouseButtonUp(), but coordinates are in logic unit. + virtual void LogicMouseButtonUp(const MouseEvent& rMouseEvent) override; + /// Same as MouseMove(), but coordinates are in logic unit. + virtual void LogicMouseMove(const MouseEvent& rMouseEvent) override; FactoryFunction GetUITestFactory() const override; }; diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index d9ea81e4982e..597787533010 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -2506,20 +2506,22 @@ void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode) if (!pWindow) return; - KeyEvent aEvent(nCharCode, nKeyCode, 0); - + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = pWindow; switch (nType) { case LOK_KEYEVENT_KEYINPUT: - pWindow->KeyInput(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYINPUT; break; case LOK_KEYEVENT_KEYUP: - pWindow->KeyUp(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYUP; break; default: assert(false); - break; } + + pLOKEv->maKeyEvent = KeyEvent(nCharCode, nKeyCode, 0); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) @@ -2547,33 +2549,28 @@ void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, i return; } - Window* pWindow = pViewShell->GetActiveWindow(); - - Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY))); - MouseEvent aEvent(aPos, nCount, - MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); - + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = pViewShell->GetActiveWindow(); switch (nType) { case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: - pViewShell->LogicMouseButtonDown(aEvent); - - if (nButtons & MOUSE_RIGHT) - { - const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr); - pViewShell->Command(aCEvt, pWindow); - } + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONDOWN; break; case LOK_MOUSEEVENT_MOUSEBUTTONUP: - pViewShell->LogicMouseButtonUp(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONUP; break; case LOK_MOUSEEVENT_MOUSEMOVE: - pViewShell->LogicMouseMove(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEMOVE; break; default: assert(false); - break; } + + const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY))); + pLOKEv->maMouseEvent = MouseEvent(aPos, nCount, + MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void SdXImpressDocument::setTextSelection(int nType, int nX, int nY) diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index e1b4fa5267b3..7472695ee728 100644 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -1016,6 +1016,45 @@ void Window::LogicInvalidate(const Rectangle* pRectangle) SfxLokHelper::notifyInvalidation(&rSfxViewShell, sRectangle); } +void Window::LogicMouseButtonDown(const MouseEvent& rMouseEvent) +{ + // When we're not doing tiled rendering, then positions must be passed as pixels. + assert(comphelper::LibreOfficeKit::isActive()); + + Point aPoint = GetPointerPosPixel(); + SetLastMousePos(rMouseEvent.GetPosPixel()); + + mpViewShell->MouseButtonDown(rMouseEvent, this); + + SetPointerPosPixel(aPoint); +} + +void Window::LogicMouseButtonUp(const MouseEvent& rMouseEvent) +{ + // When we're not doing tiled rendering, then positions must be passed as pixels. + assert(comphelper::LibreOfficeKit::isActive()); + + Point aPoint = GetPointerPosPixel(); + SetLastMousePos(rMouseEvent.GetPosPixel()); + + mpViewShell->MouseButtonUp(rMouseEvent, this); + + SetPointerPosPixel(aPoint); +} + +void Window::LogicMouseMove(const MouseEvent& rMouseEvent) +{ + // When we're not doing tiled rendering, then positions must be passed as pixels. + assert(comphelper::LibreOfficeKit::isActive()); + + Point aPoint = GetPointerPosPixel(); + SetLastMousePos(rMouseEvent.GetPosPixel()); + + mpViewShell->MouseMove(rMouseEvent, this); + + SetPointerPosPixel(aPoint); +} + FactoryFunction Window::GetUITestFactory() const { if (get_id() == "impress_win") diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 2a6fd8b2c4bc..4ffa61f7cdf4 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -499,45 +499,6 @@ void ViewShell::MouseButtonDown(const MouseEvent& rMEvt, ::sd::Window* pWin) } } -void ViewShell::LogicMouseButtonDown(const MouseEvent& rMouseEvent) -{ - // When we're not doing tiled rendering, then positions must be passed as pixels. - assert(comphelper::LibreOfficeKit::isActive()); - - Point aPoint = mpActiveWindow->GetPointerPosPixel(); - mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); - - MouseButtonDown(rMouseEvent, mpActiveWindow); - - mpActiveWindow->SetPointerPosPixel(aPoint); -} - -void ViewShell::LogicMouseButtonUp(const MouseEvent& rMouseEvent) -{ - // When we're not doing tiled rendering, then positions must be passed as pixels. - assert(comphelper::LibreOfficeKit::isActive()); - - Point aPoint = mpActiveWindow->GetPointerPosPixel(); - mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); - - MouseButtonUp(rMouseEvent, mpActiveWindow); - - mpActiveWindow->SetPointerPosPixel(aPoint); -} - -void ViewShell::LogicMouseMove(const MouseEvent& rMouseEvent) -{ - // When we're not doing tiled rendering, then positions must be passed as pixels. - assert(comphelper::LibreOfficeKit::isActive()); - - Point aPoint = mpActiveWindow->GetPointerPosPixel(); - mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); - - MouseMove(rMouseEvent, mpActiveWindow); - - mpActiveWindow->SetPointerPosPixel(aPoint); -} - void ViewShell::SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark) { if (SdrView* pSdrView = GetView()) diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index bb539a326149..b437016afb5f 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -306,6 +306,7 @@ void SwTiledRenderingTest::testPostKeyEvent() pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); // Did we manage to insert the character after the first one? CPPUNIT_ASSERT_EQUAL(OUString("Axaa bbb."), pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->GetText()); } @@ -324,6 +325,7 @@ void SwTiledRenderingTest::testPostMouseEvent() aStart.setX(aStart.getX() - 1000); pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0); pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); // The new cursor position must be before the first word. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pShellCursor->GetPoint()->nContent.GetIndex()); comphelper::LibreOfficeKit::setActive(false); @@ -930,20 +932,24 @@ void SwTiledRenderingTest::testShapeViewCursors() pWrtShell2->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell2->GetWin()); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); - + Scheduler::ProcessEventsToIdle(); // Press a key in the second view, while the first one observes this. - aView1.m_bOwnCursorInvalidated = false; aView1.m_bViewCursorInvalidated = false; aView2.m_bOwnCursorInvalidated = false; - aView2.m_bViewCursorInvalidated = false; + const Rectangle aLastOwnCursor1 = aView1.m_aOwnCursor; + const Rectangle aLastViewCursor1 = aView1.m_aViewCursor; + const Rectangle aLastOwnCursor2 = aView2.m_aOwnCursor; + const Rectangle aLastViewCursor2 = aView2.m_aViewCursor; + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'y', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'y', 0); + Scheduler::ProcessEventsToIdle(); // Make sure that aView1 gets a view-only cursor notification, while // aView2 gets a real cursor notification. - CPPUNIT_ASSERT(!aView1.m_bOwnCursorInvalidated); - CPPUNIT_ASSERT(aView1.m_bViewCursorInvalidated); - CPPUNIT_ASSERT(aView2.m_bOwnCursorInvalidated); - CPPUNIT_ASSERT(!aView2.m_bViewCursorInvalidated); + CPPUNIT_ASSERT(aView1.m_aOwnCursor == aLastOwnCursor1); + CPPUNIT_ASSERT(aView1.m_bViewCursorInvalidated && aLastViewCursor1 != aView1.m_aViewCursor); + CPPUNIT_ASSERT(aView2.m_bOwnCursorInvalidated && aLastOwnCursor2 != aView2.m_aOwnCursor); + CPPUNIT_ASSERT(aLastViewCursor2 == aView2.m_aViewCursor); mxComponent->dispose(); mxComponent.clear(); @@ -1073,11 +1079,14 @@ void SwTiledRenderingTest::testTextEditViewInvalidations() pWrtShell->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell->GetWin()); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); // Assert that both views are invalidated when pressing a key while in text edit. aView1.m_bTilesInvalidated = false; pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'y', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'y', 0); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT(aView1.m_bTilesInvalidated); pWrtShell->EndTextEdit(); @@ -1105,6 +1114,9 @@ void SwTiledRenderingTest::testUndoInvalidations() pWrtShell->EndDoc(); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0); + Scheduler::ProcessEventsToIdle(); + // ProcessEventsToIdle resets the view; set it again + SfxLokHelper::setView(nView1); SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false); CPPUNIT_ASSERT_EQUAL(OUString("Aaa bbb.c"), pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->GetText()); @@ -1136,6 +1148,7 @@ void SwTiledRenderingTest::testUndoLimiting() pWrtShell2->EndDoc(); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0); + Scheduler::ProcessEventsToIdle(); SwShellCursor* pShellCursor = pWrtShell2->getShellCursor(false); CPPUNIT_ASSERT_EQUAL(OUString("Aaa bbb.c"), pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->GetText()); @@ -1163,6 +1176,7 @@ void SwTiledRenderingTest::testUndoShapeLimiting() pWrtShell2->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell2->GetWin()); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); // Assert that the first view can't and the second view can undo the insertion. SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc(); @@ -1192,6 +1206,7 @@ void SwTiledRenderingTest::testUndoDispatch() SfxLokHelper::setView(nView1); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0); + Scheduler::ProcessEventsToIdle(); // Click before the first word in the second view. SfxLokHelper::setView(nView2); @@ -1201,6 +1216,7 @@ void SwTiledRenderingTest::testUndoDispatch() aStart.setX(aStart.getX() - 1000); pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0); pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(comphelper::getProcessComponentContext()); uno::Reference<frame::XFrame> xFrame2 = xDesktop->getActiveFrame(); @@ -1227,6 +1243,7 @@ void SwTiledRenderingTest::testUndoRepairDispatch() SfxLokHelper::setView(nView1); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0); + Scheduler::ProcessEventsToIdle(); // Assert that by default the second view can't undo the action. SfxLokHelper::setView(nView2); @@ -1267,6 +1284,7 @@ void SwTiledRenderingTest::testShapeTextUndoShells() pWrtShell->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell->GetWin()); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); // Make sure that the undo item remembers who created it. SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc(); @@ -1299,6 +1317,7 @@ void SwTiledRenderingTest::testShapeTextUndoGroupShells() pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::BACKSPACE); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::BACKSPACE); + Scheduler::ProcessEventsToIdle(); // Make sure that the undo item remembers who created it. SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc(); @@ -1311,6 +1330,7 @@ void SwTiledRenderingTest::testShapeTextUndoGroupShells() EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); // 0th para, 0th char -> 0th para, 1st char. ESelection aWordSelection(0, 0, 0, 1); rEditView.SetSelection(aWordSelection); @@ -1585,22 +1605,23 @@ void SwTiledRenderingTest::testCommentEndTextEdit() SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); Rectangle aBodyCursor = aView1.m_aOwnCursor; // Create a comment and type a character there as well. const int nCtrlAltC = KEY_MOD1 + KEY_MOD2 + 512 + 'c' - 'a'; pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', nCtrlAltC); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', nCtrlAltC); - Scheduler::ProcessEventsToIdle(); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); - + Scheduler::ProcessEventsToIdle(); // End comment text edit by clicking in the body text area, and assert that // no unexpected cursor callbacks are emitted at origin (top left corner of // the document). aView1.m_bOwnCursorAtOrigin = false; pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aBodyCursor.getX(), aBodyCursor.getY(), 1, MOUSE_LEFT, 0); pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aBodyCursor.getX(), aBodyCursor.getY(), 1, MOUSE_LEFT, 0); + Scheduler::ProcessEventsToIdle(); // This failed, the cursor was at 0, 0 at some point during end text edit // of the comment. CPPUNIT_ASSERT(!aView1.m_bOwnCursorAtOrigin); @@ -1687,11 +1708,13 @@ void SwTiledRenderingTest::testUndoRepairResult() SfxLokHelper::setView(nView2); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0); + Scheduler::ProcessEventsToIdle(); // Insert a character in the first view. SfxLokHelper::setView(nView1); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0); + Scheduler::ProcessEventsToIdle(); // Assert that by default the second view can't undo the action. SfxLokHelper::setView(nView2); @@ -1720,11 +1743,14 @@ void SwTiledRenderingTest::testRedoRepairResult() SfxLokHelper::setView(nView2); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0); + Scheduler::ProcessEventsToIdle(); // Insert a character in the first view. SfxLokHelper::setView(nView1); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0); pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0); + Scheduler::ProcessEventsToIdle(); + comphelper::dispatchCommand(".uno:Undo", {}, xListener); CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), pResult2->m_nDocRepair); diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index bc390609a41b..7ede77f7a3ce 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -299,11 +299,11 @@ public: /// @see OutputDevice::LogicInvalidate(). void LogicInvalidate(const Rectangle* pRectangle) override; /// Same as MouseButtonDown(), but coordinates are in logic unit. - void LogicMouseButtonDown(const MouseEvent& rMouseEvent); + virtual void LogicMouseButtonDown(const MouseEvent& rMouseEvent) override; /// Same as MouseButtonUp(), but coordinates are in logic unit. - void LogicMouseButtonUp(const MouseEvent& rMouseEvent); + virtual void LogicMouseButtonUp(const MouseEvent& rMouseEvent) override; /// Same as MouseMove(), but coordinates are in logic unit. - void LogicMouseMove(const MouseEvent& rMouseEvent); + virtual void LogicMouseMove(const MouseEvent& rMouseEvent) override; /// Allows adjusting the point or mark of the selection to a document coordinate. void SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool bClearMark); /// Allows starting or ending a graphic move or resize action. diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx index 0244b3db6a2b..e8dbe796ca5b 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -3495,19 +3495,22 @@ void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode) if (!pWindow) return; - KeyEvent aEvent(nCharCode, nKeyCode, 0); + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = pWindow; switch (nType) { case LOK_KEYEVENT_KEYINPUT: - pWindow->KeyInput(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYINPUT; break; case LOK_KEYEVENT_KEYUP: - pWindow->KeyUp(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_KEYUP; break; default: assert(false); - break; } + + pLOKEv->maKeyEvent = KeyEvent(nCharCode, nKeyCode, 0); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) @@ -3535,30 +3538,29 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int } SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin(); - Point aPos(nX , nY); - MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); + + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + pLOKEv->mpWindow = &rEditWin; switch (nType) { case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: - rEditWin.LogicMouseButtonDown(aEvent); - - if (nButtons & MOUSE_RIGHT) - { - const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr); - rEditWin.Command(aCEvt); - } + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONDOWN; break; case LOK_MOUSEEVENT_MOUSEBUTTONUP: - rEditWin.LogicMouseButtonUp(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEBUTTONUP; break; case LOK_MOUSEEVENT_MOUSEMOVE: - rEditWin.LogicMouseMove(aEvent); + pLOKEv->mnEvent = VCLEVENT_WINDOW_MOUSEMOVE; break; default: assert(false); - break; } + + pLOKEv->maMouseEvent = MouseEvent(Point(nX, nY), nCount, + MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); + Application::PostUserEvent(Link<void*, void>(pLOKEv, ITiledRenderable::LOKPostAsyncEvent)); } void SwXTextDocument::setTextSelection(int nType, int nX, int nY) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits