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:
Samuel Mehrbrodt
2019-11-11 10:52:52 +01:00
parent 24f17f0336
commit aadc7ee973
2 changed files with 73 additions and 97 deletions

View File

@@ -17,13 +17,13 @@ from com.sun.star.awt import XKeyListener
mouseListenerCount = 0
keyListenerCount = 0
mouseEventsIntercepted = 0
mousePressedEventsIntercepted = 0
mouseReleasedEventsIntercepted = 0
mouseEnteredEventsIntercepted = 0
mouseExitedEventsIntercepted = 0
keyPressedEventsIntercepted = 0
keyReleasedEventsIntercepted = 0
keymousePressedEventsIntercepted = 0
keymouseReleasedEventsIntercepted = 0
class XMouseListenerExtended(unohelper.Base, XMouseListener):
@@ -47,39 +47,37 @@ class XMouseListenerExtended(unohelper.Base, XMouseListener):
# is invoked when the mouse enters a window.
@classmethod
def mouseEntered(self, xMouseEvent):
global mouseEnteredEventsIntercepted
mouseEnteredEventsIntercepted += 1
global mouseEventsIntercepted
mouseEventsIntercepted += 1
return super(XMouseListenerExtended, self).mouseEntered(xMouseEvent)
# is invoked when the mouse exits a window.
@classmethod
def mouseExited(self, xMouseEvent):
global mouseExitedEventsIntercepted
mouseExitedEventsIntercepted += 1
global mouseEventsIntercepted
mouseEventsIntercepted += 1
return super(XMouseListenerExtended, self).mouseExited(xMouseEvent)
class XKeyListenerExtended(unohelper.Base, XKeyListener):
def __init__(self):
global keyListenerCount
keyListenerCount += 1
super().__init__()
# is invoked when a key has been pressed
@classmethod
def keyPressed(self, xKeyEvent):
global keyPressedEventsIntercepted
keyPressedEventsIntercepted += 1
global keymousePressedEventsIntercepted
keymousePressedEventsIntercepted += 1
return super(XKeyListenerExtended, self).keyPressed(xKeyEvent)
# is invoked when a key has been released
@classmethod
def keyReleased(self, xKeyEvent):
global keyReleasedEventsIntercepted
keyReleasedEventsIntercepted += 1
global keymouseReleasedEventsIntercepted
keymouseReleasedEventsIntercepted += 1
return super(XKeyListenerExtended, self).keyReleased(xKeyEvent)
# Test that registered mouse/key listeners for top window receive mouse/key events
class XWindow(UITestCase):
def test_listeners(self):
global mouseListenerCount
global keyListenerCount
self.ui_test.create_doc_in_start_center("writer")
xDoc = self.ui_test.get_component()
@@ -100,7 +98,6 @@ class XWindow(UITestCase):
xKeyListener = XKeyListenerExtended()
self.assertIsNotNone(xKeyListener)
xWindow.addKeyListener(xKeyListener)
self.assertEqual(1, keyListenerCount)
# create dummy mouse event
xMouseEvent = MouseEvent()
@@ -121,6 +118,7 @@ class XWindow(UITestCase):
xMouseEvent2.PopupTrigger = False
xMouseEvent2.Source = xWindow
# send mouse event
xToolkitRobot = xWindow.getToolkit()
self.assertIsNotNone(xToolkitRobot)
@@ -156,26 +154,23 @@ class XWindow(UITestCase):
xWindow.removeKeyListener(xKeyListener)
del xKeyListener
global keyPressedEventsIntercepted
global keymousePressedEventsIntercepted
# Not expected any interceptions
self.assertEqual(1, keyPressedEventsIntercepted)
self.assertEqual(0, keymousePressedEventsIntercepted)
global keyReleasedEventsIntercepted
global keymouseReleasedEventsIntercepted
# Not expected any interceptions
self.assertEqual(1, keyReleasedEventsIntercepted)
self.assertEqual(0, keymouseReleasedEventsIntercepted)
global mousePressedEventsIntercepted
self.assertEqual(2, mousePressedEventsIntercepted)
self.assertEqual(0, mousePressedEventsIntercepted)
global mouseReleasedEventsIntercepted
self.assertEqual(2, mouseReleasedEventsIntercepted)
self.assertEqual(0, mouseReleasedEventsIntercepted)
# Upon xMouseEvent, enter the vcl::Window with GetText() being "Standard", then upon
# xMouseEvent2, exit that vcl::Window and enter the one with get_id() being "writer_edit":
global mouseEnteredEventsIntercepted
self.assertEqual(2, mouseEnteredEventsIntercepted)
global mouseExitedEventsIntercepted
self.assertEqual(1, mouseExitedEventsIntercepted)
global mouseEventsIntercepted
# Not expected 3 interceptions
self.assertEqual(0, mouseEventsIntercepted)
# close document
self.ui_test.close_doc()

View File

@@ -644,27 +644,24 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
}
break;
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:
{
VclPtr<vcl::Window> pWin = GetWindow();
while (pWin)
if ( mpImpl->getKeyListeners().getLength() )
{
VCLXWindow* pXWindow = pWin->GetWindowPeer();
if (!pXWindow || pXWindow->mpImpl->getKeyListeners().getLength() == 0)
{
pWin = pWin->GetWindow(GetWindowType::RealParent);
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);
css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
*static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
) );
mpImpl->getKeyListeners().keyReleased( aEvent );
}
}
break;
@@ -697,66 +694,50 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
case VclEventId::WindowMouseMove:
{
MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
VclPtr<vcl::Window> pWin = GetWindow();
while (pWin)
if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
{
VCLXWindow* pXWindow = pWin->GetWindowPeer();
if (!pXWindow || pXWindow->mpImpl->getMouseListeners().getLength() == 0)
{
pWin = pWin->GetWindow(GetWindowType::RealParent);
continue;
}
awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(*pMouseEvt, *pXWindow));
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); };
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);
}
ImplExecuteAsyncWithoutSolarLock( aCallback );
}
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 );
else
{
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);
mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
}
}
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:
{
VclPtr<vcl::Window> pWin = GetWindow();
while (pWin)
if ( mpImpl->getMouseListeners().getLength() )
{
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);
awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
// Next window (parent)
pWin = pWin->GetWindow(GetWindowType::RealParent);
Callback aCallback = [ this, aEvent ]()
{ this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
ImplExecuteAsyncWithoutSolarLock( aCallback );
}
}
break;