include/vcl/window.hxx | 2 vcl/inc/window.h | 2 vcl/source/window/window.cxx | 2 vcl/source/window/window2.cxx | 88 +++++++++++++++++++++++++++--------------- vcl/source/window/winproc.cxx | 16 ++++++- 5 files changed, 78 insertions(+), 32 deletions(-)
New commits: commit 7e7ae7ef1dd4d9c9c84ee0b96cb96f456c8da48e Author: Henry Castro <hcas...@collabora.com> AuthorDate: Thu Jun 24 07:30:15 2021 -0400 Commit: Henry Castro <hcas...@collabora.com> CommitDate: Thu Feb 10 13:04:47 2022 +0100 lok: introduce local mouse tracking Add the term local mouse tracking per frame window (per user) instead of global mouse tracking in the desktop case. Change-Id: I3f8c55fc770b4ac7dea167385586d8639ac4d93b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118856 Tested-by: Szymon Kłos <szymon.k...@collabora.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117777 Tested-by: Jenkins Reviewed-by: Henry Castro <hcas...@collabora.com> diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx index fb87796bdcd3..ac0bfa54ad0a 100644 --- a/include/vcl/window.hxx +++ b/include/vcl/window.hxx @@ -1096,6 +1096,8 @@ public: void SetComponentInterface( css::uno::Reference< css::awt::XWindowPeer > const & xIFace ); + void SetUseFrameData(bool bUseFrameData); + /// Interface to register for dialog / window tunneling. void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier, bool bParent = false); const vcl::ILibreOfficeKitNotifier* GetLOKNotifier() const; diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 1c3e2e1c41f9..c932a4d09d51 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -136,6 +136,7 @@ struct ImplFrameData VclPtr<vcl::Window> mpFocusWin; //< focus window (is also set, when frame doesn't have the focus) VclPtr<vcl::Window> mpMouseMoveWin; //< last window, where MouseMove() called VclPtr<vcl::Window> mpMouseDownWin; //< last window, where MouseButtonDown() called + VclPtr<vcl::Window> mpTrackWin; //< window, that is in tracking mode std::vector<VclPtr<vcl::Window> > maOwnerDrawList; //< List of system windows with owner draw decoration std::shared_ptr<vcl::font::PhysicalFontCollection> mxFontCollection; //< Font-List for this frame std::shared_ptr<ImplFontCache> mxFontCache; //< Font-Cache for this frame @@ -393,6 +394,7 @@ public: const vcl::ILibreOfficeKitNotifier* mpLOKNotifier; ///< To emit the LOK callbacks eg. for dialog tunneling. vcl::LOKWindowId mnLOKWindowId; ///< ID of this specific window. bool mbLOKParentNotifier; + bool mbUseFrameData; }; namespace vcl diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index bfab65f2fa8a..2072de7e0ed0 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -736,6 +736,7 @@ WindowImpl::WindowImpl( vcl::Window& rWindow, WindowType nType ) mpLOKNotifier = nullptr; mnLOKWindowId = 0; mbLOKParentNotifier = false; + mbUseFrameData = false; } WindowImpl::~WindowImpl() @@ -772,6 +773,7 @@ ImplFrameData::ImplFrameData( vcl::Window *pWindow ) mpFocusWin = nullptr; mpMouseMoveWin = nullptr; mpMouseDownWin = nullptr; + mpTrackWin = nullptr; mxFontCollection = pSVData->maGDIData.mxScreenFontList; mxFontCache = pSVData->maGDIData.mxScreenFontCache; mnFocusId = nullptr; diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 1383bad0888f..bf8973114185 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -241,17 +241,30 @@ IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void ) Tracking( aTEvt ); } +void Window::SetUseFrameData(bool bUseFrameData) +{ + if (mpWindowImpl) + mpWindowImpl->mbUseFrameData = bUseFrameData; +} + void Window::StartTracking( StartTrackingFlags nFlags ) { + if (!mpWindowImpl) + return; + ImplSVData* pSVData = ImplGetSVData(); + VclPtr<vcl::Window> pTrackWin = mpWindowImpl->mbUseFrameData ? + mpWindowImpl->mpFrameData->mpTrackWin : + pSVData->mpWinData->mpTrackWin; - if ( pSVData->mpWinData->mpTrackWin.get() != this ) + if ( pTrackWin.get() != this ) { - if ( pSVData->mpWinData->mpTrackWin ) - pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel ); + if ( pTrackWin ) + pTrackWin->EndTracking( TrackingEventFlags::Cancel ); } - if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) ) + if ( !mpWindowImpl->mbUseFrameData && + (nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat)) ) { pSVData->mpWinData->mpTrackTimer = new AutoTimer("vcl::Window pSVData->mpWinData->mpTrackTimer"); @@ -263,55 +276,70 @@ void Window::StartTracking( StartTrackingFlags nFlags ) pSVData->mpWinData->mpTrackTimer->Start(); } - pSVData->mpWinData->mpTrackWin = this; - pSVData->mpWinData->mnTrackFlags = nFlags; - CaptureMouse(); + if (mpWindowImpl->mbUseFrameData) + { + mpWindowImpl->mpFrameData->mpTrackWin = this; + } + else + { + pSVData->mpWinData->mpTrackWin = this; + pSVData->mpWinData->mnTrackFlags = nFlags; + CaptureMouse(); + } } void Window::EndTracking( TrackingEventFlags nFlags ) { + if (!mpWindowImpl) + return; + ImplSVData* pSVData = ImplGetSVData(); + VclPtr<vcl::Window> pTrackWin = mpWindowImpl->mbUseFrameData ? + mpWindowImpl->mpFrameData->mpTrackWin : + pSVData->mpWinData->mpTrackWin; - if ( pSVData->mpWinData->mpTrackWin.get() != this ) + if ( pTrackWin.get() != this ) return; - if ( pSVData->mpWinData->mpTrackTimer ) + if ( !mpWindowImpl->mbUseFrameData && pSVData->mpWinData->mpTrackTimer ) { delete pSVData->mpWinData->mpTrackTimer; pSVData->mpWinData->mpTrackTimer = nullptr; } - pSVData->mpWinData->mpTrackWin = nullptr; + mpWindowImpl->mpFrameData->mpTrackWin = pSVData->mpWinData->mpTrackWin = nullptr; pSVData->mpWinData->mnTrackFlags = StartTrackingFlags::NONE; ReleaseMouse(); // call EndTracking if required - if (!mpWindowImpl || !mpWindowImpl->mpFrameData) - return; - - Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY ); - if( GetOutDev()->ImplIsAntiparallel() ) + if (mpWindowImpl->mpFrameData) { - // re-mirror frame pos at pChild - const OutputDevice *pOutDev = GetOutDev(); - pOutDev->ReMirror( aMousePos ); - } + Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY ); + if( GetOutDev()->ImplIsAntiparallel() ) + { + // re-mirror frame pos at pChild + const OutputDevice *pOutDev = GetOutDev(); + pOutDev->ReMirror( aMousePos ); + } - MouseEvent aMEvt( ImplFrameToOutput( aMousePos ), - mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE, - mpWindowImpl->mpFrameData->mnMouseCode, - mpWindowImpl->mpFrameData->mnMouseCode ); - TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End ); - // CompatTracking effectively - if (!mpWindowImpl || mpWindowImpl->mbInDispose) - return Window::Tracking( aTEvt ); - else - return Tracking( aTEvt ); + MouseEvent aMEvt( ImplFrameToOutput( aMousePos ), + mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE, + mpWindowImpl->mpFrameData->mnMouseCode, + mpWindowImpl->mpFrameData->mnMouseCode ); + TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End ); + // CompatTracking effectively + if (!mpWindowImpl || mpWindowImpl->mbInDispose) + return Window::Tracking( aTEvt ); + else + return Tracking( aTEvt ); + } } bool Window::IsTracking() const { - return mpWindowImpl && (ImplGetSVData()->mpWinData->mpTrackWin == this); + return (mpWindowImpl->mbUseFrameData ? + mpWindowImpl->mpFrameData->mpTrackWin == this : + ImplGetSVData()->mpWinData->mpTrackWin == this); } void Window::StartAutoScroll( StartAutoScrollFlags nFlags ) diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index b79bc0744729..ab40c51347b2 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -895,9 +895,16 @@ bool ImplLOKHandleMouseEvent(const VclPtr<vcl::Window>& xWindow, MouseNotifyEven MouseEvent aMouseEvent(aWinPos, nClicks, nMode, nCode, nCode); if (nEvent == MouseNotifyEvent::MOUSEMOVE) { - xWindow->MouseMove(aMouseEvent); + if (pFrameData->mpTrackWin) + { + TrackingEvent aTrackingEvent(aMouseEvent); + pFrameData->mpTrackWin->Tracking(aTrackingEvent); + } + else + xWindow->MouseMove(aMouseEvent); } - else if (nEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) + else if (nEvent == MouseNotifyEvent::MOUSEBUTTONDOWN && + !pFrameData->mpTrackWin) { pFrameData->mpMouseDownWin = xWindow; pFrameData->mnFirstMouseX = aMousePos.X(); @@ -907,6 +914,11 @@ bool ImplLOKHandleMouseEvent(const VclPtr<vcl::Window>& xWindow, MouseNotifyEven } else { + if (pFrameData->mpTrackWin) + { + pFrameData->mpTrackWin->EndTracking(); + } + pFrameData->mpMouseDownWin = nullptr; pFrameData->mpMouseMoveWin = nullptr; pFrameData->mbStartDragCalled = false;