aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2015-04-14 14:55:24 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2016-08-05 08:59:52 +0000
commitebf07c3f68415099132856b2831633c310bc3395 (patch)
tree685ea0baeb507071f1095f3015bf9cc113675f61
parentb65b6bd5a6d571ad7047d85508f85c62ca9ad8ce (diff)
Flickable: avoid infinite velocity during release after drag
It sometimes happens on touchscreens that mouse events occur too close together. We cannot calculate velocity based on zero elapsed time, so just ignore the event. Task-number: QTBUG-45527 Change-Id: I120e73cfa60e2fcc594cb1f3b69f530e746abddd Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
-rw-r--r--src/quick/items/qquickflickable.cpp8
-rw-r--r--tests/auto/qmltest/listview/tst_listview.qml4
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp1
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp8
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp13
5 files changed, 32 insertions, 2 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index b0980cd2c1..760eeed452 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1224,13 +1224,17 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
return;
qint64 currentTimestamp = computeCurrentTime(event);
- qreal elapsed = qreal(currentTimestamp - (lastPos.isNull() ? lastPressTime : lastPosTime)) / 1000.;
QVector2D deltas = QVector2D(event->localPos() - pressPos);
bool overThreshold = false;
QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event);
// TODO guarantee that events always have velocity so that it never needs to be computed here
- if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity))
+ if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) {
+ qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime);
+ if (currentTimestamp == lastTimestamp)
+ return; // events are too close together: velocity would be infinite
+ qreal elapsed = qreal(currentTimestamp - lastTimestamp) / 1000.;
velocity = QVector2D(event->localPos() - (lastPos.isNull() ? pressPos : lastPos)) / elapsed;
+ }
if (q->yflick())
overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, event);
diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
index a3cae7fce2..ef9f73e005 100644
--- a/tests/auto/qmltest/listview/tst_listview.qml
+++ b/tests/auto/qmltest/listview/tst_listview.qml
@@ -304,9 +304,13 @@ Item {
function test_listInteractiveCurrentIndexEnforce() {
mousePress(listInteractiveCurrentIndexEnforce, 10, 50);
+ wait(1); // because Flickable pays attention to velocity, we need some time between movements
mouseMove(listInteractiveCurrentIndexEnforce, 10, 40);
+ wait(1);
mouseMove(listInteractiveCurrentIndexEnforce, 10, 30);
+ wait(1);
mouseMove(listInteractiveCurrentIndexEnforce, 10, 20);
+ wait(1);
mouseMove(listInteractiveCurrentIndexEnforce, 10, 10);
compare(listInteractiveCurrentIndexEnforce.interactive, false);
mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10);
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 2e134ff5ad..294f7069c0 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -1466,6 +1466,7 @@ void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *tou
for (int i = 1; i <= 8; ++i) {
QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements
}
QTest::touchEvent(window, touchDevice).release(0, to, window);
QQuickTouchUtils::flush(window);
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 2f432e57bc..d3b576e092 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -601,18 +601,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
@@ -788,18 +792,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
QCOMPARE(point11->pressed(), true);
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
p1 += QPoint(0,15);
+ QTest::qWait(1);
QTest::touchEvent(window.data(), device).move(0, p1);
QQuickTouchUtils::flush(window.data());
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index e14b7d7c84..0608af7cd4 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -591,10 +591,13 @@ void tst_TouchMouse::buttonOnFlickable()
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements
QTest::touchEvent(window, device).move(0, p1, window);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p2, window);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p3, window);
QQuickTouchUtils::flush(window);
@@ -676,10 +679,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p1, window);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p2, window);
QQuickTouchUtils::flush(window);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p3, window);
QQuickTouchUtils::flush(window);
QVERIFY(flickable->isMovingVertically());
@@ -871,15 +877,19 @@ void tst_TouchMouse::pinchOnFlickable()
QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p, window);
QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p, window);
QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p, window);
QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
+ QTest::qWait(1);
QTest::touchEvent(window, device).move(0, p, window);
QQuickTouchUtils::flush(window);
QTest::touchEvent(window, device).release(0, p, window);
@@ -1092,13 +1102,16 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
QQuickTouchUtils::flush(window);
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
+ QTest::qWait(1);
pinchSequence.move(0, p, window).commit();
QQuickTouchUtils::flush(window);
p -= QPoint(10, 0);
+ QTest::qWait(1);
pinchSequence.move(0, p, window).commit();
QQuickTouchUtils::flush(window);
QGuiApplication::processEvents();
p -= QPoint(10, 0);
+ QTest::qWait(1);
pinchSequence.move(0, p, window).commit();
QQuickTouchUtils::flush(window);