diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-11-13 23:04:39 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-11-17 13:32:25 +0000 |
commit | 0506fba1a862a30af5dcd9c5e240a8fb2fe304cf (patch) | |
tree | 3b6d11390ed10f21759e9108fbc4b87d49b8c847 | |
parent | 3073a81e90c8d835dfccccf8b3a080a93ed0d2af (diff) |
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 <volker.hilsheimer@qt.io>
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 13 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview/BLACKLIST | 2 |
3 files changed, 9 insertions, 8 deletions
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<QSinglePointEvent *>(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<QPointerEvent *>(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); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index d613b7e4f5..8183988835 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2605,7 +2605,7 @@ void QQuickWindowPrivate::onGrabChanged(QObject *grabber, QPointingDevice::GrabT if (isDeliveringTouchAsMouse() || point.device()->type() == QInputDevice::DeviceType::Mouse || point.device()->type() == QInputDevice::DeviceType::TouchPad) { - QEvent e(QEvent::UngrabMouse); + QMutableSinglePointEvent e(QEvent::UngrabMouse, point.device(), point); hasFiltered.clear(); filtered = sendFilteredMouseEvent(&e, item, item->parentItem()); if (!filtered) diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST index 414f21b347..1984999130 100644 --- a/tests/auto/quick/qquicklistview/BLACKLIST +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -12,7 +12,5 @@ macos macos opensuse-leap ubuntu-18.04 -[touchCancel] -* # QTBUG-86729 [sectionsSnap] macos ci # QTBUG-86729 |