From 936570a3b3440ed2508bacb9b9916381cb864ffb Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 6 Mar 2018 13:52:33 +0100 Subject: QQuickWindow: skip mouse synthesis for touch events from trackpads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/quick/items/qquickevents_p_p.h | 1 + src/quick/items/qquickwindow.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src') 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 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 filteringParentTouchEvent(pte->touchEventForItem(receiver, true)); if (filteringParentTouchEvent) { -- cgit v1.2.3