aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickwindow.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-10-04 11:54:53 +0200
committerJan Arve Sæther <jan-arve.saether@qt.io>2017-10-05 11:09:17 +0000
commit2dd530ca35032465d4e928aa7c8f29563eb0c5da (patch)
tree1244ab00a76f5e4b603afa1d0de08d04e99d3c5a /src/quick/items/qquickwindow.cpp
parent22e0de4a9fd2124a992c9e47540bf37bb273fbea (diff)
pre-accept the mouse event before childMouseEventFilter; grab after
In 5.9 a typical filtering sequence would be deliverPressEvent -> deliverMatchingPointsToItem -> QQuickWindow::sendEvent -> sendFilteredMouseEvent -> Test::childMouseEventFilter, let's say it returns true; then because the event is accepted, deliverMatchingPointsToItem grabs the mouse. In 5.10, we rather do deliverPressOrReleaseEvent -> sendFilteredPointerEvent -> sendFilteredPointerEventImpl -> Test::childMouseEventFilter, which returns true; and in this case, setGrabberItem was missing until now. In case of touch rather than mouse, it grabs the touchpoints in this kind of scenario. Also made the failsafe more reliable to ensure that no grabs are retained after release (after seeing that one failing autotest can cause failures in subsequent tests). Done-with: Jan-Arve Sæther Task-number: QTBUG-62631 Task-number: QTBUG-62549 Task-number: QTBUG-62628 Change-Id: I16dafc9aa0de2fc163c524f7f5b109f82d7e84fd Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/items/qquickwindow.cpp')
-rw-r--r--src/quick/items/qquickwindow.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 9f3f8531e4..c15079b3d7 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1745,9 +1745,6 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven
// make sure not to accept unhandled events
pointerEvent->setAccepted(false);
}
- // failsafe: never allow any kind of grab to persist after release
- if (mouseIsReleased)
- pointerEvent->clearGrabbers();
}
bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
@@ -2263,6 +2260,9 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
skipDelivery.clear();
if (event->asPointerMouseEvent()) {
deliverMouseEvent(event->asPointerMouseEvent());
+ // failsafe: never allow any kind of grab to persist after release
+ if (event->isReleaseEvent() && event->buttons() == Qt::NoButton)
+ event->clearGrabbers();
} else if (event->asPointerTouchEvent()) {
deliverTouchEvent(event->asPointerTouchEvent());
} else {
@@ -2768,10 +2768,20 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (receiver->acceptedMouseButtons()) {
QPointF localPos = receiver->mapFromScene(pme->point(0)->scenePosition());
QMouseEvent *me = pme->asMouseEvent(localPos);
+ me->setAccepted(true);
+ auto oldMouseGrabber = pme->point(0)->grabberItem();
if (filteringParent->childMouseEventFilter(receiver, me)) {
qCDebug(DBG_MOUSE) << "mouse event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
filtered = true;
+ if (me->isAccepted() && pme->isPressEvent()) {
+ auto mouseGrabber = pme->point(0)->grabberItem();
+ if (mouseGrabber && mouseGrabber != receiver && mouseGrabber != oldMouseGrabber) {
+ receiver->mouseUngrabEvent();
+ } else {
+ pme->point(0)->setGrabberItem(receiver);
+ }
+ }
}
}
} else if (QQuickPointerTouchEvent *pte = event->asPointerTouchEvent()) {
@@ -2789,7 +2799,6 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) {
qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
- filteringParent->grabMouse();
for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) {
auto pointerEventPoint = pte->pointById(point.id());
for (auto handler : pointerEventPoint->passiveGrabbers()) {
@@ -2797,7 +2806,9 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (!passiveGrabsToCancel.contains(grab))
passiveGrabsToCancel.append(grab);
}
- event->pointById(point.id())->setAccepted();
+ QQuickEventPoint *pt = event->pointById(point.id());
+ pt->setAccepted();
+ pt->setGrabberItem(filteringParent);
}
return true;
} else {
@@ -2838,7 +2849,8 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
pointerEventInstance(touchMouseDevice)->pointById(tp.id())->setGrabberItem(filteringParent);
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
- filteringParent->grabMouse();
+ if (mouseEvent->isAccepted())
+ filteringParent->grabMouse();
auto pointerEventPoint = pte->pointById(tp.id());
for (auto handler : pointerEventPoint->passiveGrabbers()) {
QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint);