aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2018-03-06 13:52:33 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2018-03-16 06:54:17 +0000
commit936570a3b3440ed2508bacb9b9916381cb864ffb (patch)
tree01bbf6b52f869b1955740df4a13089388ea4fa04 /src/quick/items
parent08197a25c081f734b93065f6c7c7ce570b155758 (diff)
QQuickWindow: skip mouse synthesis for touch events from trackpads
A trackpad is primarily a mouse-emulating device, which can also recognize gestures, and furthermore can send raw touches iff it is asked to. So, every touch event from a trackpad is likely to be followed by a mouse or gesture event (especially when the MouseEmulation capability confirms that it is able to do that). Therefore mouse event synthesis is redundant. In this bug scenario, MultiPointTouchArea enables touch events within its rectangular bounds. A Flickable is on top. As you flick with two fingers on the trackpad, macOS sends touch events with two touch points (because MPTA enabled touch events) and also a series of QWheelEvents as it recognizes the flick gesture. The Flickable receives mouse events sythesized from one touch point, and reacts as if you were dragging with one finger on a touchscreen, while it simultaneously also reacts to the QWheelEvents. Meanwhile the remaining touchpoint falls through to the MPTA underneath; so the user ends up interacting with both at the same time and making the Flickable jump around besides. This patch just fixes the jumpiness in Flickable: it will no longer receive the synth-mouse events, so it will not be dragged, and will react only to the wheel events. But MPTA still gets the touches. Task-number: QTBUG-66329 Change-Id: I6f535a2c9e47bcb284eaf9ae1fdaa39f8b510af9 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickevents_p_p.h1
-rw-r--r--src/quick/items/qquickwindow.cpp12
2 files changed, 12 insertions, 1 deletions
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index c4f0b60d92..2a1e9dc184 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -597,6 +597,7 @@ public:
Area = QTouchDevice::Area,
Pressure = QTouchDevice::Pressure,
Velocity = QTouchDevice::Velocity,
+ MouseEmulation = QTouchDevice::MouseEmulation,
// some bits reserved in case we need more of QTouchDevice::Capabilities
Scroll = 0x0100, // mouse has a wheel, or there is OS-level scroll gesture recognition (dubious?)
Hover = 0x0200,
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index aefdaea2b7..48eba6a7a0 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -654,6 +654,12 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
Q_Q(QQuickWindow);
auto device = pointerEvent->device();
+ // A touch event from a trackpad is likely to be followed by a mouse or gesture event, so mouse event synth is redundant
+ if (device->type() == QQuickPointerDevice::TouchPad && device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) {
+ qCDebug(DBG_TOUCH_TARGET) << "skipping delivery of synth-mouse event from" << device;
+ return false;
+ }
+
// FIXME: make this work for mouse events too and get rid of the asTouchEvent in here.
Q_ASSERT(pointerEvent->asPointerTouchEvent());
QScopedPointer<QTouchEvent> event(pointerEvent->asPointerTouchEvent()->touchEventForItem(item));
@@ -2831,7 +2837,11 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
// In versions prior to Qt 6, we can't trust item->acceptTouchEvents() here, because it defaults to true.
bool acceptsTouchEvents = false;
#endif
- if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
+ auto device = pte->device();
+ if (device->type() == QQuickPointerDevice::TouchPad &&
+ device->capabilities().testFlag(QQuickPointerDevice::MouseEmulation)) {
+ qCDebug(DBG_TOUCH_TARGET) << "skipping filtering of synth-mouse event from" << device;
+ } else if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
// get a touch event customized for delivery to filteringParent
QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true));
if (filteringParentTouchEvent) {