From 8bdf33051aa679db1f060314c6ccab1cb9a77a7a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 27 Nov 2017 16:30:15 +0100 Subject: don't get confused about the grabber during replayDelayedPress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a ListView with pressDelay contains a MouseArea in a delegate, and you tap the MouseArea on a touchscreen, QQuickFlickablePrivate::replayDelayedPress() sends a saved copy of the original QMouseEvent, and then a synthetic release, without marking it as synthetic. (QQuickFlickable is not touch-aware in any way: it thinks the mouse events it receives are real ones.) As a result of sending the delayed press through, QQuickWindowPrivate::setMouseGrabber() is called and sets the touchpoint's grabber to the MouseArea, but does not set the core pointer's eventpoint's grabber. Flickable then ungrabs for itself, so we have to ensure that the ungrab affects either the actual mouse or the synth-mouse, whichever was in use. Then because the synthetic release is not known to come from a touchscreen, QQuickWindowPrivate::deliverMouseEvent() was checking the core pointer's grabber and concluding that there is no grabber. In such a case, it now checks whether touchMouseId is set, meaning that we are somewhere between sending a synthesized press and release, gets the touchpoint's grabber (which is MouseArea, because it didn't reject the press), and sends the release there. Task-number: QTBUG-61144 Change-Id: I494873e48af179bc63b618e881ba469b97dadf4d Reviewed-by: Jan Arve Sæther --- src/quick/items/qquickitem.cpp | 2 +- src/quick/items/qquickwindow.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 3571feb2cc..53f855e56d 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7330,7 +7330,7 @@ void QQuickItem::ungrabMouse() if (!d->window) return; QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window); - windowPriv->removeGrabber(this, true, false); + windowPriv->removeGrabber(this, true, (windowPriv->touchMouseId != -1 && windowPriv->touchMouseDevice)); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 70c8590ae7..fa251b7d78 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1656,6 +1656,9 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven auto point = pointerEvent->point(0); lastMousePosition = point->scenePos(); QQuickItem *grabber = point->grabber(); + if (!grabber && touchMouseId != -1 && touchMouseDevice) + grabber = q->mouseGrabberItem(); + if (grabber) { // if the update consists of changing button state, then don't accept it // unless the button is one in which the item is interested -- cgit v1.2.3