summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp')
-rw-r--r--tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp155
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;