From 47ee54455beb1a063515041f85b4c216132491b3 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 2 Aug 2016 14:17:57 +0200 Subject: Start to unite press event delivery for touch and mouse Needs some cleanup, but seems to work now. Change-Id: I579009648d874c9293a0ebb3d7809536420b5574 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickwindow.cpp | 76 +++++++++++++++++++++------------------- src/quick/items/qquickwindow_p.h | 5 ++- 2 files changed, 42 insertions(+), 39 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index b8a7382525..3f5e85be5e 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1622,31 +1622,6 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t return me; } -void QQuickWindowPrivate::deliverInitialMousePressEvent(QQuickPointerMouseEvent *event) -{ - Q_Q(QQuickWindow); - QPointF scenePos = event->point(0)->scenePos(); - - QVector targets = pointerTargets(contentItem, scenePos, true); - for (QQuickItem *item: qAsConst(targets)) { - if (item->acceptedMouseButtons() & event->button()) { - QPointF localPos = item->mapFromScene(scenePos); - if (item->contains(localPos)) { - QMouseEvent *me = event->asMouseEvent(localPos); - me->accept(); - q->sendEvent(item, me); - if (me->isAccepted()) { - if (!q->mouseGrabberItem()) - item->grabMouse(); - return; - } - } - } - } - // no item accepted the event, make sure we don't accept the original mouse event - event->setAccepted(false); -} - void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent) { Q_Q(QQuickWindow); @@ -1666,12 +1641,15 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven q->mouseGrabberItem()->ungrabMouse(); } else { // send initial press + bool delivered = false; if (pointerEvent->isPressEvent()) { - deliverInitialMousePressEvent(pointerEvent); - } else { + QSet hasFiltered; + delivered = deliverPressEvent(pointerEvent, &hasFiltered); + } + + if (!delivered) // make sure not to accept unhandled events pointerEvent->setAccepted(false); - } } } @@ -2196,7 +2174,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) QSet hasFiltered; if (event->isPressEvent()) - deliverNewTouchPoints(event, &hasFiltered); + deliverPressEvent(event, &hasFiltered); if (!event->allPointsAccepted()) deliverUpdatedTouchPoints(event, &hasFiltered); @@ -2236,7 +2214,7 @@ bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve } // Deliver newly pressed touch points -bool QQuickWindowPrivate::deliverNewTouchPoints(QQuickPointerTouchEvent *event, QSet *hasFiltered) +bool QQuickWindowPrivate::deliverPressEvent(QQuickPointerEvent *event, QSet *hasFiltered) { const QVector points = event->unacceptedPressedPointScenePositions(); QVector targetItems; @@ -2249,18 +2227,44 @@ bool QQuickWindowPrivate::deliverNewTouchPoints(QQuickPointerTouchEvent *event, } } - for (QQuickItem *item: targetItems) + for (QQuickItem *item: targetItems) { deliverMatchingPointsToItem(item, event, hasFiltered); + if (event->allPointsAccepted()) + break; + } return event->allPointsAccepted(); } -// touchEventForItem has no means to generate a touch event that contains -// only the points that are relevant for this item. Thus the need for -// matchingPoints to already be that set of interesting points. -// They are all pre-transformed, too. -bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet *hasFiltered) +bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, QSet *hasFiltered) { + Q_Q(QQuickWindow); + + // TODO: unite this mouse point delivery with the synthetic mouse event below + if (auto event = pointerEvent->asPointerMouseEvent()) { + if (item->acceptedMouseButtons() & event->button()) { + auto point = event->point(0); + if (point->isAccepted()) + return false; + QPointF localPos = item->mapFromScene(point->scenePos()); + Q_ASSERT(item->contains(localPos)); // transform is checked already + QMouseEvent *me = event->asMouseEvent(localPos); + me->accept(); + q->sendEvent(item, me); + if (me->isAccepted()) { + if (!q->mouseGrabberItem()) + item->grabMouse(); + point->setAccepted(true); + } + return me->isAccepted(); + } + return false; + } + + QQuickPointerTouchEvent *event = pointerEvent->asPointerTouchEvent(); + if (!event) + return false; + QScopedPointer touchEvent(event->touchEventForItem(item)); if (!touchEvent) return false; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index a97ed36b09..11cadb4739 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -145,7 +145,6 @@ public: void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true); static void transformTouchPoints(QList &touchPoints, const QTransform &transform); static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); - void deliverInitialMousePressEvent(QQuickPointerMouseEvent *); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet *); #ifndef QT_NO_WHEELEVENT @@ -167,9 +166,9 @@ public: void deliverPointerEvent(QQuickPointerEvent *); void deliverTouchEvent(QQuickPointerTouchEvent *); bool deliverTouchCancelEvent(QTouchEvent *); - bool deliverNewTouchPoints(QQuickPointerTouchEvent *, QSet *); + bool deliverPressEvent(QQuickPointerEvent *, QSet *); bool deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet *hasFiltered); - bool deliverMatchingPointsToItem(QQuickItem *item, const QQuickPointerTouchEvent *event, QSet *filtered); + bool deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, QSet *filtered); static QTouchEvent *touchEventForItem(QQuickItem *target, const QTouchEvent &originalEvent); static QTouchEvent *touchEventWithPoints(const QTouchEvent &event, const QList &newPoints); bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event, QSet *filtered); -- cgit v1.2.3