sw/qa/uitest/writer_tests/xwindow.py |  150 +++++++++++++++++++++++++++++++++++
 toolkit/source/awt/vclxwindow.cxx    |   84 +++++++++++--------
 2 files changed, 200 insertions(+), 34 deletions(-)

New commits:
commit a2fcf51a77f4a37fb1c14f47bab450eea79a0dcb
Author:     Samuel Mehrbrodt <samuel.mehrbr...@cib.de>
AuthorDate: Wed Apr 10 11:21:32 2019 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Tue Apr 23 17:48:40 2019 +0200

    tdf#122920 Send UNO mouse events to parent window listeners as well
    
    When user registers a mouse listener to a window, he expects
    to receive mouse events when a user clicks in somewhere in that
    window, even if it's technically a widget inside that window
    
    Change-Id: Ie6d3f8b140e4a5b516051014282b43775ecec59e
    Reviewed-on: https://gerrit.libreoffice.org/70512
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de>
    Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de>
    (cherry picked from commit 6f43902b12dd36fa2b69401065df198ef9ffdb09)
    Reviewed-on: https://gerrit.libreoffice.org/71139
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    Tested-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git a/sw/qa/uitest/writer_tests/xwindow.py 
b/sw/qa/uitest/writer_tests/xwindow.py
index d63df73c69ea..428dd3723a05 100644
--- a/sw/qa/uitest/writer_tests/xwindow.py
+++ b/sw/qa/uitest/writer_tests/xwindow.py
@@ -43,15 +43,13 @@ class XMouseListenerExtended(unohelper.Base, 
XMouseListener):
     # is invoked when the mouse enters a window.
     @classmethod
     def mouseEntered(self, xMouseEvent):
-        global mouseEventsIntercepted
-        mouseEventsIntercepted += 1
+        # doesn't work in UI tests
         return super(XMouseListenerExtended, self).mouseEntered(xMouseEvent)
 
     # is invoked when the mouse exits a window.
     @classmethod
     def mouseExited(self, xMouseEvent):
-        global mouseEventsIntercepted
-        mouseEventsIntercepted += 1
+        # doesn't work in UI tests
         return super(XMouseListenerExtended, self).mouseExited(xMouseEvent)
 
 
@@ -142,8 +140,8 @@ class XWindow(UITestCase):
         self.assertEqual(0, keymouseEventsIntercepted)
 
         global mouseEventsIntercepted
-        # Not expected 3 interceptions
-        self.assertEqual(0, mouseEventsIntercepted)
+        # mousePressed, mouseReleased and mouseEntered should be triggered
+        self.assertEqual(2, mouseEventsIntercepted)
 
         # close document
         self.ui_test.close_doc()
diff --git a/toolkit/source/awt/vclxwindow.cxx 
b/toolkit/source/awt/vclxwindow.cxx
index 6d89c13f3697..31438dfec9e2 100644
--- a/toolkit/source/awt/vclxwindow.cxx
+++ b/toolkit/source/awt/vclxwindow.cxx
@@ -704,50 +704,66 @@ void VCLXWindow::ProcessWindowEvent( const 
VclWindowEvent& rVclWindowEvent )
         case VclEventId::WindowMouseMove:
         {
             MouseEvent* pMouseEvt = 
static_cast<MouseEvent*>(rVclWindowEvent.GetData());
-            if ( mpImpl->getMouseListeners().getLength() && ( 
pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
+            VclPtr<vcl::Window> pWin = GetWindow();
+            while (pWin)
             {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
*pMouseEvt, *this ) );
-                bool const isEnter(pMouseEvt->IsEnterWindow());
-                Callback aCallback = [ this, isEnter, aEvent ]()
-                     { MouseListenerMultiplexer& rMouseListeners = 
this->mpImpl->getMouseListeners();
-                       isEnter
-                           ? rMouseListeners.mouseEntered(aEvent)
-                           : rMouseListeners.mouseExited(aEvent); };
-
-                ImplExecuteAsyncWithoutSolarLock( aCallback );
-            }
+                VCLXWindow* pXWindow = pWin->GetWindowPeer();
+                if (!pXWindow || 
pXWindow->mpImpl->getMouseListeners().getLength() == 0)
+                {
+                    pWin = pWin->GetWindow(GetWindowType::RealParent);
+                    continue;
+                }
+                awt::MouseEvent 
aEvent(VCLUnoHelper::createMouseEvent(*pMouseEvt, *pXWindow));
 
-            if ( mpImpl->getMouseMotionListeners().getLength() && 
!pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
-            {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
*pMouseEvt, *this ) );
-                aEvent.ClickCount = 0;
-                if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE )
-                    mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
+                if (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow())
+                {
+                    bool const isEnter(pMouseEvt->IsEnterWindow());
+                    Callback aCallback = [pXWindow, isEnter, aEvent]() {
+                        isEnter ? 
pXWindow->mpImpl->getMouseListeners().mouseEntered(aEvent)
+                                : 
pXWindow->mpImpl->getMouseListeners().mouseExited(aEvent);
+                    };
+                    ImplExecuteAsyncWithoutSolarLock(aCallback);
+                }
                 else
-                    mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
+                {
+                    aEvent.ClickCount = 0;
+                    MouseMotionListenerMultiplexer& rMouseListeners
+                        = pXWindow->mpImpl->getMouseMotionListeners();
+                    if (pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE)
+                        rMouseListeners.mouseMoved(aEvent);
+                    else
+                        rMouseListeners.mouseDragged(aEvent);
+                }
+
+                // Next window (parent)
+                pWin = pWin->GetWindow(GetWindowType::RealParent);
             }
         }
         break;
         case VclEventId::WindowMouseButtonDown:
-        {
-            if ( mpImpl->getMouseListeners().getLength() )
-            {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
*static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
-                Callback aCallback = [ this, aEvent ]()
-                                     { 
this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
-                ImplExecuteAsyncWithoutSolarLock( aCallback );
-            }
-        }
-        break;
         case VclEventId::WindowMouseButtonUp:
         {
-            if ( mpImpl->getMouseListeners().getLength() )
+            VclPtr<vcl::Window> pWin = GetWindow();
+            while (pWin)
             {
-                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( 
*static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
-
-                Callback aCallback = [ this, aEvent ]()
-                                     { 
this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
-                ImplExecuteAsyncWithoutSolarLock( aCallback );
+                VCLXWindow* pXWindow = pWin->GetWindowPeer();
+                if (!pXWindow || 
pXWindow->mpImpl->getMouseListeners().getLength() == 0)
+                {
+                    pWin = pWin->GetWindow(GetWindowType::RealParent);
+                    continue;
+                }
+                MouseEvent* pMouseEvt = 
static_cast<MouseEvent*>(rVclWindowEvent.GetData());
+                awt::MouseEvent 
aEvent(VCLUnoHelper::createMouseEvent(*pMouseEvt, *pXWindow));
+                VclEventId eventId = rVclWindowEvent.GetId();
+                Callback aCallback = [pXWindow, aEvent, eventId]() {
+                    eventId == VclEventId::WindowMouseButtonDown
+                        ? 
pXWindow->mpImpl->getMouseListeners().mousePressed(aEvent)
+                        : 
pXWindow->mpImpl->getMouseListeners().mouseReleased(aEvent);
+                };
+                ImplExecuteAsyncWithoutSolarLock(aCallback);
+
+                // Next window (parent)
+                pWin = pWin->GetWindow(GetWindowType::RealParent);
             }
         }
         break;
commit dcf4f3804d394df5c6184e6d2487c5517ba9e7cc
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Thu Jan 24 10:25:16 2019 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Tue Apr 23 17:48:27 2019 +0200

    tdf#122920 uitest: XMouseListener is not called for top most window
    
    Reviewed-on: https://gerrit.libreoffice.org/66856
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    (cherry picked from commit 5723d303a44597cdb2ea242cf3fb0ac0e8c15b83)
    
    Change-Id: Ia6f79e50b93004b8bf896e24450ce8666b303037
    Reviewed-on: https://gerrit.libreoffice.org/71138
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    Tested-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git a/sw/qa/uitest/writer_tests/xwindow.py 
b/sw/qa/uitest/writer_tests/xwindow.py
new file mode 100644
index 000000000000..d63df73c69ea
--- /dev/null
+++ b/sw/qa/uitest/writer_tests/xwindow.py
@@ -0,0 +1,152 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+import unittest
+import unohelper
+from org.libreoffice.unotest import UnoInProcess
+from com.sun.star.awt import XMouseListener
+from com.sun.star.awt import XToolkitRobot
+from com.sun.star.awt import MouseEvent
+from com.sun.star.awt import KeyEvent
+from com.sun.star.awt import XKeyListener
+
+
+mouseListenerCount = 0
+mouseEventsIntercepted = 0
+keymouseEventsIntercepted = 0
+
+
+class XMouseListenerExtended(unohelper.Base, XMouseListener):
+    def __init__(self):
+        global mouseListenerCount
+        mouseListenerCount += 1
+        super().__init__()
+
+    # is invoked when a mouse button has been pressed on a window.
+    @classmethod
+    def mousePressed(self, xMouseEvent):
+        global mouseEventsIntercepted
+        mouseEventsIntercepted += 1
+        return super(XMouseListenerExtended, self).mousePressed(xMouseEvent)
+
+    # is invoked when a mouse button has been released on a window.
+    @classmethod
+    def mouseReleased(self, xMouseEvent):
+        global mouseEventsIntercepted
+        mouseEventsIntercepted += 1
+        return super(XMouseListenerExtended, self).mouseReleased(xMouseEvent)
+
+    # is invoked when the mouse enters a window.
+    @classmethod
+    def mouseEntered(self, xMouseEvent):
+        global mouseEventsIntercepted
+        mouseEventsIntercepted += 1
+        return super(XMouseListenerExtended, self).mouseEntered(xMouseEvent)
+
+    # is invoked when the mouse exits a window.
+    @classmethod
+    def mouseExited(self, xMouseEvent):
+        global mouseEventsIntercepted
+        mouseEventsIntercepted += 1
+        return super(XMouseListenerExtended, self).mouseExited(xMouseEvent)
+
+
+class XKeyListenerExtended(unohelper.Base, XKeyListener):
+    # is invoked when a key has been pressed
+    @classmethod
+    def keyPressed(self, xKeyEvent):
+        global keymouseEventsIntercepted
+        keymouseEventsIntercepted += 1
+        return super(XKeyListenerExtended, self).keyPressed(xKeyEvent)
+
+    # is invoked when a key has been released
+    @classmethod
+    def keyReleased(self, xKeyEvent):
+        global keymouseEventsIntercepted
+        keymouseEventsIntercepted += 1
+        return super(XKeyListenerExtended, self).keyReleased(xKeyEvent)
+
+# registered mouse/key listeners for top window
+# do not receive any mouse/key events while
+# everything is passed only to focused child window
+# where we have no any registered mouse/key listeners
+class XWindow(UITestCase):
+    def test_listeners(self):
+        global mouseListenerCount
+
+        writer_doc = self.ui_test.create_doc_in_start_center("writer")
+        xDoc = self.ui_test.get_component()
+        xWriterDoc = self.xUITest.getTopFocusWindow()
+        xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+        # create new mouse listener
+        xFrame = xDoc.getCurrentController().getFrame()
+        self.assertIsNotNone(xFrame)
+        xWindow = xFrame.getContainerWindow()
+        self.assertIsNotNone(xWindow)
+
+        # add new mouse listener
+        xMouseListener = XMouseListenerExtended()
+        self.assertIsNotNone(xMouseListener)
+        xWindow.addMouseListener(xMouseListener)
+        self.assertEqual(1, mouseListenerCount)
+
+        # add new key listener
+        xKeyListener = XKeyListenerExtended()
+        self.assertIsNotNone(xKeyListener)
+        xWindow.addKeyListener(xKeyListener)
+
+        # create dummy mouse event
+        xMouseEvent = MouseEvent()
+        xMouseEvent.Modifiers = 0
+        xMouseEvent.Buttons = 0
+        xMouseEvent.X = 10
+        xMouseEvent.Y = 10
+        xMouseEvent.ClickCount = 1
+        xMouseEvent.PopupTrigger = False
+        xMouseEvent.Source = xWindow
+
+        # send mouse event
+        xToolkitRobot = xWindow.getToolkit()
+        self.assertIsNotNone(xToolkitRobot)
+
+        xToolkitRobot.mousePress(xMouseEvent)
+        xToolkitRobot.mouseMove(xMouseEvent)
+        xToolkitRobot.mouseRelease(xMouseEvent)
+
+        # send key press event
+        xKeyEvent = KeyEvent()
+        xKeyEvent.Modifiers = 0
+        xKeyEvent.KeyCode = 70
+        xKeyEvent.KeyChar = 70
+        xKeyEvent.Source = xWindow
+
+        xToolkitRobot.keyPress(xKeyEvent)
+        xToolkitRobot.keyRelease(xKeyEvent)
+
+        # remove moue listener
+        xWindow.removeMouseListener(xMouseListener)
+        self.assertEqual(1, mouseListenerCount)
+        del xMouseListener
+
+        # remove key listener
+        xWindow.removeKeyListener(xKeyListener)
+        del xKeyListener
+
+        global keymouseEventsIntercepted
+        # Not expected 2 interceptions
+        self.assertEqual(0, keymouseEventsIntercepted)
+
+        global mouseEventsIntercepted
+        # Not expected 3 interceptions
+        self.assertEqual(0, mouseEventsIntercepted)
+
+        # close document
+        self.ui_test.close_doc()
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to