diff options
Diffstat (limited to 'tests/auto/gui')
-rw-r--r-- | tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index db5e83e2c7..13dc924f93 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -204,6 +204,7 @@ private slots: void basicRawEventTranslationOfIds(); void multiPointRawEventTranslationOnTouchScreen(); void multiPointRawEventTranslationOnTouchPad(); + void touchOnMultipleTouchscreens(); void deleteInEventHandler(); void deleteInRawEventTranslation(); void crashInQGraphicsSceneAfterNotHandlingTouchBegin(); @@ -213,11 +214,13 @@ private slots: private: QTouchDevice *touchScreenDevice; + QTouchDevice *secondaryTouchScreenDevice; QTouchDevice *touchPadDevice; }; tst_QTouchEvent::tst_QTouchEvent() : touchScreenDevice(QTest::createTouchDevice()) + , secondaryTouchScreenDevice(QTest::createTouchDevice()) , touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad)) { } @@ -225,6 +228,7 @@ tst_QTouchEvent::tst_QTouchEvent() void tst_QTouchEvent::cleanup() { QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); + QWindowSystemInterfacePrivate::clearPointIdMap(); } void tst_QTouchEvent::qPointerUniqueId() @@ -951,6 +955,157 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() } } +void tst_QTouchEvent::touchOnMultipleTouchscreens() +{ + tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QWindow *window = touchWidget.windowHandle(); + + QPointF pos = touchWidget.rect().center(); + QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); + QPointF delta(10, 10); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); + + QVector<QTouchEvent::TouchPoint> rawTouchPoints(3); + rawTouchPoints[0].setId(0); + rawTouchPoints[1].setId(10); + rawTouchPoints[2].setId(11); + + // this should be translated to a TouchBegin + rawTouchPoints[0].setState(Qt::TouchPointPressed); + rawTouchPoints[0].setScreenPos(screenPos); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + rawTouchPoints[0].setRawScreenPositions({{12, 34}, {56, 78}}); + ulong timestamp = 1234; + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(!touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first(); + const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1; + const int secTouchPointId = (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2; + QCOMPARE(touchBeginPoint.id(), touchPointId); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // press a point on secondaryTouchScreenDevice + touchWidget.seenTouchBegin = false; + rawTouchPoints[1].setState(Qt::TouchPointPressed); + rawTouchPoints[1].setScreenPos(screenPos); + rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); + rawTouchPoints[1].setRawScreenPositions({{90, 100}, {110, 120}}); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + touchBeginPoint = touchWidget.touchBeginPoints[0]; + QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[1].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // press another point on secondaryTouchScreenDevice + touchWidget.seenTouchBegin = false; + rawTouchPoints[2].setState(Qt::TouchPointPressed); + rawTouchPoints[2].setScreenPos(screenPos); + rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry)); + rawTouchPoints[2].setRawScreenPositions({{130, 140}, {150, 160}}); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + touchBeginPoint = touchWidget.touchBeginPoints[0]; + QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 3); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[2].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // moving the first point should translate to TouchUpdate + rawTouchPoints[0].setState(Qt::TouchPointMoved); + rawTouchPoints[0].setScreenPos(screenPos + delta); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 1); + QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first(); + QCOMPARE(touchUpdatePoint.id(), touchPointId); + QCOMPARE(touchUpdatePoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchUpdatePoint.pos(), pos + delta); + + // releasing the first point translates to TouchEnd + rawTouchPoints[0].setState(Qt::TouchPointReleased); + rawTouchPoints[0].setScreenPos(screenPos + delta + delta); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchEndPoints.count(), 1); + QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first(); + QCOMPARE(touchEndPoint.id(), touchPointId); + QCOMPARE(touchEndPoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchEndPoint.pos(), pos + delta + delta); + + // Widgets don't normally handle this case: if a TouchEnd was seen before, then + // WA_WState_AcceptedTouchBeginEvent will be false, and + // QApplicationPrivate::translateRawTouchEvent will ignore touch events that aren't TouchBegin. + // So we have to set it true. It _did_ in fact accept the touch begin from the secondary device, + // but it also got a TouchEnd from the primary device in the meantime. + touchWidget.setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, true); + + // Releasing one point on the secondary touchscreen does not yet generate TouchEnd. + touchWidget.seenTouchEnd = false; + touchWidget.touchEndPoints.clear(); + rawTouchPoints[1].setState(Qt::TouchPointReleased); + rawTouchPoints[2].setState(Qt::TouchPointStationary); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[1] << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints[0].id(), secTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints[1].id(), secTouchPointId + 1); + + // releasing the last point on the secondary touchscreen translates to TouchEnd + touchWidget.seenTouchEnd = false; + rawTouchPoints[2].setState(Qt::TouchPointReleased); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList<QTouchEvent::TouchPoint>() << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchEndPoints.count(), 1); + touchEndPoint = touchWidget.touchEndPoints.first(); + QCOMPARE(touchEndPoint.id(), secTouchPointId + 1); + QCOMPARE(touchEndPoint.state(), rawTouchPoints[2].state()); +} + void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { tst_QTouchEventWidget touchWidget; |