From 0506fba1a862a30af5dcd9c5e240a8fb2fe304cf Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 13 Nov 2020 23:04:39 +0100 Subject: When Flickable filters UngrabMouse, react as if it was ungrabbed itself Fixes tst_QQuickListView::touchCancel again. In this scenario, a TouchCancel is sent, but gets turned into an UngrabMouse for delivery to the MouseArea which is the current grabber. We try to avoid calling QQuickWindow::mouseGrabberItem() because it's too vague a question to ask (which mouse? or did you mean the synth-mouse during synthesis from a touch or tablet event?); and now it acts different anyway, because eventsInDelivery.top() is an UngrabMouse, which did not include a pointer to the QPointingDevice until now. So now we turn the UngrabMouse event into a QSinglePointEvent so that it's possible to get exclusiveGrabber() and check that the grabber is not the same Flickable. (Otherwise, the grabber that's getting ungrabbed is usually the child receiver item sent to childMouseEventFilter().) Task-number: QTBUG-86729 Task-number: QTBUG-74679 Change-Id: I6dfd96686bdfb54723bbe093406b6ab1f75de855 Reviewed-by: Volker Hilsheimer --- src/quick/items/qquickflickable.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/quick/items/qquickflickable.cpp') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 31c1c33b10..9e7b2a4f17 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -2529,12 +2529,15 @@ bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) return QQuickItem::childMouseEventFilter(i, e); } - if (e->isPointerEvent()) { + if (e->type() == QEvent::UngrabMouse) { + Q_ASSERT(e->isSinglePointEvent()); + auto spe = static_cast(e); + const QObject *grabber = spe->exclusiveGrabber(spe->points().first()); + qCDebug(lcFilter) << "filtering UngrabMouse" << spe->points().first() << "for" << i << "grabber is" << grabber; + if (grabber != this) + mouseUngrabEvent(); // A child has been ungrabbed + } else if (e->isPointerEvent()) { return filterPointerEvent(i, static_cast(e)); - } else if (e->type() == QEvent::UngrabMouse && d->window && - d->window->mouseGrabberItem() && d->window->mouseGrabberItem() != this) { - // The grab has been taken away from a child and given to some other item. - mouseUngrabEvent(); } return QQuickItem::childMouseEventFilter(i, e); -- cgit v1.2.3