diff options
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 32 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 2 |
2 files changed, 22 insertions, 12 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index c03b362ab8..44bcda027f 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2425,17 +2425,25 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, } } - if (allowChildEventFiltering && !handlersOnly) { + if (allowChildEventFiltering && !handlersOnly) updateFilteringParentItems(targetItems); - QQuickItem *filteredItem; - if (sendFilteredPointerEvent(event, nullptr, &filteredItem)) { - if (event->isAccepted()) + + QVarLengthArray<QQuickItem *> filteredItems; + for (QQuickItem *item : targetItems) { + if (sendFilteredPointerEvent(event, item)) { + if (event->isAccepted()) { + for (int i = 0; i < event->pointCount(); ++i) + event->point(i)->setAccepted(); return true; - targetItems.removeAll(filteredItem); + } + while (!filteringParentItems.isEmpty() && filteringParentItems.first().first == item) + filteringParentItems.removeFirst(); + filteredItems << item; } - } - for (QQuickItem *item: targetItems) { + // Do not deliverMatchingPointsTo any item for which the parent-filter already intercepted the event + if (filteredItems.contains(item)) + continue; deliverMatchingPointsToItem(item, event, handlersOnly); if (event->allPointsAccepted()) break; @@ -2755,23 +2763,25 @@ void QQuickWindowPrivate::updateFilteringParentItems(const QVector<QQuickItem *> } } -bool QQuickWindowPrivate::sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem **itemThatFiltered) +bool QQuickWindowPrivate::sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver) { if (!allowChildEventFiltering) return false; bool ret = false; + QVarLengthArray<QQuickItem *> filteringParentsToSkip; if (QQuickPointerMouseEvent *pme = event->asPointerMouseEvent()) { for (QPair<QQuickItem *,QQuickItem *> itemAndParent : filteringParentItems) { QQuickItem *item = receiver ? receiver : itemAndParent.first; QQuickItem *filteringParent = itemAndParent.second; if (item == filteringParent) continue; // a filtering item never needs to filter for itself + if (filteringParentsToSkip.contains(filteringParent)) + continue; QPointF localPos = item->mapFromScene(pme->point(0)->scenePos()); QMouseEvent *me = pme->asMouseEvent(localPos); - if (filteringParent->childMouseEventFilter(item, me)) { - if (itemThatFiltered) *itemThatFiltered = item; + if (filteringParent->childMouseEventFilter(item, me)) ret = true; - } + filteringParentsToSkip.append(filteringParent); } } else if (QQuickPointerTouchEvent *pte = event->asPointerTouchEvent()) { QVarLengthArray<QPair<QQuickPointerHandler *, QQuickEventPoint *>, 32> passiveGrabsToCancel; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 837ef11d25..36b2c57e5c 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -148,7 +148,7 @@ public: static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet<QQuickItem *> *); - bool sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem **itemThatFiltered = 0); + bool sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver); #if QT_CONFIG(wheelevent) bool deliverWheelEvent(QQuickItem *, QWheelEvent *); #endif |