include/vcl/svapp.hxx | 3 + vcl/inc/window.h | 10 +++ vcl/source/app/svapp.cxx | 68 ++++++++++++++++++++++ vcl/source/window/winproc.cxx | 126 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 205 insertions(+), 2 deletions(-)
New commits: commit 8a0ada00e20f1450d29a4f8ab416d3e6c96d9600 Author: Henry Castro <hcas...@collabora.com> AuthorDate: Wed Jun 23 08:37:34 2021 -0400 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Thu Oct 7 11:40:39 2021 +0200 lok: introduce Application::LOKHandleMouseEvent Entry point to call the ImplLOKHandleMouseEvent function mainly to process mouse events. Change-Id: I17513643733bf5990d41ab8cf47cdc322ed526ea Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118846 Tested-by: Szymon Kłos <szymon.k...@collabora.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index d6a6bfbc5065..3746b09dcc6a 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -741,6 +741,9 @@ public: */ static ImplSVEvent * PostKeyEvent( VclEventId nEvent, vcl::Window *pWin, KeyEvent const * pKeyEvent ); + + static bool LOKHandleMouseEvent( VclEventId nEvent, vcl::Window *pWin, const MouseEvent* pEvent ); + /** Send mouse event @param nEvent Event ID for mouse event diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 928481aa23a5..aebd513426f9 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -30,6 +30,7 @@ #include <vcl/settings.hxx> #include <o3tl/typed_flags_set.hxx> #include <cppuhelper/weakref.hxx> +#include <salwtype.hxx> #include <optional> #include <list> @@ -96,6 +97,10 @@ bool isEnabledInLayout(const vcl::Window *pWindow); bool ImplWindowFrameProc( vcl::Window* pInst, SalEvent nEvent, const void* pEvent ); +MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent ); + +MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent const * pEvent ); + struct ImplWinData { std::optional<OUString> diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 10ca0e206325..efffc46d3b56 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -898,6 +898,74 @@ ImplSVEvent* Application::PostGestureEvent(VclEventId nEvent, vcl::Window* pWin, return nEventId; } +bool Application::LOKHandleMouseEvent(VclEventId nEvent, vcl::Window* pWindow, const MouseEvent* pEvent) +{ + bool bSuccess = false; + SalMouseEvent aMouseEvent; + + if (!pWindow) + return false; + + if (!pEvent) + return false; + + aMouseEvent.mnTime = tools::Time::GetSystemTicks(); + aMouseEvent.mnX = pEvent->GetPosPixel().X(); + aMouseEvent.mnY = pEvent->GetPosPixel().Y(); + aMouseEvent.mnCode = pEvent->GetButtons() | pEvent->GetModifier(); + + switch (nEvent) + { + case VclEventId::WindowMouseMove: + aMouseEvent.mnButton = 0; + bSuccess = ImplLOKHandleMouseEvent(pWindow, MouseNotifyEvent::MOUSEMOVE, false, + aMouseEvent.mnX, aMouseEvent.mnY, + aMouseEvent.mnTime, aMouseEvent.mnCode, + ImplGetMouseMoveMode(&aMouseEvent), + pEvent->GetClicks()); + break; + + case VclEventId::WindowMouseButtonDown: + aMouseEvent.mnButton = pEvent->GetButtons(); + bSuccess = ImplLOKHandleMouseEvent(pWindow, MouseNotifyEvent::MOUSEBUTTONDOWN, false, + aMouseEvent.mnX, aMouseEvent.mnY, + aMouseEvent.mnTime, +#ifdef MACOSX + aMouseEvent.mnButton | + (aMouseEvent.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)), +#else + aMouseEvent.mnButton | + (aMouseEvent.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)), +#endif + ImplGetMouseButtonMode(&aMouseEvent), + pEvent->GetClicks()); + break; + + case VclEventId::WindowMouseButtonUp: + aMouseEvent.mnButton = pEvent->GetButtons(); + bSuccess = ImplLOKHandleMouseEvent(pWindow, MouseNotifyEvent::MOUSEBUTTONUP, false, + aMouseEvent.mnX, aMouseEvent.mnY, + aMouseEvent.mnTime, +#ifdef MACOSX + aMouseEvent.mnButton | + (aMouseEvent.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)), +#else + aMouseEvent.mnButton | + (aMouseEvent.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)), +#endif + ImplGetMouseButtonMode(&aMouseEvent), + pEvent->GetClicks()); + break; + + default: + SAL_WARN( "vcl.layout", "Application::HandleMouseEvent unknown event (" << static_cast<int>(nEvent) << ")" ); + break; + } + + return bSuccess; +} + + ImplSVEvent* Application::PostMouseEvent( VclEventId nEvent, vcl::Window *pWin, MouseEvent const * pMouseEvent ) { const SolarMutexGuard aGuard; diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 9ef66aadfb0e..fcbf268290a0 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -2137,7 +2137,7 @@ static void ImplHandleUserEvent( ImplSVEvent* pSVEvent ) } } -static MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent ) +MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent ) { MouseEventModifiers nMode = MouseEventModifiers::NONE; if ( !pEvent->mnCode ) @@ -2149,7 +2149,7 @@ static MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent ) return nMode; } -static MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent const * pEvent ) +MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent const * pEvent ) { MouseEventModifiers nMode = MouseEventModifiers::NONE; if ( pEvent->mnButton == MOUSE_LEFT ) commit 28a347ad3c64d53ab3b24b999df26a7057cc6392 Author: Henry Castro <hcas...@collabora.com> AuthorDate: Wed Jun 23 07:44:26 2021 -0400 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Thu Oct 7 11:40:24 2021 +0200 lok: sc: introduce ImplLOKHandleMouseEvent In tiled rendering case, each user has a View/Controller object to interact with a unique document (Model) for collaborating purposes. However, in the desktop case a unique user has many View/Controller objects to handle a unique document, so the user has only one global active focus, capture and tracking window object. In order to handle independent drag & drop for each user, it is created ImplLOKHandleMouseEvent. Change-Id: I735fae9b9858a75f9fedb603798220ab302d65f6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118843 Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> Tested-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/vcl/inc/window.h b/vcl/inc/window.h index a14852ca02c0..928481aa23a5 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -424,6 +424,11 @@ public: bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave, tools::Long nX, tools::Long nY, sal_uInt64 nMsgTime, sal_uInt16 nCode, MouseEventModifiers nMode ); + +bool ImplLOKHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave, + tools::Long nX, tools::Long nY, sal_uInt64 nMsgTime, + sal_uInt16 nCode, MouseEventModifiers nMode, sal_uInt16 nClicks); + void ImplHandleResize( vcl::Window* pWindow, tools::Long nNewWidth, tools::Long nNewHeight ); VCL_DLLPUBLIC void ImplWindowStateFromStr(WindowStateData& rData, const OString& rStr); diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 2096b7cf3da1..9ef66aadfb0e 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -792,6 +792,128 @@ bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent return bRet; } +bool ImplLOKHandleMouseEvent(const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent nEvent, bool /*bMouseLeave*/, + tools::Long nX, tools::Long nY, sal_uInt64 /*nMsgTime*/, + sal_uInt16 nCode, MouseEventModifiers nMode, sal_uInt16 nClicks) +{ + Point aMousePos(nX, nY); + + if (!xWindow) + return false; + + if (xWindow->isDisposed()) + return false; + + ImplFrameData* pFrameData = xWindow->ImplGetFrameData(); + if (!pFrameData) + return false; + + Point aWinPos = xWindow->ImplFrameToOutput(aMousePos); + + pFrameData->mnLastMouseX = nX; + pFrameData->mnLastMouseY = nY; + pFrameData->mnClickCount = nClicks; + pFrameData->mnMouseCode = nCode; + pFrameData->mbMouseIn = false; + + vcl::Window* pDownWin = pFrameData->mpMouseDownWin; + if (pDownWin && nEvent == MouseNotifyEvent::MOUSEMOVE) + { + const MouseSettings& aSettings = pDownWin->GetSettings().GetMouseSettings(); + if ((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) == + (MouseSettings::GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ) + { + if (!pFrameData->mbStartDragCalled) + { + tools::Long nDragWidth = aSettings.GetStartDragWidth(); + tools::Long nDragHeight = aSettings.GetStartDragHeight(); + tools::Long nMouseX = aMousePos.X(); + tools::Long nMouseY = aMousePos.Y(); + + if ((((nMouseX - nDragWidth) > pFrameData->mnFirstMouseX) || + ((nMouseX + nDragWidth) < pFrameData->mnFirstMouseX)) || + (((nMouseY - nDragHeight) > pFrameData->mnFirstMouseY) || + ((nMouseY + nDragHeight) < pFrameData->mnFirstMouseY))) + { + pFrameData->mbStartDragCalled = true; + + if (pFrameData->mbInternalDragGestureRecognizer) + { + // query DropTarget from child window + css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer( + pDownWin->ImplGetWindowImpl()->mxDNDListenerContainer, + css::uno::UNO_QUERY ); + + if (xDragGestureRecognizer.is()) + { + // create a UNO mouse event out of the available data + css::awt::MouseEvent aEvent( + static_cast < css::uno::XInterface * > ( nullptr ), + #ifdef MACOSX + nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3), + #else + nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2), + #endif + nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE), + nMouseX, + nMouseY, + nClicks, + false); + css::uno::Reference< css::datatransfer::dnd::XDragSource > xDragSource = + pDownWin->GetDragSource(); + + if (xDragSource.is()) + { + static_cast<DNDListenerContainer *>(xDragGestureRecognizer.get())-> + fireDragGestureEvent( + 0, + aWinPos.X(), + aWinPos.Y(), + xDragSource, + css::uno::makeAny(aEvent)); + } + } + } + } + } + else pFrameData->mbStartDragCalled = true; + } + } + + MouseEvent aMouseEvent(aWinPos, nClicks, nMode, nCode, nCode); + if (nEvent == MouseNotifyEvent::MOUSEMOVE) + { + xWindow->MouseMove(aMouseEvent); + } + else if (nEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) + { + pFrameData->mpMouseDownWin = xWindow; + pFrameData->mnFirstMouseX = aMousePos.X(); + pFrameData->mnFirstMouseY = aMousePos.Y(); + + xWindow->MouseButtonDown(aMouseEvent); + } + else + { + pFrameData->mpMouseDownWin = nullptr; + pFrameData->mpMouseMoveWin = nullptr; + pFrameData->mbStartDragCalled = false; + xWindow->MouseButtonUp(aMouseEvent); + } + + if (nEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) + { + // ContextMenu + if ( (nCode == MouseSettings::GetContextMenuCode()) && + (nClicks == MouseSettings::GetContextMenuClicks()) ) + { + ImplCallCommand(xWindow, CommandEventId::ContextMenu, nullptr, true, &aWinPos); + } + } + + return true; +} + static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow ) { ImplSVData* pSVData = ImplGetSVData();