diff options
author | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-08-30 11:03:39 +0200 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-10-10 22:09:07 +0000 |
commit | a37785ec7638e7485112b87dd7e767881fecc114 (patch) | |
tree | c238af4d154c12e80532daff5245627b181f5d40 /src/gui/kernel/qwindowsysteminterface.cpp | |
parent | 0900cf3581be3ff2b2e924ce0d845566c5df841e (diff) |
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 <paul.tvete@qt.io>
Diffstat (limited to 'src/gui/kernel/qwindowsysteminterface.cpp')
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 53653f94d8..a065e254df 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -341,36 +341,79 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *window, bool *accepted) \a w == 0 means that the event is in global coords only, \a local will be ignored in this case */ +#if QT_DEPRECATED_SINCE(5, 11) QT_DEFINE_QPA_EVENT_HANDLER(void, handleMouseEvent, QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { - unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleMouseEvent<Delivery>(window, time, local, global, b, mods, source); + handleMouseEvent<Delivery>(window, local, global, b, Qt::NoButton, QEvent::None, mods, source); } QT_DEFINE_QPA_EVENT_HANDLER(void, handleMouseEvent, QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { - QWindowSystemInterfacePrivate::MouseEvent * e = - new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), b, mods, source); - QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); + handleMouseEvent<Delivery>(window, timestamp, local, global, b, Qt::NoButton, QEvent::None, mods, source); } void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { - const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleFrameStrutMouseEvent(window, time, local, global, b, mods, source); + handleFrameStrutMouseEvent(window, local, global, b, Qt::NoButton, QEvent::None, mods, source); } void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { - QWindowSystemInterfacePrivate::MouseEvent * e = - new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, - QHighDpi::fromNativeLocalPosition(local, window), - QHighDpi::fromNativePixels(global, window), - b, mods, source, true); + handleFrameStrutMouseEvent(window, timestamp, local, global, b, Qt::NoButton, QEvent::None, mods, source); +} +#endif // QT_DEPRECATED_SINCE(5, 11) + +QT_DEFINE_QPA_EVENT_HANDLER(void, handleMouseEvent, QWindow *window, + const QPointF &local, const QPointF &global, Qt::MouseButtons state, + Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods, + Qt::MouseEventSource source) +{ + unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleMouseEvent<Delivery>(window, time, local, global, state, button, type, mods, source); +} + +QT_DEFINE_QPA_EVENT_HANDLER(void, handleMouseEvent, QWindow *window, ulong timestamp, + const QPointF &local, const QPointF &global, Qt::MouseButtons state, + Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods, + Qt::MouseEventSource source) +{ + auto localPos = QHighDpi::fromNativeLocalPosition(local, window); + auto globalPos = QHighDpi::fromNativePixels(global, window); + + QWindowSystemInterfacePrivate::MouseEvent *e = + new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos, + state, mods, button, type, source); + QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); +} + +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, + const QPointF &local, const QPointF &global, + Qt::MouseButtons state, + Qt::MouseButton button, QEvent::Type type, + Qt::KeyboardModifiers mods, + Qt::MouseEventSource source) +{ + const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleFrameStrutMouseEvent(window, time, local, global, state, button, type, mods, source); +} + +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, + const QPointF &local, const QPointF &global, + Qt::MouseButtons state, + Qt::MouseButton button, QEvent::Type type, + Qt::KeyboardModifiers mods, + Qt::MouseEventSource source) +{ + auto localPos = QHighDpi::fromNativeLocalPosition(local, window); + auto globalPos = QHighDpi::fromNativePixels(global, window); + + QWindowSystemInterfacePrivate::MouseEvent *e = + new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos, + state, mods, button, type, source, true); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -1008,11 +1051,26 @@ bool QWindowSystemInterface::nonUserInputEventsQueued() // The following functions are used by testlib, and need to be synchronous to avoid // race conditions with plugins delivering native events from secondary threads. +// FIXME: It seems unnecessary to export these wrapper functions, when qtestlib could access +// QWindowSystemInterface directly (by adding dependency to gui-private), see QTBUG-63146. + +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) +{ + const qreal factor = QHighDpiScaling::factor(window); + QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(window, + timestamp, local * factor, global * factor, state, button, type, mods); +} -Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp) +// Wrapper for compatibility with Qt < 5.11 +// ### Qt6: Remove +Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, + Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp) { const qreal factor = QHighDpiScaling::factor(window); - QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(window, timestamp, local * factor, global * factor, b, mods); + QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(window, + timestamp, local * factor, global * factor, b, Qt::NoButton, QEvent::None, mods); } // Wrapper for compatibility with Qt < 5.6 |