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;

Reply via email to