tdf#127921 Revert mouse/key listeners to original state
The changes caused several issues in the presenter console (mouse events delivered to wrong widgets). Also it turned up that parent windows got the notification about mouse events from their children, but the position was always relative to the top widget, so very unhelpful for the parent widgets. Also I found out that there are XKeyHandler and XMouseClickHandler interfaces which already do what I tried to do with the below commits (events get passed down to parent widgets, and they even can be marked as consumed). So the original issue reported can be fixed by using XKeyHandler/XMouseClickHandler instead. This reverts the following two commits: * "Related tdf#122920 Treat UNO key events the same as mouse events"9e0e97b716
* "tdf#122920 Send UNO mouse events to parent window listeners as well"6f43902b12
Change-Id: I005d22770a7a4db9588c5bc22197dc0ae526627e Reviewed-on: https://gerrit.libreoffice.org/82423 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
This commit is contained in:
@@ -17,13 +17,13 @@ from com.sun.star.awt import XKeyListener
|
|||||||
|
|
||||||
|
|
||||||
mouseListenerCount = 0
|
mouseListenerCount = 0
|
||||||
keyListenerCount = 0
|
mouseEventsIntercepted = 0
|
||||||
mousePressedEventsIntercepted = 0
|
mousePressedEventsIntercepted = 0
|
||||||
mouseReleasedEventsIntercepted = 0
|
mouseReleasedEventsIntercepted = 0
|
||||||
mouseEnteredEventsIntercepted = 0
|
mouseEnteredEventsIntercepted = 0
|
||||||
mouseExitedEventsIntercepted = 0
|
mouseExitedEventsIntercepted = 0
|
||||||
keyPressedEventsIntercepted = 0
|
keymousePressedEventsIntercepted = 0
|
||||||
keyReleasedEventsIntercepted = 0
|
keymouseReleasedEventsIntercepted = 0
|
||||||
|
|
||||||
|
|
||||||
class XMouseListenerExtended(unohelper.Base, XMouseListener):
|
class XMouseListenerExtended(unohelper.Base, XMouseListener):
|
||||||
@@ -47,39 +47,37 @@ class XMouseListenerExtended(unohelper.Base, XMouseListener):
|
|||||||
# is invoked when the mouse enters a window.
|
# is invoked when the mouse enters a window.
|
||||||
@classmethod
|
@classmethod
|
||||||
def mouseEntered(self, xMouseEvent):
|
def mouseEntered(self, xMouseEvent):
|
||||||
global mouseEnteredEventsIntercepted
|
global mouseEventsIntercepted
|
||||||
mouseEnteredEventsIntercepted += 1
|
mouseEventsIntercepted += 1
|
||||||
|
return super(XMouseListenerExtended, self).mouseEntered(xMouseEvent)
|
||||||
|
|
||||||
# is invoked when the mouse exits a window.
|
# is invoked when the mouse exits a window.
|
||||||
@classmethod
|
@classmethod
|
||||||
def mouseExited(self, xMouseEvent):
|
def mouseExited(self, xMouseEvent):
|
||||||
global mouseExitedEventsIntercepted
|
global mouseEventsIntercepted
|
||||||
mouseExitedEventsIntercepted += 1
|
mouseEventsIntercepted += 1
|
||||||
|
return super(XMouseListenerExtended, self).mouseExited(xMouseEvent)
|
||||||
|
|
||||||
|
|
||||||
class XKeyListenerExtended(unohelper.Base, XKeyListener):
|
class XKeyListenerExtended(unohelper.Base, XKeyListener):
|
||||||
def __init__(self):
|
|
||||||
global keyListenerCount
|
|
||||||
keyListenerCount += 1
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
# is invoked when a key has been pressed
|
# is invoked when a key has been pressed
|
||||||
@classmethod
|
@classmethod
|
||||||
def keyPressed(self, xKeyEvent):
|
def keyPressed(self, xKeyEvent):
|
||||||
global keyPressedEventsIntercepted
|
global keymousePressedEventsIntercepted
|
||||||
keyPressedEventsIntercepted += 1
|
keymousePressedEventsIntercepted += 1
|
||||||
|
return super(XKeyListenerExtended, self).keyPressed(xKeyEvent)
|
||||||
|
|
||||||
# is invoked when a key has been released
|
# is invoked when a key has been released
|
||||||
@classmethod
|
@classmethod
|
||||||
def keyReleased(self, xKeyEvent):
|
def keyReleased(self, xKeyEvent):
|
||||||
global keyReleasedEventsIntercepted
|
global keymouseReleasedEventsIntercepted
|
||||||
keyReleasedEventsIntercepted += 1
|
keymouseReleasedEventsIntercepted += 1
|
||||||
|
return super(XKeyListenerExtended, self).keyReleased(xKeyEvent)
|
||||||
|
|
||||||
# Test that registered mouse/key listeners for top window receive mouse/key events
|
# Test that registered mouse/key listeners for top window receive mouse/key events
|
||||||
class XWindow(UITestCase):
|
class XWindow(UITestCase):
|
||||||
def test_listeners(self):
|
def test_listeners(self):
|
||||||
global mouseListenerCount
|
global mouseListenerCount
|
||||||
global keyListenerCount
|
|
||||||
|
|
||||||
self.ui_test.create_doc_in_start_center("writer")
|
self.ui_test.create_doc_in_start_center("writer")
|
||||||
xDoc = self.ui_test.get_component()
|
xDoc = self.ui_test.get_component()
|
||||||
@@ -100,7 +98,6 @@ class XWindow(UITestCase):
|
|||||||
xKeyListener = XKeyListenerExtended()
|
xKeyListener = XKeyListenerExtended()
|
||||||
self.assertIsNotNone(xKeyListener)
|
self.assertIsNotNone(xKeyListener)
|
||||||
xWindow.addKeyListener(xKeyListener)
|
xWindow.addKeyListener(xKeyListener)
|
||||||
self.assertEqual(1, keyListenerCount)
|
|
||||||
|
|
||||||
# create dummy mouse event
|
# create dummy mouse event
|
||||||
xMouseEvent = MouseEvent()
|
xMouseEvent = MouseEvent()
|
||||||
@@ -121,6 +118,7 @@ class XWindow(UITestCase):
|
|||||||
xMouseEvent2.PopupTrigger = False
|
xMouseEvent2.PopupTrigger = False
|
||||||
xMouseEvent2.Source = xWindow
|
xMouseEvent2.Source = xWindow
|
||||||
|
|
||||||
|
# send mouse event
|
||||||
xToolkitRobot = xWindow.getToolkit()
|
xToolkitRobot = xWindow.getToolkit()
|
||||||
self.assertIsNotNone(xToolkitRobot)
|
self.assertIsNotNone(xToolkitRobot)
|
||||||
|
|
||||||
@@ -156,26 +154,23 @@ class XWindow(UITestCase):
|
|||||||
xWindow.removeKeyListener(xKeyListener)
|
xWindow.removeKeyListener(xKeyListener)
|
||||||
del xKeyListener
|
del xKeyListener
|
||||||
|
|
||||||
global keyPressedEventsIntercepted
|
global keymousePressedEventsIntercepted
|
||||||
# Not expected any interceptions
|
# Not expected any interceptions
|
||||||
self.assertEqual(1, keyPressedEventsIntercepted)
|
self.assertEqual(0, keymousePressedEventsIntercepted)
|
||||||
|
|
||||||
global keyReleasedEventsIntercepted
|
global keymouseReleasedEventsIntercepted
|
||||||
# Not expected any interceptions
|
# Not expected any interceptions
|
||||||
self.assertEqual(1, keyReleasedEventsIntercepted)
|
self.assertEqual(0, keymouseReleasedEventsIntercepted)
|
||||||
|
|
||||||
global mousePressedEventsIntercepted
|
global mousePressedEventsIntercepted
|
||||||
self.assertEqual(2, mousePressedEventsIntercepted)
|
self.assertEqual(0, mousePressedEventsIntercepted)
|
||||||
|
|
||||||
global mouseReleasedEventsIntercepted
|
global mouseReleasedEventsIntercepted
|
||||||
self.assertEqual(2, mouseReleasedEventsIntercepted)
|
self.assertEqual(0, mouseReleasedEventsIntercepted)
|
||||||
|
|
||||||
# Upon xMouseEvent, enter the vcl::Window with GetText() being "Standard", then upon
|
global mouseEventsIntercepted
|
||||||
# xMouseEvent2, exit that vcl::Window and enter the one with get_id() being "writer_edit":
|
# Not expected 3 interceptions
|
||||||
global mouseEnteredEventsIntercepted
|
self.assertEqual(0, mouseEventsIntercepted)
|
||||||
self.assertEqual(2, mouseEnteredEventsIntercepted)
|
|
||||||
global mouseExitedEventsIntercepted
|
|
||||||
self.assertEqual(1, mouseExitedEventsIntercepted)
|
|
||||||
|
|
||||||
# close document
|
# close document
|
||||||
self.ui_test.close_doc()
|
self.ui_test.close_doc()
|
||||||
|
@@ -644,27 +644,24 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VclEventId::WindowKeyInput:
|
case VclEventId::WindowKeyInput:
|
||||||
|
{
|
||||||
|
if ( mpImpl->getKeyListeners().getLength() )
|
||||||
|
{
|
||||||
|
css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
|
||||||
|
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
|
||||||
|
) );
|
||||||
|
mpImpl->getKeyListeners().keyPressed( aEvent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case VclEventId::WindowKeyUp:
|
case VclEventId::WindowKeyUp:
|
||||||
{
|
{
|
||||||
VclPtr<vcl::Window> pWin = GetWindow();
|
if ( mpImpl->getKeyListeners().getLength() )
|
||||||
while (pWin)
|
|
||||||
{
|
{
|
||||||
VCLXWindow* pXWindow = pWin->GetWindowPeer();
|
css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
|
||||||
if (!pXWindow || pXWindow->mpImpl->getKeyListeners().getLength() == 0)
|
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
|
||||||
{
|
) );
|
||||||
pWin = pWin->GetWindow(GetWindowType::RealParent);
|
mpImpl->getKeyListeners().keyReleased( aEvent );
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
awt::KeyEvent aEvent(VCLUnoHelper::createKeyEvent(
|
|
||||||
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this));
|
|
||||||
if (rVclWindowEvent.GetId() == VclEventId::WindowKeyInput)
|
|
||||||
pXWindow->mpImpl->getKeyListeners().keyPressed(aEvent);
|
|
||||||
else
|
|
||||||
pXWindow->mpImpl->getKeyListeners().keyReleased(aEvent);
|
|
||||||
|
|
||||||
// Next window (parent)
|
|
||||||
pWin = pWin->GetWindow(GetWindowType::RealParent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -697,66 +694,50 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
|
|||||||
case VclEventId::WindowMouseMove:
|
case VclEventId::WindowMouseMove:
|
||||||
{
|
{
|
||||||
MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
|
MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
|
||||||
VclPtr<vcl::Window> pWin = GetWindow();
|
if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
|
||||||
while (pWin)
|
|
||||||
{
|
{
|
||||||
VCLXWindow* pXWindow = pWin->GetWindowPeer();
|
awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
|
||||||
if (!pXWindow || pXWindow->mpImpl->getMouseListeners().getLength() == 0)
|
bool const isEnter(pMouseEvt->IsEnterWindow());
|
||||||
{
|
Callback aCallback = [ this, isEnter, aEvent ]()
|
||||||
pWin = pWin->GetWindow(GetWindowType::RealParent);
|
{ MouseListenerMultiplexer& rMouseListeners = this->mpImpl->getMouseListeners();
|
||||||
continue;
|
isEnter
|
||||||
}
|
? rMouseListeners.mouseEntered(aEvent)
|
||||||
awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(*pMouseEvt, *pXWindow));
|
: rMouseListeners.mouseExited(aEvent); };
|
||||||
|
|
||||||
if (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow())
|
ImplExecuteAsyncWithoutSolarLock( aCallback );
|
||||||
{
|
}
|
||||||
bool const isEnter(pMouseEvt->IsEnterWindow());
|
|
||||||
Callback aCallback = [pXWindow, isEnter, aEvent]() {
|
if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
|
||||||
isEnter ? pXWindow->mpImpl->getMouseListeners().mouseEntered(aEvent)
|
{
|
||||||
: pXWindow->mpImpl->getMouseListeners().mouseExited(aEvent);
|
awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
|
||||||
};
|
aEvent.ClickCount = 0;
|
||||||
ImplExecuteAsyncWithoutSolarLock(aCallback);
|
if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE )
|
||||||
}
|
mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
|
||||||
else
|
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;
|
break;
|
||||||
case VclEventId::WindowMouseButtonDown:
|
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:
|
case VclEventId::WindowMouseButtonUp:
|
||||||
{
|
{
|
||||||
VclPtr<vcl::Window> pWin = GetWindow();
|
if ( mpImpl->getMouseListeners().getLength() )
|
||||||
while (pWin)
|
|
||||||
{
|
{
|
||||||
VCLXWindow* pXWindow = pWin->GetWindowPeer();
|
awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
|
||||||
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)
|
Callback aCallback = [ this, aEvent ]()
|
||||||
pWin = pWin->GetWindow(GetWindowType::RealParent);
|
{ this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
|
||||||
|
ImplExecuteAsyncWithoutSolarLock( aCallback );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user