aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickwindow.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-05-18 11:23:25 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2017-11-14 05:35:37 +0000
commita2e2c8a329768e783b205564e44b2f486b777d74 (patch)
tree28816a9645df182628b6786997b883d60d32e1a2 /src/quick/items/qquickwindow.cpp
parentd845bdae79c93b1fd34427a76543152bd679b03f (diff)
Let passive-grabbing PointerHandlers see all point updates
even if all points are accepted or grabbed. A passive grab isn't much good if there are cases where the handler is prevented from monitoring. This enables e.g. the PinchHandler to steal the grab when the right number of touchpoints are present and have moved past the drag threshold, and enables completion of a couple of autotests. Change-Id: I78dc6fc585f80bfb3c13e0c6e757ef815fb94afe Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/items/qquickwindow.cpp')
-rw-r--r--src/quick/items/qquickwindow.cpp90
1 files changed, 37 insertions, 53 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 73a594b281..4bee6dcd9a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -768,16 +768,12 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
pt->cancelExclusiveGrab();
}
point->setGrabberItem(grabber);
- for (auto handler : point->passiveGrabbers())
- point->cancelPassiveGrab(handler);
}
} else {
QQuickPointerEvent *event = pointerEventInstance(QQuickPointerDevice::genericMouseDevice());
Q_ASSERT(event->pointCount() == 1);
auto point = event->point(0);
point->setGrabberItem(grabber);
- for (auto handler : point->passiveGrabbers())
- point->cancelPassiveGrab(handler);
}
@@ -1745,6 +1741,7 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven
if (mouseIsReleased)
point->setGrabberPointerHandler(nullptr, true);
}
+ deliverToPassiveGrabbers(point->passiveGrabbers(), pointerEvent);
} else {
bool delivered = false;
if (pointerEvent->isPressEvent()) {
@@ -2410,6 +2407,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
// Deliver touch points to existing grabbers
void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event)
{
+ bool done = false;
const auto grabbers = event->exclusiveGrabbers();
for (auto grabber : grabbers) {
// The grabber is guaranteed to be either an item or a handler.
@@ -2419,52 +2417,52 @@ void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve
QQuickPointerHandler *handler = static_cast<QQuickPointerHandler *>(grabber);
receiver = static_cast<QQuickPointerHandler *>(grabber)->parentItem();
if (sendFilteredPointerEvent(event, receiver))
- return;
+ done = true;
event->localize(receiver);
handler->handlePointerEvent(event);
if (event->allPointsAccepted())
- return;
+ done = true;
}
+ if (done)
+ break;
// If the grabber is an item or the grabbing handler didn't handle it,
// then deliver the event to the item (which may have multiple handlers).
deliverMatchingPointsToItem(receiver, event);
}
- // If some points weren't grabbed, deliver only to non-grabber PointerHandlers
- if (!event->allPointsGrabbed()) {
- int pointCount = event->pointCount();
+ // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once)
+ int pointCount = event->pointCount();
+ for (int i = 0; i < pointCount; ++i) {
+ QQuickEventPoint *point = event->point(i);
+ deliverToPassiveGrabbers(point->passiveGrabbers(), event);
+ }
+
+ if (done)
+ return;
- // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once)
+ // If some points weren't grabbed, deliver only to non-grabber PointerHandlers in reverse paint order
+ if (!event->allPointsGrabbed()) {
+ QVector<QQuickItem *> targetItems;
for (int i = 0; i < pointCount; ++i) {
QQuickEventPoint *point = event->point(i);
- deliverToPassiveGrabbers(point->passiveGrabbers(), event);
- }
-
- // If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order
- if (!event->allPointsGrabbed()) {
- QVector<QQuickItem *> targetItems;
- for (int i = 0; i < pointCount; ++i) {
- QQuickEventPoint *point = event->point(i);
- if (point->state() == QQuickEventPoint::Pressed)
- continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints
- QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false);
- if (targetItems.count()) {
- targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
- } else {
- targetItems = targetItemsForPoint;
- }
- }
-
- for (QQuickItem *item: targetItems) {
- if (grabbers.contains(item))
- continue;
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- event->localize(item);
- itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers
- if (event->allPointsGrabbed())
- break;
+ if (point->state() == QQuickEventPoint::Pressed)
+ continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints
+ QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false);
+ if (targetItems.count()) {
+ targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
+ } else {
+ targetItems = targetItemsForPoint;
}
}
+ for (QQuickItem *item : targetItems) {
+ if (grabbers.contains(item))
+ continue;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ event->localize(item);
+ itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers
+ if (event->allPointsGrabbed())
+ break;
+ }
}
}
@@ -2503,7 +2501,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
continue;
deliverMatchingPointsToItem(item, event, handlersOnly);
if (event->allPointsAccepted())
- break;
+ handlersOnly = true;
}
return event->allPointsAccepted();
@@ -2518,8 +2516,9 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
// Let the Item's handlers (if any) have the event first.
// However, double click should never be delivered to handlers.
if (!pointerEvent->isDoubleClickEvent()) {
+ bool wasAccepted = pointerEvent->allPointsAccepted();
itemPrivate->handlePointerEvent(pointerEvent);
- allowDoubleClick = !(pointerEvent->asPointerMouseEvent() && pointerEvent->isPressEvent() && pointerEvent->allPointsAccepted());
+ allowDoubleClick = wasAccepted || !(pointerEvent->asPointerMouseEvent() && pointerEvent->isPressEvent() && pointerEvent->allPointsAccepted());
}
if (handlersOnly)
return;
@@ -2831,17 +2830,10 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
// get a touch event customized for delivery to filteringParent
QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true));
if (filteringParentTouchEvent) {
- QVarLengthArray<QPair<QQuickPointerHandler *, QQuickEventPoint *>, 32> passiveGrabsToCancel;
if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) {
qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) {
- auto pointerEventPoint = pte->pointById(point.id());
- for (auto handler : pointerEventPoint->passiveGrabbers()) {
- QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint);
- if (!passiveGrabsToCancel.contains(grab))
- passiveGrabsToCancel.append(grab);
- }
QQuickEventPoint *pt = event->pointById(point.id());
pt->setAccepted();
pt->setGrabberItem(filteringParent);
@@ -2887,12 +2879,6 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
if (mouseEvent->isAccepted())
filteringParent->grabMouse();
- auto pointerEventPoint = pte->pointById(tp.id());
- for (auto handler : pointerEventPoint->passiveGrabbers()) {
- QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint);
- if (!passiveGrabsToCancel.contains(grab))
- passiveGrabsToCancel.append(grab);
- }
}
filtered = true;
}
@@ -2908,8 +2894,6 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
}
}
}
- for (auto grab : passiveGrabsToCancel)
- grab.second->cancelPassiveGrab(grab.first);
}
}
}