vcl/inc/window.h              |    5 +
 vcl/source/window/winproc.cxx |  122 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

New commits:
commit 845e53ea13b317bd8ef4dc42cd60ea51359f34ab
Author:     Henry Castro <hcas...@collabora.com>
AuthorDate: Wed Jun 23 07:44:26 2021 -0400
Commit:     Henry Castro <hcas...@collabora.com>
CommitDate: Tue Feb 8 00:14:35 2022 +0100

    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>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117708
    Tested-by: Jenkins
    Reviewed-by: Henry Castro <hcas...@collabora.com>

diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index bc4b1ee1fe49..050c0558eb7c 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -419,6 +419,11 @@ typedef std::unique_ptr<PaintBufferGuard, 
o3tl::default_delete<PaintBufferGuard>
 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 059e89980fbf..35a5ce2754d2 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -804,6 +804,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();

Reply via email to