From 3bdb3c1d8a581906f49cd4dc89d55c04d9159f40 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 2 Oct 2018 09:34:05 +0200 Subject: Amend TouchMouse::buttonOnDelayedPressFlickable to test delayed tap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test is for Flickable with pressDelay set to a testable timeout value. For some reason it only checked trying to flick before the press delay is over, or holding and waiting for the press delay to expire. But if the user taps a child MouseArea before the press delay expires (neither moving nor waiting), at the moment of release it's supposed to send the delayed press and then the release, so that the MouseArea gets "clicked" almost as if there was no delay. Lack of test coverage allowed a regression in this functionality for 2 minor versions: 5.10 and 5.11. Task-number: QTBUG-61144 Task-number: QTBUG-69059 Change-Id: I0d8867587e6877359c41ec5fc3a5cdd17447d0b8 Reviewed-by: Jan Arve Sæther --- tests/auto/quick/touchmouse/tst_touchmouse.cpp | 104 ++++++++++++++++--------- 1 file changed, 66 insertions(+), 38 deletions(-) diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index a69cd5bc34..dc319ba28c 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -28,6 +28,7 @@ #include +#include #include #include @@ -47,6 +48,8 @@ #include "../../shared/util.h" #include "../shared/viewtestutil.h" +Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") + struct Event { Event(QEvent::Type t, QPoint mouse, QPoint global) @@ -683,14 +686,18 @@ void tst_TouchMouse::touchButtonOnFlickable() void tst_TouchMouse::buttonOnDelayedPressFlickable_data() { QTest::addColumn("scrollBeforeDelayIsOver"); + QTest::addColumn("releaseBeforeDelayIsOver"); // the item should never see the event, // due to the pressDelay which never delivers if we start moving - QTest::newRow("scroll before press delay is over") << true; + QTest::newRow("scroll before press delay is over") << true << false; + + // after release, the item should see the press and release via event replay (QTBUG-61144) + QTest::newRow("release before press delay is over") << false << true; // wait until the "button" sees the press but then // start moving: the button gets a press and cancel event - QTest::newRow("scroll after press delay is over") << false; + QTest::newRow("scroll after press delay is over") << false << false; } void tst_TouchMouse::buttonOnDelayedPressFlickable() @@ -699,6 +706,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() // - eventItem1 y: 100, height 100 // - eventItem2 y: 300, height 100 QFETCH(bool, scrollBeforeDelayIsOver); + QFETCH(bool, releaseBeforeDelayIsOver); qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); filteredEventList.clear(); @@ -737,11 +745,12 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() // touch press QPoint p1 = QPoint(10, 110); + QPoint pEnd = p1; QTest::touchEvent(window.data(), device).press(0, p1, window.data()); QQuickTouchUtils::flush(window.data()); - if (scrollBeforeDelayIsOver) { - // no events, the flickable got scrolled, the button sees nothing + if (scrollBeforeDelayIsOver || releaseBeforeDelayIsOver) { + // no events yet: press is delayed QCOMPARE(eventItem1->eventList.size(), 0); } else { // wait until the button sees the press @@ -750,45 +759,64 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QCOMPARE(filteredEventList.count(), 1); } - p1 += QPoint(0, -10); - QPoint p2 = p1 + QPoint(0, -10); - QPoint p3 = p2 + QPoint(0, -10); - QQuickTouchUtils::flush(window.data()); - QTest::touchEvent(window.data(), device).move(0, p1, window.data()); - QQuickTouchUtils::flush(window.data()); - QTest::touchEvent(window.data(), device).move(0, p2, window.data()); - QQuickTouchUtils::flush(window.data()); - QTest::touchEvent(window.data(), device).move(0, p3, window.data()); - QQuickTouchUtils::flush(window.data()); - QTRY_VERIFY(flickable->isMovingVertically()); + if (!releaseBeforeDelayIsOver) { + // move the touchpoint: try to flick + p1 += QPoint(0, -10); + QPoint p2 = p1 + QPoint(0, -10); + pEnd = p2 + QPoint(0, -10); + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, p1, window.data()); + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, p2, window.data()); + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, pEnd, window.data()); + QQuickTouchUtils::flush(window.data()); + QTRY_VERIFY(flickable->isMovingVertically()); + + if (scrollBeforeDelayIsOver) { + QCOMPARE(eventItem1->eventList.size(), 0); + QCOMPARE(filteredEventList.count(), 0); + } else { + // see at least press, move and ungrab + QTRY_VERIFY(eventItem1->eventList.size() > 2); + QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress); + QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse); + QCOMPARE(filteredEventList.count(), 1); + } - if (scrollBeforeDelayIsOver) { - QCOMPARE(eventItem1->eventList.size(), 0); - QCOMPARE(filteredEventList.count(), 0); - } else { - // see at least press, move and ungrab - QTRY_VERIFY(eventItem1->eventList.size() > 2); - QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress); - QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse); - QCOMPARE(filteredEventList.count(), 1); + // flickable should have the mouse grab, and have moved the itemForTouchPointId + // for the touchMouseId to the new grabber. + QCOMPARE(window->mouseGrabberItem(), flickable); + QVERIFY(windowPriv->touchMouseId != -1); + auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0)); + QCOMPARE(pointerEvent->point(0)->grabberItem(), flickable); } - // flickable should have the mouse grab, and have moved the itemForTouchPointId - // for the touchMouseId to the new grabber. - QCOMPARE(window->mouseGrabberItem(), flickable); - QVERIFY(windowPriv->touchMouseId != -1); - auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0)); - QCOMPARE(pointerEvent->point(0)->grabberItem(), flickable); - - QTest::touchEvent(window.data(), device).release(0, p3, window.data()); + QTest::touchEvent(window.data(), device).release(0, pEnd, window.data()); QQuickTouchUtils::flush(window.data()); - // We should not have received any synthesised mouse events from Qt gui, - // just the delayed press. - if (scrollBeforeDelayIsOver) - QCOMPARE(filteredEventList.count(), 0); - else - QCOMPARE(filteredEventList.count(), 1); + if (releaseBeforeDelayIsOver) { + // when the touchpoint was released, the child saw the delayed press and the release in sequence + qCDebug(lcTests) << "expected delivered events: press, release, ungrab" << eventItem1->eventList; + qCDebug(lcTests) << "expected filtered events: delayed press, release" << filteredEventList; + QTRY_COMPARE(eventItem1->eventList.size(), 3); + QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress); + QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonRelease); + QCOMPARE(eventItem1->eventList.last().type, QEvent::UngrabMouse); + // QQuickWindow filters the delayed press and release + QCOMPARE(filteredEventList.count(), 2); + QCOMPARE(filteredEventList.at(0).type, QEvent::MouseButtonPress); + QCOMPARE(filteredEventList.at(1).type, QEvent::MouseButtonRelease); + } else { + // QQuickWindow filters the delayed press if there was one; otherwise nothing + if (scrollBeforeDelayIsOver) { + QCOMPARE(filteredEventList.count(), 0); + } else { + qCDebug(lcTests) << "expected filtered event: delayed press" << filteredEventList; + QCOMPARE(filteredEventList.count(), 1); + QCOMPARE(filteredEventList.at(0).type, QEvent::MouseButtonPress); + } + } } void tst_TouchMouse::buttonOnTouch() -- cgit v1.2.3