diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2019-03-13 17:18:11 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2019-03-14 10:14:11 +0100 |
commit | efef0583c62be4aeb5c360621cb3072ff336eb6b (patch) | |
tree | 346a86de3e7931b5292810811b054e04ac2b4da3 /sfx2 | |
parent | 1da82a6e80cd2147839031250dba10976560962d (diff) |
LOK: re-factor async key & mouse event re-posting.
A fairly pure re-factor, although adding disposed window
checking to a number of sites with a warning.
Moves the event emission helpers from VCL into SfxLokHelper: we're
going to need more view / integration here next anyway.
Removes lots of copy/paste horror.
Change-Id: I279c11a1d8093b4feeeb6b7850f500806fff80dd
Reviewed-on: https://gerrit.libreoffice.org/69218
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/source/view/lokcharthelper.cxx | 24 | ||||
-rw-r--r-- | sfx2/source/view/lokhelper.cxx | 118 |
2 files changed, 121 insertions, 21 deletions
diff --git a/sfx2/source/view/lokcharthelper.cxx b/sfx2/source/view/lokcharthelper.cxx index b17fbb28fdcf..d0d37e4865a4 100644 --- a/sfx2/source/view/lokcharthelper.cxx +++ b/sfx2/source/view/lokcharthelper.cxx @@ -284,33 +284,15 @@ bool LokChartHelper::postMouseEvent(int nType, int nX, int nY, tools::Rectangle rChartBBox = GetChartBoundingBox(); if (rChartBBox.IsInside(aMousePos)) { - vcl::ITiledRenderable::LOKAsyncEventData* pLOKEv = new vcl::ITiledRenderable::LOKAsyncEventData; - pLOKEv->mpWindow = pChartWindow; - switch (nType) - { - case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: - pLOKEv->mnEvent = VclEventId::WindowMouseButtonDown; - break; - case LOK_MOUSEEVENT_MOUSEBUTTONUP: - pLOKEv->mnEvent = VclEventId::WindowMouseButtonUp; - break; - case LOK_MOUSEEVENT_MOUSEMOVE: - pLOKEv->mnEvent = VclEventId::WindowMouseMove; - break; - default: - assert(false); - } - int nChartWinX = nX - rChartBBox.Left(); int nChartWinY = nY - rChartBBox.Top(); // chart window expects pixels, but the conversion factor // can depend on the client zoom Point aPos(nChartWinX * fScaleX, nChartWinY * fScaleY); - pLOKEv->maMouseEvent = MouseEvent(aPos, nCount, - MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); - - Application::PostUserEvent(Link<void*, void>(pLOKEv, vcl::ITiledRenderable::LOKPostAsyncEvent)); + SfxLokHelper::postMouseEventAsync(pChartWindow, nType, aPos, nCount, + MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); return true; } diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 374abf900936..016ca841a263 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -12,6 +12,7 @@ #include <com/sun/star/frame/Desktop.hpp> #include <comphelper/processfactory.hxx> +#include <vcl/svapp.hxx> #include <sfx2/viewsh.hxx> #include <sfx2/request.hxx> #include <sfx2/viewfrm.hxx> @@ -237,4 +238,121 @@ void SfxLokHelper::notifyContextChange(SfxViewShell const* pViewShell, const OUS pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_CHANGED, aBuffer.makeStringAndClear().getStr()); } + +namespace +{ + struct LOKAsyncEventData + { + VclPtr<vcl::Window> mpWindow; + VclEventId mnEvent; + MouseEvent maMouseEvent; + KeyEvent maKeyEvent; + }; + + void LOKPostAsyncEvent(void* pEv, void*) + { + LOKAsyncEventData* pLOKEv = static_cast<LOKAsyncEventData*>(pEv); + if (pLOKEv->mpWindow->IsDisposed()) + return; + + switch (pLOKEv->mnEvent) + { + case VclEventId::WindowKeyInput: + pLOKEv->mpWindow->KeyInput(pLOKEv->maKeyEvent); + break; + case VclEventId::WindowKeyUp: + pLOKEv->mpWindow->KeyUp(pLOKEv->maKeyEvent); + break; + case VclEventId::WindowMouseButtonDown: + 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 VclEventId::WindowMouseButtonUp: + pLOKEv->mpWindow->LogicMouseButtonUp(pLOKEv->maMouseEvent); + + // sometimes MouseButtonDown captures mouse and starts tracking, and VCL + // will not take care of releasing that with tiled rendering + if (pLOKEv->mpWindow->IsTracking()) + pLOKEv->mpWindow->EndTracking(); + + break; + case VclEventId::WindowMouseMove: + pLOKEv->mpWindow->LogicMouseMove(pLOKEv->maMouseEvent); + break; + default: + assert(false); + break; + } + + delete pLOKEv; + } + + void postEventAsync(LOKAsyncEventData *pEvent) + { + if (!pEvent->mpWindow || pEvent->mpWindow->IsDisposed()) + { + SAL_WARN("vcl", "Async event post - but no valid window as destination " << pEvent->mpWindow.get()); + delete pEvent; + return; + } + + Application::PostUserEvent(Link<void*, void>(pEvent, LOKPostAsyncEvent)); + } +} + +void SfxLokHelper::postKeyEventAsync(const VclPtr<vcl::Window> &xWindow, + int nType, int nCharCode, int nKeyCode) +{ + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + switch (nType) + { + case LOK_KEYEVENT_KEYINPUT: + pLOKEv->mnEvent = VclEventId::WindowKeyInput; + break; + case LOK_KEYEVENT_KEYUP: + pLOKEv->mnEvent = VclEventId::WindowKeyUp; + break; + default: + assert(false); + } + pLOKEv->maKeyEvent = KeyEvent(nCharCode, nKeyCode, 0); + pLOKEv->mpWindow = xWindow; + postEventAsync(pLOKEv); +} + +void SfxLokHelper::postMouseEventAsync(const VclPtr<vcl::Window> &xWindow, + int nType, const Point &rPos, + int nCount, MouseEventModifiers aModifiers, + int nButtons, int nModifier) +{ + LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; + switch (nType) + { + case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: + pLOKEv->mnEvent = VclEventId::WindowMouseButtonDown; + break; + case LOK_MOUSEEVENT_MOUSEBUTTONUP: + pLOKEv->mnEvent = VclEventId::WindowMouseButtonUp; + break; + case LOK_MOUSEEVENT_MOUSEMOVE: + pLOKEv->mnEvent = VclEventId::WindowMouseMove; + break; + default: + assert(false); + } + + // no reason - just always true so far. + assert (aModifiers == MouseEventModifiers::SIMPLECLICK); + + pLOKEv->maMouseEvent = MouseEvent(rPos, nCount, + aModifiers, nButtons, nModifier); + pLOKEv->mpWindow = xWindow; + postEventAsync(pLOKEv); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |