From 213a7054b563fc7374d328bc458739f8b8afa863 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 29 Aug 2017 10:34:23 +0200 Subject: failsafe: never allow touch or mouse grab to persist after release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a PointerHandler acquires a passive grab and we fail to remove it, then next time the mouse moves, a filtering parent Flickable will have a chance to see the mouse hover movement in the course of delivery to that handler, and will grab. Thus you are stuck in flicking state even though no mouse button is held. Passive grabs must therefore always be cleared on release. Change-Id: Ibaf46de32d7855e7b5f377c2d4fdae1312601c4f Reviewed-by: Jan Arve Sæther --- src/quick/items/qquickwindow.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 3d355bb5b3..cf64a94631 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1669,9 +1669,9 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven { auto point = pointerEvent->point(0); lastMousePosition = point->scenePos(); + const bool mouseIsReleased = (point->state() == QQuickEventPoint::Released && pointerEvent->buttons() == Qt::NoButton); if (point->exclusiveGrabber()) { - bool mouseIsReleased = (point->state() == QQuickEventPoint::Released && pointerEvent->buttons() == Qt::NoButton); if (auto grabber = point->grabberItem()) { if (sendFilteredPointerEvent(pointerEvent, grabber)) return; @@ -1700,10 +1700,8 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven pointerEvent->localize(handler->parentItem()); if (!sendFilteredPointerEvent(pointerEvent, handler->parentItem())) handler->handlePointerEvent(pointerEvent); - if (mouseIsReleased) { + if (mouseIsReleased) point->setGrabberPointerHandler(nullptr, true); - point->clearPassiveGrabbers(); - } } } else { bool delivered = false; @@ -1742,6 +1740,9 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven // make sure not to accept unhandled events pointerEvent->setAccepted(false); } + // failsafe: never allow any kind of grab to persist after release + if (mouseIsReleased) + pointerEvent->clearGrabbers(); } bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item, @@ -2332,8 +2333,9 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) } } - if (allReleased && !event->exclusiveGrabbers().isEmpty()) { - qWarning() << "No release received for some grabbers" << event->exclusiveGrabbers(); + if (allReleased) { + if (Q_UNLIKELY(!event->exclusiveGrabbers().isEmpty())) + qWarning() << "No release received for some grabbers" << event->exclusiveGrabbers(); event->clearGrabbers(); } } -- cgit v1.2.3