aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-08-29 10:34:23 +0200
committerJan Arve Sæther <jan-arve.saether@qt.io>2017-08-29 09:53:52 +0000
commit213a7054b563fc7374d328bc458739f8b8afa863 (patch)
treefba265d82e1f4de1b67b8c1c5764d1e96081c166
parent18052d17999c2e95cb666508e6e571594163562a (diff)
failsafe: never allow touch or mouse grab to persist after release
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 <jan-arve.saether@qt.io>
-rw-r--r--src/quick/items/qquickwindow.cpp14
1 files 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();
}
}