diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2016-07-29 17:58:12 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2016-08-01 19:17:30 +0000 |
commit | eae73be9060b4017b3eee64ab43a5b8ecb62ab2c (patch) | |
tree | cd53b56ffc4d14e5e9be32f2af47e202cfc855d1 /src | |
parent | bf2c880b2b147804e9553d17a23ac4dd6ea4b3f4 (diff) |
Deliver touch points in defined order
[ChangeLog][QtQuick] Touch events are now delivered in a well defined
order: New touch points are delivered first to items under the finger
which was first touching the screen. Then to items that are under the
second finger and finally to common ancestors.
This means that items that are "on top" will get a chance to grab touch
points before any items in the background.
Change-Id: Icf9a163c0183437cdb79040b8513fd746c3a6a44
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 42 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 4 |
2 files changed, 16 insertions, 30 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 339e770910..cc422361f8 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1626,7 +1626,7 @@ bool QQuickWindowPrivate::deliverInitialMousePressEvent(QMouseEvent *event) { Q_Q(QQuickWindow); - QVector<QQuickItem *> targets = pointerTargets(contentItem, event->windowPos()); + QVector<QQuickItem *> targets = pointerTargets(contentItem, event->windowPos(), true); for (QQuickItem *item: qAsConst(targets)) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (itemPrivate->acceptedMouseButtons() & event->button()) { @@ -2141,7 +2141,7 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) // check if item or any of its child items contain the point // FIXME: should this be iterative instead of recursive? -QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, const QPointF &scenePos) const +QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, const QPointF &scenePos, bool checkMouseButtons) const { QVector<QQuickItem *> targets; auto itemPrivate = QQuickItemPrivate::get(item); @@ -2159,10 +2159,10 @@ QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, cons auto childPrivate = QQuickItemPrivate::get(child); if (!child->isVisible() || !child->isEnabled() || childPrivate->culled) continue; - targets << pointerTargets(child, scenePos); + targets << pointerTargets(child, scenePos, false); } - if (item->contains(itemPos) && itemPrivate->acceptedMouseButtons()) { + if (item->contains(itemPos) && (!checkMouseButtons || itemPrivate->acceptedMouseButtons())) { // add this item last - children take precedence targets << item; } @@ -2197,7 +2197,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) QSet<QQuickItem *> hasFiltered; if (event->isPressEvent()) - deliverNewTouchPoints(contentItem, event, &hasFiltered); + deliverNewTouchPoints(event, &hasFiltered); if (!event->allPointsAccepted()) deliverUpdatedTouchPoints(event, &hasFiltered); @@ -2236,33 +2236,19 @@ bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve return false; } -// This function recurses and sends the events to the individual items -bool QQuickWindowPrivate::deliverNewTouchPoints(QQuickItem *item, QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered) +// Deliver newly pressed touch points +bool QQuickWindowPrivate::deliverNewTouchPoints(QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered) { - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - - // Check if our children want the event (or parts of it) - // This is the only point where touch event delivery recurses! - QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); - for (int ii = children.count() - 1; ii >= 0; --ii) { - QQuickItem *child = children.at(ii); - if (!child->isEnabled() || !child->isVisible() || QQuickItemPrivate::get(child)->culled) - continue; - if (deliverNewTouchPoints(child, event, hasFiltered)) - return true; + const QVector<QPointF> points = event->unacceptedPressedPointScenePositions(); + QVector<QQuickItem *> targetItems; + for (QPointF point: points) { + QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point, false); + targetItems = mergePointerTargets(targetItems, targetItemsForPoint); } - // None of the children accepted the event, so check the given item itself. - // First, construct matchingPoints as a list of TouchPoints which the - // given item might be interested in. Any newly-pressed point which is - // inside the item's bounds will be interesting, and also any updated point - // which was already accepted by that item when it was first pressed. - // (A point which was already accepted is effectively "grabbed" by the item.) - - // This item might be interested in the event. - deliverMatchingPointsToItem(item, event, hasFiltered); + for (QQuickItem *item: targetItems) + deliverMatchingPointsToItem(item, event, hasFiltered); - // recursion is done only if ALL touch points have been delivered return event->allPointsAccepted(); } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 51804653f7..cd63f5a8f6 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -167,14 +167,14 @@ public: void deliverPointerEvent(QQuickPointerEvent *); void deliverTouchEvent(QQuickPointerTouchEvent *); bool deliverTouchCancelEvent(QTouchEvent *); - bool deliverNewTouchPoints(QQuickItem *, QQuickPointerTouchEvent *, QSet<QQuickItem *> *); + bool deliverNewTouchPoints(QQuickPointerTouchEvent *, QSet<QQuickItem *> *); bool deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered); bool deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet<QQuickItem*> *filtered); static QTouchEvent *touchEventForItem(QQuickItem *target, const QTouchEvent &originalEvent); static QTouchEvent *touchEventWithPoints(const QTouchEvent &event, const QList<QTouchEvent::TouchPoint> &newPoints); bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event, QSet<QQuickItem*> *filtered); - QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &) const; + QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &, bool checkMouseButtons) const; QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const; // hover delivery |