aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2016-07-29 17:58:12 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2016-08-01 19:17:30 +0000
commiteae73be9060b4017b3eee64ab43a5b8ecb62ab2c (patch)
treecd53b56ffc4d14e5e9be32f2af47e202cfc855d1 /src
parentbf2c880b2b147804e9553d17a23ac4dd6ea4b3f4 (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.cpp42
-rw-r--r--src/quick/items/qquickwindow_p.h4
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