diff options
Diffstat (limited to 'src/quick/handlers')
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler.cpp | 16 | ||||
-rw-r--r-- | src/quick/handlers/qquickpointerhandler.cpp | 27 | ||||
-rw-r--r-- | src/quick/handlers/qquicktaphandler.cpp | 13 |
3 files changed, 43 insertions, 13 deletions
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index f404788de4..2a9ecd341c 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -146,7 +146,7 @@ void QQuickMultiPointHandler::onActiveChanged() } } -void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *) +void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) { Q_D(QQuickMultiPointHandler); // If another handler or item takes over this set of points, assume it has @@ -155,6 +155,20 @@ void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventP // (e.g. between DragHandler and PinchHandler). if (transition == QQuickEventPoint::UngrabExclusive || transition == QQuickEventPoint::CancelGrabExclusive) d->currentPoints.clear(); + if (grabber != this) + return; + switch (transition) { + case QQuickEventPoint::GrabExclusive: + case QQuickEventPoint::GrabPassive: + case QQuickEventPoint::UngrabPassive: + case QQuickEventPoint::UngrabExclusive: + case QQuickEventPoint::CancelGrabPassive: + case QQuickEventPoint::CancelGrabExclusive: + QQuickPointerHandler::onGrabChanged(grabber, transition, point); + break; + case QQuickEventPoint::OverrideGrabPassive: + return; // don't emit + } } QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointerEvent *event) diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 03f8d8918c..a6c18feafe 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -346,10 +346,16 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec existingPhGrabber->metaObject()->className() == metaObject()->className()) allowed = true; } else if ((d->grabPermissions & CanTakeOverFromItems)) { + allowed = true; QQuickItem * existingItemGrabber = point->grabberItem(); - if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && point->pointerEvent()->asPointerMouseEvent()) || - (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent()))) { - allowed = true; + QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(parentItem()->window()); + const bool isMouse = point->pointerEvent()->asPointerMouseEvent(); + const bool isTouch = point->pointerEvent()->asPointerTouchEvent(); + if (existingItemGrabber && + ((existingItemGrabber->keepMouseGrab() && + (isMouse || winPriv->isDeliveringTouchAsMouse())) || + (existingItemGrabber->keepTouchGrab() && isTouch))) { + allowed = false; // If the handler wants to steal the exclusive grab from an Item, the Item can usually veto // by having its keepMouseGrab flag set. But an exception is if that Item is a parent that // normally filters events (such as a Flickable): it needs to be possible for e.g. a @@ -358,14 +364,19 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec // at first and then expects to be able to steal the grab later on. It cannot respect // Flickable's wishes in that case, because then it would never have a chance. if (existingItemGrabber->keepMouseGrab() && - !(existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem()))) { - QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(parentItem()->window()); + existingItemGrabber->filtersChildMouseEvents() && existingItemGrabber->isAncestorOf(parentItem())) { if (winPriv->isDeliveringTouchAsMouse() && point->pointId() == winPriv->touchMouseId) { - qCDebug(lcPointerHandlerGrab) << this << "wants to grab touchpoint" << point->pointId() - << "but declines to steal grab from touch-mouse grabber with keepMouseGrab=true" << existingItemGrabber; - allowed = false; + qCDebug(lcPointerHandlerGrab) << this << "steals touchpoint" << point->pointId() + << "despite parent touch-mouse grabber with keepMouseGrab=true" << existingItemGrabber; + allowed = true; } } + if (!allowed) { + qCDebug(lcPointerHandlerGrab) << this << "wants to grab point" << point->pointId() + << "but declines to steal from grabber" << existingItemGrabber + << "with keepMouseGrab=" << existingItemGrabber->keepMouseGrab() + << "keepTouchGrab=" << existingItemGrabber->keepTouchGrab(); + } } } } diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp index f3674d6fa9..2284750f15 100644 --- a/src/quick/handlers/qquicktaphandler.cpp +++ b/src/quick/handlers/qquicktaphandler.cpp @@ -209,6 +209,8 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event) If the spatial constraint is violated, \l pressed transitions immediately from true to false, regardless of the time held. + The \c gesturePolicy also affects grab behavior as described below. + \value TapHandler.DragThreshold (the default value) The event point must not move significantly. If the mouse, finger or stylus moves past the system-wide drag @@ -217,11 +219,13 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event) can be useful whenever TapHandler needs to cooperate with other input handlers (for example \l DragHandler) or event-handling Items (for example QtQuick Controls), because in this case TapHandler - will not take the exclusive grab, but merely a passive grab. + will not take the exclusive grab, but merely a + \l {QPointerEvent::addPassiveGrabber()}{passive grab}. \value TapHandler.WithinBounds If the event point leaves the bounds of the \c parent Item, the tap - gesture is canceled. The TapHandler will take the exclusive grab on + gesture is canceled. The TapHandler will take the + \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on press, but will release the grab as soon as the boundary constraint is no longer satisfied. @@ -232,8 +236,9 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event) typical behavior for button widgets: you can cancel a click by dragging outside the button, and you can also change your mind by dragging back inside the button before release. Note that it's - necessary for TapHandler take the exclusive grab on press and retain - it until release in order to detect this gesture. + necessary for TapHandler to take the + \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on press + and retain it until release in order to detect this gesture. */ void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy) { |