diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2010-06-17 10:13:14 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2010-06-17 10:20:24 (GMT) |
commit | 8fe1b2baf562df50e7b5cd7b4ea23bc5545ee80f (patch) | |
tree | 69a7d124eb08101b6b51b6a09115381dcf82e4b0 | |
parent | 2b08b67660b3f059262f867c765fb6f068404820 (diff) | |
download | Qt-8fe1b2baf562df50e7b5cd7b4ea23bc5545ee80f.zip Qt-8fe1b2baf562df50e7b5cd7b4ea23bc5545ee80f.tar.gz Qt-8fe1b2baf562df50e7b5cd7b4ea23bc5545ee80f.tar.bz2 |
Fix event forwarding in QDeclarativeFlickable.
The flickable element filters all events of its children and store the
press event to replay it if there is a release or if the scrolling
didn't happen. The issue was that the event and the item stored to
"replay" the press event might not be the item that is interessted by
the event. Let say you have a translucent overlay on top of an other
item. Previously all events will be send to the overlay and not to the
item underneath. This happen beause QGraphicsView propagate events from
top to bottom (stacking order) so the overlay will be the first child
filtered by the flickable. So we need to repropagate the event through
the normal process to the event delivery mechanism of QGraphicsView
will work properly. Also we need to unset the mouse grabber since after
the first press it might be set to a wrong item. We also need to replay
the release by ourself on the new mouse grabber but only if we need to
send again the press.
Reviewed-by:Yann Bodson
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativeflickable.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 6dfd4d9..3f681b7 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -914,8 +914,14 @@ void QDeclarativeFlickable::timerEvent(QTimerEvent *event) d->delayedPressTimer.stop(); if (d->delayedPressEvent) { QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0; - if (!grabber || grabber != this) - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); + if (!grabber || grabber != this) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (scene()->mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(scene(), d->delayedPressEvent); + } delete d->delayedPressEvent; d->delayedPressEvent = 0; } @@ -1206,8 +1212,17 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) break; case QEvent::GraphicsSceneMouseRelease: if (d->delayedPressEvent) { - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (s->mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(scene(), d->delayedPressEvent); d->clearDelayedPress(); + // We send the release + scene()->sendEvent(s->mouseGrabberItem(), event); + // And the event has been consumed + return true; } d->handleMouseReleaseEvent(&mouseEvent); break; |