diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2016-09-30 12:28:13 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@qt.io> | 2016-10-02 14:21:10 +0000 |
commit | d9d2277fb8e823af8977d6f3aa5cc7ee8213c26a (patch) | |
tree | 1d2edd2d8de627ac771a5c0aa2fe48ac2efbaecd /src/quick/items/qquickflickable.cpp | |
parent | 5f4299eb597b89df20189a5c5a6235287e54b636 (diff) |
Flickable: respect keepMouseGrab again
The keep grab property works in a "cooperative" way, items need to
respect it. Since we don't pre-grab any more, flickable would check the
wrong item for the property. It should simply take the receiver item
into account, which has to have the grab if anyone has it. If the
receiver didn't have the grab, it wouldn't be the receiver in the first
place.
Task-number: QTBUG-55229
Change-Id: If7d8b0c99bf912c0e09427cd20e89be1798ace5d
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/items/qquickflickable.cpp')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 0333f6b9bd..e69c6a8d59 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -2235,21 +2235,28 @@ void QQuickFlickablePrivate::cancelInteraction() } } -bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event) +/*! + QQuickFlickable::filterMouseEvent checks filtered mouse events and potentially steals them. + + This is how flickable takes over events from other items (\a receiver) that are on top of it. + It filters their events and may take over (grab) the \a event. + Return true if the mouse event will be stolen. + \internal +*/ +bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event) { Q_D(QQuickFlickable); QPointF localPos = mapFromScene(event->windowPos()); - QQuickWindow *c = window(); - QQuickItem *grabber = c ? c->mouseGrabberItem() : 0; - if (grabber == this && d->stealMouse) { + Q_ASSERT_X(receiver != this, "", "Flickable received a filter event for itself"); + if (receiver == this && d->stealMouse) { // we are already the grabber and we do want the mouse event to ourselves. return true; } - bool grabberDisabled = grabber && !grabber->isEnabled(); + bool receiverDisabled = receiver && !receiver->isEnabled(); bool stealThisEvent = d->stealMouse; - if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab() || grabberDisabled)) { + if ((stealThisEvent || contains(localPos)) && (!receiver || !receiver->keepMouseGrab() || receiverDisabled)) { QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos)); mouseEvent->setAccepted(false); @@ -2259,7 +2266,7 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event) break; case QEvent::MouseButtonPress: d->handleMousePressEvent(mouseEvent.data()); - d->captureDelayedPress(item, event); + d->captureDelayedPress(receiver, event); stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above break; case QEvent::MouseButtonRelease: @@ -2269,15 +2276,14 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event) default: break; } - grabber = qobject_cast<QQuickItem*>(c->mouseGrabberItem()); - if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || grabberDisabled) { + if ((receiver && stealThisEvent && !receiver->keepMouseGrab() && receiver != this) || receiverDisabled) { d->clearDelayedPress(); grabMouse(); } else if (d->delayedPressEvent) { grabMouse(); } - const bool filtered = stealThisEvent || d->delayedPressEvent || grabberDisabled; + const bool filtered = stealThisEvent || d->delayedPressEvent || receiverDisabled; if (filtered) { event->setAccepted(true); } @@ -2286,7 +2292,7 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event) d->lastPosTime = -1; returnToBounds(); } - if (event->type() == QEvent::MouseButtonRelease || (grabber && grabber->keepMouseGrab() && !grabberDisabled)) { + if (event->type() == QEvent::MouseButtonRelease || (receiver && receiver->keepMouseGrab() && !receiverDisabled)) { // mouse released, or another item has claimed the grab d->lastPosTime = -1; d->clearDelayedPress(); @@ -2306,7 +2312,7 @@ bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) case QEvent::MouseButtonPress: case QEvent::MouseMove: case QEvent::MouseButtonRelease: - return sendMouseEvent(i, static_cast<QMouseEvent *>(e)); + return filterMouseEvent(i, static_cast<QMouseEvent *>(e)); case QEvent::UngrabMouse: if (d->window && d->window->mouseGrabberItem() && d->window->mouseGrabberItem() != this) { // The grab has been taken away from a child and given to some other item. |