From a37785ec7638e7485112b87dd7e767881fecc114 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 30 Aug 2017 11:03:39 +0200 Subject: qpa: enhance mouse event with type and button data ... and deprecate QWSI APIs that accepts mouse event without mouse button/ type data. In the early days of Qt5 it was decided to centralize mouse button/type handling in QGuiApplication (because of limitation of some now unknown platform). This has proven to be problematic as mouse handling details differ across platforms (e.g on X11 we do not receive mouse release event when closing popup windows or ordinary windows that are closed from the mouse press event). Instead of hacking around platform specific behaviors in Qt Gui, we should move this task back to platform plugins (similar to how this was done in Qt4 with native APIs sending mouse details directly to QApplication). There are even cases where it simply is not possible to deduce (from QGuiApplication) which button caused the event (e.g. when more than one button is involved and some event goes missing). Besisdes, throwing away information which is already available at QPA level (for free) and trying to deduce it again at Qt Gui level seems impractical, fagile (as probably noticed by people fixing all the unexpected issues) and adds unnecessary complexity. Note: Removing the deprecated QWSI APIs from offscreen plugin depends on fixing autotests that rely on QOffscreenCursor::setPos() logic. For the convenience of testing use QT_QPA_DISABLE_ENHANCED_MOUSE to restore to the old code path where QGuiApplication does the mouse state deducing. Other platforms have similar issues. I do not have all supported platform available on my desk, so other platform maintainers will need to take care of porting those platforms to the new APIs. And mainly, I don't want to deal with all the hacks that other platforms have added to workaround this broken mouse logic. In Qt6 we need to remove deprecated code path from QGuiApplication. This patch: - Extends QWindowSystemInterfacePrivate::MouseEvent ctor with QEvent::Type and Qt::MouseButton. We use this extra data when processing mouse events in QGuiApplication. This actually is similar to KeyEvent, where we do pass the type (press or release) to QtGui. - Refactors QGuiApplicationPrivate::processMouseEvent and qtestlib to use the new APIs. Task-number: QTBUG-59277 Task-number: QTBUG-62329 Task-number: QTBUG-63467 Change-Id: If94fd46a7cccfea8264dcb1368804c73334558b8 Reviewed-by: Paul Olav Tvete --- src/testlib/qtestmouse.h | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/testlib') diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 8f55c1801f..55f8baa003 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -64,7 +64,9 @@ QT_BEGIN_NAMESPACE -Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp); +Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, + Qt::MouseButtons state, Qt::MouseButton button, + QEvent::Type type, Qt::KeyboardModifiers mods, int timestamp); namespace QTest { @@ -120,23 +122,28 @@ namespace QTest switch (action) { case MouseDClick: - qt_handleMouseEvent(w, pos, global, button, stateKey, ++lastMouseTimestamp); - qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, button, button, QEvent::MouseButtonPress, + stateKey, ++lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, Qt::NoButton, button, QEvent::MouseButtonRelease, + stateKey, ++lastMouseTimestamp); Q_FALLTHROUGH(); case MousePress: case MouseClick: - qt_handleMouseEvent(w, pos, global, button, stateKey, ++lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, button, button, QEvent::MouseButtonPress, + stateKey, ++lastMouseTimestamp); lastMouseButton = button; if (action == MousePress) break; Q_FALLTHROUGH(); case MouseRelease: - qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, Qt::NoButton, button, QEvent::MouseButtonRelease, + stateKey, ++lastMouseTimestamp); lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated lastMouseButton = Qt::NoButton; break; case MouseMove: - qt_handleMouseEvent(w, pos, global, lastMouseButton, stateKey, ++lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, lastMouseButton, Qt::NoButton, QEvent::MouseMove, + stateKey, ++lastMouseTimestamp); // No QCursor::setPos() call here. That could potentially result in mouse events sent by the windowing system // which is highly undesired here. Tests must avoid relying on QCursor. break; -- cgit v1.2.3