diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2016-12-05 12:20:31 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-02-10 20:25:02 +0000 |
commit | 34d17ce0243ffad278ac7cf57804bf150524940a (patch) | |
tree | c714bc459d25a646fef9a84b7a931c553f9c0cfb | |
parent | f3cf71bae2e4bdc83ffa661d7273f6709b006615 (diff) |
prioritize delivery to passive grabbers
Change-Id: I445c53ea74e26318aa1193a963cbcae601b0f76d
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 457d59ea39..10144e6eb9 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1693,15 +1693,27 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven delivered = deliverPressEvent(pointerEvent, &hasFiltered); } else if (pointerEvent->device()->type() == QQuickPointerDevice::Mouse) { // if this is an update or release from an actual mouse, - // and the point wasn't grabbed, deliver only to non-grabber PointerHandlers - QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePos(), false); - for (QQuickItem *item : targetItems) { - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - pointerEvent->localize(item); - if (itemPrivate->handlePointerEvent(pointerEvent, true)) // avoid re-delivering to grabbers - delivered = true; - if (point->grabber()) - break; + // and the point wasn't grabbed, deliver only to PointerHandlers: + // passive grabbers first, then the rest + QVector<QQuickPointerHandler *> &eventDeliveryTargets = pointerEvent->device()->eventDeliveryTargets(); + for (auto handler : point->passiveGrabbers()) { + // a null pointer in passiveGrabbers is unlikely, unless the grabbing handler was deleted dynamically + if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) { + handler->handlePointerEvent(pointerEvent); + eventDeliveryTargets.append(handler); + } + } + // If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order + if (!pointerEvent->allPointsGrabbed()) { + QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePos(), false); + for (QQuickItem *item : targetItems) { + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + pointerEvent->localize(item); + if (itemPrivate->handlePointerEvent(pointerEvent, true)) // avoid re-delivering to grabbers + delivered = true; + if (point->grabber()) + break; + } } } @@ -2293,26 +2305,42 @@ bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve // If some points weren't grabbed, deliver only to non-grabber PointerHandlers if (!event->allPointsGrabbed()) { - QVector<QQuickItem *> targetItems; int pointCount = event->pointCount(); + + // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once) + QVector<QQuickPointerHandler *> &eventDeliveryTargets = event->device()->eventDeliveryTargets(); for (int i = 0; i < pointCount; ++i) { QQuickEventPoint *point = event->point(i); - QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePos(), false); - if (targetItems.count()) { - targetItems = mergePointerTargets(targetItems, targetItemsForPoint); - } else { - targetItems = targetItemsForPoint; + for (auto handler : point->passiveGrabbers()) { + if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) { + handler->handlePointerEvent(event); + eventDeliveryTargets.append(handler); + } } } - 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 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); + QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePos(), 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; + } } } |