summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@qinetic.com.au>2016-03-10 13:28:06 +1000
committerAndrew den Exter <andrew.den.exter@qinetic.com.au>2016-09-23 00:31:58 +0000
commit0aea009425242417bffdb171c8eca02ff52f4a7b (patch)
treea8c22df67944ee830c7a7d351748d5e8013a0c7a
parent345226aa3ecee8642c3bf46e40c981d4a49d958e (diff)
Fix Flickable state being reset when it replays a delayed press.
Ignore mouseUngrabEvents() triggered by giving mouse grab to a child item when replaying a delayed press event. Change-Id: I6c8db61167e21bf10d533b17f7cc65e4754bd432 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Martin Jones <martin.jones@qinetic.com.au>
-rw-r--r--src/quick/items/qquickflickable.cpp5
-rw-r--r--tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml4
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp98
3 files changed, 88 insertions, 19 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 870a0268e1..c838eae3c7 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1539,11 +1539,11 @@ void QQuickFlickablePrivate::replayDelayedPress()
// If we have the grab, release before delivering the event
if (QQuickWindow *w = q->window()) {
+ replayingPressEvent = true;
if (w->mouseGrabberItem() == q)
q->ungrabMouse();
// Use the event handler that will take care of finding the proper item to propagate the event
- replayingPressEvent = true;
QCoreApplication::sendEvent(w, mouseEvent.data());
replayingPressEvent = false;
}
@@ -2199,7 +2199,8 @@ void QQuickFlickable::mouseUngrabEvent()
Q_D(QQuickFlickable);
// if our mouse grab has been removed (probably by another Flickable),
// fix our state
- d->cancelInteraction();
+ if (!d->replayingPressEvent)
+ d->cancelInteraction();
}
void QQuickFlickablePrivate::cancelInteraction()
diff --git a/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml b/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
index 59318e5b95..81187f3c2f 100644
--- a/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
+++ b/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
@@ -32,6 +32,10 @@ Flickable {
anchors.margins: 100
color: "blue"
}
+ MouseArea {
+ anchors.fill: parent
+ objectName: "mouseArea"
+ }
}
}
}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 96fe97f372..bbaccfe534 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -33,6 +33,7 @@
#include <QtQuick/qquickview.h>
#include <private/qquickflickable_p.h>
#include <private/qquickflickable_p_p.h>
+#include <private/qquickmousearea_p.h>
#include <private/qquicktransition_p.h>
#include <private/qqmlvaluetype_p.h>
#include <math.h>
@@ -486,8 +487,20 @@ void tst_qquickflickable::nestedPressDelay()
// QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
QTRY_VERIFY(outer->property("pressed").toBool());
+ QTest::mouseMove(window.data(), QPoint(130, 150));
+ QTest::mouseMove(window.data(), QPoint(110, 150));
+ QTest::mouseMove(window.data(), QPoint(90, 150));
+
+ QVERIFY(!outer->property("moving").toBool());
+ QVERIFY(!outer->property("dragging").toBool());
+ QVERIFY(inner->property("moving").toBool());
+ QVERIFY(inner->property("dragging").toBool());
+
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150));
+ QVERIFY(!inner->property("dragging").toBool());
+ QTRY_VERIFY(!inner->property("moving").toBool());
+
// Dragging inner Flickable should work
moveAndPress(window.data(), QPoint(80, 150));
// the MouseArea is not pressed immediately
@@ -499,10 +512,15 @@ void tst_qquickflickable::nestedPressDelay()
QTest::mouseMove(window.data(), QPoint(20, 150));
QVERIFY(inner->property("moving").toBool());
+ QVERIFY(inner->property("dragging").toBool());
QVERIFY(!outer->property("moving").toBool());
+ QVERIFY(!outer->property("dragging").toBool());
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(20, 150));
+ QVERIFY(!inner->property("dragging").toBool());
+ QTRY_VERIFY(!inner->property("moving").toBool());
+
// Dragging the MouseArea in the inner Flickable should move the inner Flickable
moveAndPress(window.data(), QPoint(150, 150));
// the MouseArea is not pressed immediately
@@ -512,11 +530,15 @@ void tst_qquickflickable::nestedPressDelay()
QTest::mouseMove(window.data(), QPoint(110, 150));
QTest::mouseMove(window.data(), QPoint(90, 150));
-
QVERIFY(!outer->property("moving").toBool());
+ QVERIFY(!outer->property("dragging").toBool());
QVERIFY(inner->property("moving").toBool());
+ QVERIFY(inner->property("dragging").toBool());
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(90, 150));
+
+ QVERIFY(!inner->property("dragging").toBool());
+ QTRY_VERIFY(!inner->property("moving").toBool());
}
void tst_qquickflickable::filterReplayedPress()
@@ -1472,20 +1494,26 @@ void tst_qquickflickable::nestedStopAtBounds_data()
QTest::addColumn<bool>("invert");
QTest::addColumn<int>("boundsBehavior");
QTest::addColumn<qreal>("margin");
-
- QTest::newRow("left,stop") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(0);
- QTest::newRow("right,stop") << false << true << int(QQuickFlickable::StopAtBounds) << qreal(0);
- QTest::newRow("top,stop") << true << false << int(QQuickFlickable::StopAtBounds) << qreal(0);
- QTest::newRow("bottom,stop") << true << true << int(QQuickFlickable::StopAtBounds) << qreal(0);
- QTest::newRow("left,over") << false << false << int(QQuickFlickable::DragOverBounds) << qreal(0);
- QTest::newRow("right,over") << false << true << int(QQuickFlickable::DragOverBounds) << qreal(0);
- QTest::newRow("top,over") << true << false << int(QQuickFlickable::DragOverBounds) << qreal(0);
- QTest::newRow("bottom,over") << true << true << int(QQuickFlickable::DragOverBounds) << qreal(0);
-
- QTest::newRow("left,stop,margin") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(20);
- QTest::newRow("right,stop,margin") << false << true << int(QQuickFlickable::StopAtBounds) << qreal(20);
- QTest::newRow("top,stop,margin") << true << false << int(QQuickFlickable::StopAtBounds) << qreal(20);
- QTest::newRow("bottom,stop,margin") << true << true << int(QQuickFlickable::StopAtBounds) << qreal(20);
+ QTest::addColumn<bool>("innerFiltering");
+ QTest::addColumn<int>("pressDelay");
+ QTest::addColumn<bool>("waitForPressDelay");
+
+ QTest::newRow("left,stop") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("right,stop") << false << true << int(QQuickFlickable::StopAtBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("top,stop") << true << false << int(QQuickFlickable::StopAtBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("bottom,stop") << true << true << int(QQuickFlickable::StopAtBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("left,over") << false << false << int(QQuickFlickable::DragOverBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("right,over") << false << true << int(QQuickFlickable::DragOverBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("top,over") << true << false << int(QQuickFlickable::DragOverBounds) << qreal(0) << false << 0 << false;
+ QTest::newRow("bottom,over") << true << true << int(QQuickFlickable::DragOverBounds) << qreal(0) << false << 0 << false;
+
+ QTest::newRow("left,stop,margin") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(20) << false << 0 << false;
+ QTest::newRow("right,stop,margin") << false << true << int(QQuickFlickable::StopAtBounds) << qreal(20) << false << 0 << false;
+ QTest::newRow("top,stop,margin") << true << false << int(QQuickFlickable::StopAtBounds) << qreal(20) << false << 0 << false;
+ QTest::newRow("bottom,stop,margin") << true << true << int(QQuickFlickable::StopAtBounds) << qreal(20) << false << 0 << false;
+
+ QTest::newRow("left,stop,after press delay") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(0) << true << 50 << true;
+ QTest::newRow("left,stop,before press delay") << false << false << int(QQuickFlickable::StopAtBounds) << qreal(0) << true << 50 << false;
}
void tst_qquickflickable::nestedStopAtBounds()
@@ -1494,6 +1522,9 @@ void tst_qquickflickable::nestedStopAtBounds()
QFETCH(bool, invert);
QFETCH(int, boundsBehavior);
QFETCH(qreal, margin);
+ QFETCH(bool, innerFiltering);
+ QFETCH(int, pressDelay);
+ QFETCH(bool, waitForPressDelay);
QQuickView view;
view.setSource(testFileUrl("nestedStopAtBounds.qml"));
@@ -1526,6 +1557,12 @@ void tst_qquickflickable::nestedStopAtBounds()
QCOMPARE(inner->isAtYBeginning(), invert);
QCOMPARE(inner->isAtYEnd(), !invert);
+ inner->setPressDelay(pressDelay);
+
+ QQuickMouseArea *mouseArea = inner->findChild<QQuickMouseArea *>("mouseArea");
+ QVERIFY(mouseArea);
+ mouseArea->setEnabled(innerFiltering);
+
const int threshold = qApp->styleHints()->startDragDistance();
QPoint position(200, 200);
@@ -1533,17 +1570,25 @@ void tst_qquickflickable::nestedStopAtBounds()
// drag toward the aligned boundary. Outer flickable dragged.
moveAndPress(&view, position);
- QTest::qWait(10);
+ if (waitForPressDelay) {
+ QVERIFY(innerFiltering); // isPressed will never be true if the mouse area isn't enabled.
+ QTRY_VERIFY(mouseArea->pressed());
+ }
+
axis += invert ? threshold * 2 : -threshold * 2;
QTest::mouseMove(&view, position);
axis += invert ? threshold : -threshold;
QTest::mouseMove(&view, position);
QCOMPARE(outer->isDragging(), true);
+ QCOMPARE(outer->isMoving(), true);
QCOMPARE(inner->isDragging(), false);
+ QCOMPARE(inner->isMoving(), false);
QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
QVERIFY(!outer->isDragging());
QTRY_VERIFY(!outer->isMoving());
+ QVERIFY(!inner->isDragging());
+ QVERIFY(!inner->isMoving());
axis = 200;
outer->setContentX(50);
@@ -1557,10 +1602,15 @@ void tst_qquickflickable::nestedStopAtBounds()
axis += invert ? -threshold : threshold;
QTest::mouseMove(&view, position);
QCOMPARE(outer->isDragging(), false);
+ QCOMPARE(outer->isMoving(), false);
QCOMPARE(inner->isDragging(), true);
+ QCOMPARE(inner->isMoving(), true);
QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
- QTRY_VERIFY(!outer->isMoving());
+ QVERIFY(!inner->isDragging());
+ QTRY_VERIFY(!inner->isMoving());
+ QVERIFY(!outer->isDragging());
+ QVERIFY(!outer->isMoving());
axis = 200;
inner->setContentX(-margin);
@@ -1576,9 +1626,16 @@ void tst_qquickflickable::nestedStopAtBounds()
axis += invert ? -threshold : threshold;
QTest::mouseMove(&view, position);
QCOMPARE(outer->isDragging(), true);
+ QCOMPARE(outer->isMoving(), true);
QCOMPARE(inner->isDragging(), false);
+ QCOMPARE(inner->isMoving(), false);
QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
+ QVERIFY(!outer->isDragging());
+ QTRY_VERIFY(!outer->isMoving());
+ QVERIFY(!inner->isDragging());
+ QVERIFY(!inner->isMoving());
+
axis = 200;
inner->setContentX(-margin);
inner->setContentY(-margin);
@@ -1593,8 +1650,15 @@ void tst_qquickflickable::nestedStopAtBounds()
axis += invert ? -threshold : threshold;
QTest::mouseMove(&view, position);
QCOMPARE(outer->isDragging(), true);
+ QCOMPARE(outer->isMoving(), true);
QCOMPARE(inner->isDragging(), false);
+ QCOMPARE(inner->isMoving(), false);
QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
+
+ QVERIFY(!outer->isDragging());
+ QTRY_VERIFY(!outer->isMoving());
+ QVERIFY(!inner->isDragging());
+ QVERIFY(!inner->isMoving());
}
void tst_qquickflickable::stopAtBounds_data()