aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@jollamobile.com>2012-11-26 09:33:20 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-26 02:00:02 +0100
commit429af6244518172e19abf7fecd7112f26bac6b31 (patch)
tree13d5f0f442556721929655ce315d72d73a4765e9
parent417403f803c03d177c8563878e06b95a15f0d4df (diff)
Nested Flickables with pressDelay flick incorrect Flickable
If the gesture is triggered within the pressDelay the outer Flickable will always handle the gesture. When the drag distance is exceeded replay the press event to allow all Flickables an opportunity to process the gesture normally. Task-number: QTBUG-28189 Change-Id: I36912cc19a48c90ae7a9a430580a8f40071bd5fd Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
-rw-r--r--src/quick/items/qquickflickable.cpp16
-rw-r--r--tests/auto/quick/qquickflickable/data/nestedPressDelay.qml42
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp29
3 files changed, 69 insertions, 18 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index a0bd1fab8e..105989c7f1 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -2007,6 +2007,22 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
switch (mouseEvent->type()) {
case QEvent::MouseMove:
+ if (d->delayedPressEvent) {
+ // A move beyond the threshold replays the press to give nested Flickables
+ // the opportunity to grab the gesture.
+ QPointF delta = event->localPos() - d->delayedPressEvent->localPos();
+ if (QQuickWindowPrivate::dragOverThreshold(qAbs(delta.x()), Qt::XAxis, event)
+ || QQuickWindowPrivate::dragOverThreshold(qAbs(delta.y()), Qt::YAxis, event)) {
+ // We replay the mouse press but the grabber we had might not be interested in the event (e.g. overlay)
+ // so we reset the grabber
+ if (c->mouseGrabberItem() == d->delayedPressTarget)
+ d->delayedPressTarget->ungrabMouse();
+ // Use the event handler that will take care of finding the proper item to propagate the event
+ QQuickWindowPrivate::get(window())->deliverMouseEvent(d->delayedPressEvent);
+ d->clearDelayedPress();
+ // continue on to handle mouse move event
+ }
+ }
d->handleMouseMoveEvent(mouseEvent.data());
break;
case QEvent::MouseButtonPress:
diff --git a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml
index 60dadcc73c..557b7c4117 100644
--- a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml
+++ b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml
@@ -8,24 +8,30 @@ Flickable {
contentHeight: 320
flickableDirection: Flickable.HorizontalFlick
pressDelay: 50
- Flickable {
- objectName: "innerFlickable"
- flickableDirection: Flickable.VerticalFlick
- width: 480
- height: 320
- contentWidth: 480
- contentHeight: 400
- pressDelay: 10000
- Rectangle {
- y: 100
- anchors.horizontalCenter: parent.horizontalCenter
- width: 240
- height: 100
- color: ma.pressed ? 'blue' : 'green'
- MouseArea {
- id: ma
- objectName: "mouseArea"
- anchors.fill: parent
+ Rectangle {
+ x: 20
+ y: 20
+ width: 400
+ height: 300
+ color: "yellow"
+ Flickable {
+ objectName: "innerFlickable"
+ anchors.fill: parent
+ flickableDirection: Flickable.HorizontalFlick
+ contentWidth: 1480
+ contentHeight: 400
+ pressDelay: 10000
+ Rectangle {
+ y: 100
+ x: 80
+ width: 240
+ height: 100
+ color: ma.pressed ? 'blue' : 'green'
+ MouseArea {
+ id: ma
+ objectName: "mouseArea"
+ anchors.fill: parent
+ }
}
}
}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 703e2918e6..ceed276305 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -388,6 +388,35 @@ void tst_qquickflickable::nestedPressDelay()
QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(150, 150));
+ // Dragging inner Flickable should work
+ QTest::mousePress(window, Qt::LeftButton, 0, QPoint(80, 150));
+ // the MouseArea is not pressed immediately
+ QVERIFY(outer->property("pressed").toBool() == false);
+
+ QTest::mouseMove(window, QPoint(60, 150));
+ QTest::mouseMove(window, QPoint(40, 150));
+ QTest::mouseMove(window, QPoint(20, 150));
+
+ QVERIFY(outer->property("moving").toBool() == false);
+ QVERIFY(inner->property("moving").toBool() == true);
+
+ QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(20, 150));
+
+ // Dragging the MouseArea in the inner Flickable should move the inner Flickable
+ QTest::mousePress(window, Qt::LeftButton, 0, QPoint(150, 150));
+ // the MouseArea is not pressed immediately
+ QVERIFY(outer->property("pressed").toBool() == false);
+
+ QTest::mouseMove(window, QPoint(130, 150));
+ QTest::mouseMove(window, QPoint(110, 150));
+ QTest::mouseMove(window, QPoint(90, 150));
+
+
+ QVERIFY(outer->property("moving").toBool() == false);
+ QVERIFY(inner->property("moving").toBool() == true);
+
+ QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(90, 150));
+
delete window;
}