File indexing completed on 2024-04-28 03:58:57
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2021 Steffen Hartleib <steffenhartleib@t-online.de> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include <ktwofingerswipe.h> 0009 0010 #include <QTest> 0011 #include <QSignalSpy> 0012 #include <QWidget> 0013 #include <QMainWindow> 0014 0015 class KTwoFingerSwipeTest : public QObject 0016 { 0017 Q_OBJECT 0018 0019 QPointingDevice *mDev = nullptr; 0020 0021 QMainWindow mMainWindow; 0022 QWidget mWidget; 0023 KTwoFingerSwipeRecognizer *mTwoFingerRec = nullptr; 0024 Qt::GestureType mKTwoFingerSwipeGesture; 0025 QPoint mTouchPointPos = QPoint(200, 200); 0026 QSignalSpy *mSpySwipeFinished = nullptr; 0027 QSignalSpy *mSpySwipeStarted = nullptr; 0028 QSignalSpy *mSpySwipeUpdated = nullptr; 0029 QSignalSpy *mSpySwipeCanceled = nullptr; 0030 qreal mAngel = 0.0; 0031 0032 Q_SIGNALS: 0033 void swipeStarted(KTwoFingerSwipe *); 0034 void swipeFinished(KTwoFingerSwipe *); 0035 void swipeUpdated(KTwoFingerSwipe *); 0036 void swipeCanceled(KTwoFingerSwipe *); 0037 0038 protected: 0039 bool eventFilter(QObject *watched, QEvent *e) override 0040 { 0041 if (e->type() == QEvent::Gesture) { 0042 QGestureEvent *gEvent = static_cast<QGestureEvent *>(e); 0043 KTwoFingerSwipe *swipe = static_cast<KTwoFingerSwipe *>(gEvent->gesture(mKTwoFingerSwipeGesture)); 0044 if (swipe) { 0045 const Qt::GestureState state = swipe->state(); 0046 if (state == Qt::GestureFinished) { 0047 Q_EMIT swipeFinished(swipe); 0048 } else if (state == Qt::GestureStarted) { 0049 Q_EMIT swipeStarted(swipe); 0050 } else if (state == Qt::GestureUpdated) { 0051 Q_EMIT swipeUpdated(swipe); 0052 } else if (state == Qt::GestureCanceled) { 0053 Q_EMIT swipeCanceled(swipe); 0054 } 0055 } 0056 e->accept(); 0057 return true; 0058 } 0059 return QObject::eventFilter(watched, e); 0060 } 0061 0062 protected Q_SLOTS: 0063 void slotSwipeFinished (KTwoFingerSwipe *swipe) 0064 { 0065 compareGesturePositions(swipe); 0066 } 0067 void slotSwipeStarted (KTwoFingerSwipe *swipe) 0068 { 0069 compareGesturePositions(swipe); 0070 } 0071 void slotSwipeUpdated (KTwoFingerSwipe *swipe) 0072 { 0073 compareGesturePositions(swipe); 0074 } 0075 void slotSwipeCanceled (KTwoFingerSwipe *swipe) 0076 { 0077 compareGesturePositions(swipe); 0078 } 0079 private: 0080 void compareGesturePositions(KTwoFingerSwipe *swipe) 0081 { 0082 QCOMPARE(swipe->pos(), mTouchPointPos); 0083 QCOMPARE(swipe->screenPos(), mWidget.mapToGlobal(mTouchPointPos)); 0084 QCOMPARE(swipe->hotSpot(), mWidget.mapToGlobal(mTouchPointPos)); 0085 QCOMPARE(swipe->scenePos(), mWidget.mapToGlobal(mTouchPointPos)); 0086 QVERIFY(swipe->hasHotSpot()); 0087 mAngel = swipe->swipeAngle(); 0088 } 0089 0090 void clearSignalSpys() 0091 { 0092 mSpySwipeFinished->clear(); 0093 mSpySwipeCanceled->clear(); 0094 mSpySwipeUpdated->clear(); 0095 mSpySwipeStarted->clear(); 0096 } 0097 0098 private Q_SLOTS: 0099 void cleanupTestCase() 0100 { 0101 delete mSpySwipeFinished; 0102 delete mSpySwipeCanceled; 0103 delete mSpySwipeUpdated; 0104 delete mSpySwipeStarted; 0105 } 0106 void initTestCase() 0107 { 0108 mDev = QTest::createTouchDevice(); 0109 0110 mMainWindow.setGeometry(0, 0, 500, 500); 0111 mMainWindow.setCentralWidget(&mWidget); 0112 mMainWindow.show(); 0113 0114 mWidget.installEventFilter(this); 0115 mWidget.setAttribute(Qt::WA_AcceptTouchEvents); 0116 0117 QVERIFY(QTest::qWaitForWindowActive(&mMainWindow)); 0118 QVERIFY(QTest::qWaitForWindowActive(&mWidget)); 0119 0120 mTwoFingerRec = new KTwoFingerSwipeRecognizer(); 0121 QVERIFY(mTwoFingerRec); 0122 0123 mKTwoFingerSwipeGesture = QGestureRecognizer::registerRecognizer(mTwoFingerRec); 0124 QVERIFY(mKTwoFingerSwipeGesture & Qt::CustomGesture); 0125 0126 mWidget.grabGesture(mKTwoFingerSwipeGesture); 0127 0128 connect(this, &KTwoFingerSwipeTest::swipeFinished, this, &KTwoFingerSwipeTest::slotSwipeFinished); 0129 connect(this, &KTwoFingerSwipeTest::swipeStarted, this, &KTwoFingerSwipeTest::slotSwipeStarted); 0130 connect(this, &KTwoFingerSwipeTest::swipeUpdated, this, &KTwoFingerSwipeTest::slotSwipeUpdated); 0131 connect(this, &KTwoFingerSwipeTest::swipeCanceled, this, &KTwoFingerSwipeTest::slotSwipeCanceled); 0132 0133 mSpySwipeFinished = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeFinished); 0134 QVERIFY(mSpySwipeFinished->isValid()); 0135 0136 mSpySwipeStarted = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeStarted); 0137 QVERIFY(mSpySwipeStarted->isValid()); 0138 0139 mSpySwipeUpdated = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeUpdated); 0140 QVERIFY(mSpySwipeUpdated->isValid()); 0141 0142 mSpySwipeCanceled = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeCanceled); 0143 QVERIFY(mSpySwipeCanceled->isValid()); 0144 0145 QTest::qWait(1000); 0146 } 0147 0148 void testChangeTimeAndDistance() 0149 { 0150 QVERIFY(mTwoFingerRec->maxSwipeTime() >= 0); 0151 mTwoFingerRec->setMaxSwipeTime(10); 0152 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 10); 0153 mTwoFingerRec->setMaxSwipeTime(-10); 0154 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 0); 0155 mTwoFingerRec->setMaxSwipeTime(90); 0156 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 90); 0157 0158 QVERIFY(mTwoFingerRec->minSswipeDistance() >= 0); 0159 mTwoFingerRec->setSwipeDistance(10); 0160 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 10); 0161 mTwoFingerRec->setSwipeDistance(-10); 0162 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 0); 0163 mTwoFingerRec->setSwipeDistance(30); 0164 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 30); 0165 } 0166 0167 void testSuccessfulGesture_right() 0168 { 0169 clearSignalSpys(); 0170 0171 const int length = mTwoFingerRec->minSswipeDistance(); 0172 const QPoint swipeDistance = QPoint(length, 0); 0173 0174 QTest::touchEvent(&mWidget, mDev) 0175 .press(0, mTouchPointPos, (QWidget *) nullptr) 0176 .press(1, mTouchPointPos, (QWidget *) nullptr); 0177 0178 QTest::touchEvent(&mWidget, mDev) 0179 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0180 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0181 0182 0183 QTest::touchEvent(&mWidget, mDev) 0184 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0185 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0186 0187 QTest::touchEvent(&mWidget, mDev) 0188 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0189 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0190 0191 QTest::touchEvent(&mWidget, mDev) 0192 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0193 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0194 0195 if (mSpySwipeStarted->count() == 0) { 0196 QVERIFY(mSpySwipeStarted->wait(1000)); 0197 } 0198 0199 QCOMPARE(mSpySwipeStarted->count(), 1); 0200 QCOMPARE(mSpySwipeFinished->count(), 1); 0201 QCOMPARE(mSpySwipeCanceled->count(), 0); 0202 QVERIFY(mSpySwipeUpdated->count() > 0); 0203 QCOMPARE(mAngel, 0); 0204 } 0205 0206 void testSuccessfulGesture_left() 0207 { 0208 clearSignalSpys(); 0209 0210 const int length = mTwoFingerRec->minSswipeDistance(); 0211 const QPoint swipeDistance = QPoint(-length, 0); 0212 0213 QTest::touchEvent(&mWidget, mDev) 0214 .press(0, mTouchPointPos, (QWidget *) nullptr) 0215 .press(1, mTouchPointPos, (QWidget *) nullptr); 0216 0217 QTest::touchEvent(&mWidget, mDev) 0218 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0219 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0220 0221 0222 QTest::touchEvent(&mWidget, mDev) 0223 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0224 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0225 0226 QTest::touchEvent(&mWidget, mDev) 0227 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0228 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0229 0230 QTest::touchEvent(&mWidget, mDev) 0231 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0232 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0233 0234 if (mSpySwipeStarted->count() == 0) { 0235 QVERIFY(mSpySwipeStarted->wait(1000)); 0236 } 0237 0238 QCOMPARE(mSpySwipeStarted->count(), 1); 0239 QCOMPARE(mSpySwipeFinished->count(), 1); 0240 QCOMPARE(mSpySwipeCanceled->count(), 0); 0241 QVERIFY(mSpySwipeUpdated->count() > 0); 0242 QCOMPARE(mAngel, 180); 0243 } 0244 0245 void testSuccessfulGesture_up() 0246 { 0247 clearSignalSpys(); 0248 0249 const int length = mTwoFingerRec->minSswipeDistance(); 0250 const QPoint swipeDistance = QPoint(0, -length); 0251 0252 QTest::touchEvent(&mWidget, mDev) 0253 .press(0, mTouchPointPos, (QWidget *) nullptr) 0254 .press(1, mTouchPointPos, (QWidget *) nullptr); 0255 0256 QTest::touchEvent(&mWidget, mDev) 0257 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0258 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0259 0260 0261 QTest::touchEvent(&mWidget, mDev) 0262 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0263 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0264 0265 QTest::touchEvent(&mWidget, mDev) 0266 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0267 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0268 0269 QTest::touchEvent(&mWidget, mDev) 0270 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0271 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0272 0273 if (mSpySwipeStarted->count() == 0) { 0274 QVERIFY(mSpySwipeStarted->wait(1000)); 0275 } 0276 0277 QCOMPARE(mSpySwipeStarted->count(), 1); 0278 QCOMPARE(mSpySwipeFinished->count(), 1); 0279 QCOMPARE(mSpySwipeCanceled->count(), 0); 0280 QVERIFY(mSpySwipeUpdated->count() > 0); 0281 QCOMPARE(mAngel, 90); 0282 } 0283 0284 void testSuccessfulGesture_down() 0285 { 0286 clearSignalSpys(); 0287 0288 const int length = mTwoFingerRec->minSswipeDistance(); 0289 const QPoint swipeDistance = QPoint(0, length); 0290 0291 QTest::touchEvent(&mWidget, mDev) 0292 .press(0, mTouchPointPos, (QWidget *) nullptr) 0293 .press(1, mTouchPointPos, (QWidget *) nullptr); 0294 0295 QTest::touchEvent(&mWidget, mDev) 0296 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0297 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0298 0299 0300 QTest::touchEvent(&mWidget, mDev) 0301 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0302 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0303 0304 QTest::touchEvent(&mWidget, mDev) 0305 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0306 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0307 0308 QTest::touchEvent(&mWidget, mDev) 0309 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0310 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0311 0312 if (mSpySwipeStarted->count() == 0) { 0313 QVERIFY(mSpySwipeStarted->wait(1000)); 0314 } 0315 0316 QCOMPARE(mSpySwipeStarted->count(), 1); 0317 QCOMPARE(mSpySwipeFinished->count(), 1); 0318 QCOMPARE(mSpySwipeCanceled->count(), 0); 0319 QVERIFY(mSpySwipeUpdated->count() > 0); 0320 QCOMPARE(mAngel, 270); 0321 } 0322 0323 void testFailingGesture_toSlow() 0324 { 0325 clearSignalSpys(); 0326 0327 const int length = mTwoFingerRec->minSswipeDistance() / 3; 0328 const QPoint swipeDistance = QPoint(length, 0); 0329 0330 QTest::touchEvent(&mWidget, mDev) 0331 .press(0, mTouchPointPos, (QWidget *) nullptr) 0332 .press(1, mTouchPointPos, (QWidget *) nullptr); 0333 0334 QTest::touchEvent(&mWidget, mDev) 0335 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0336 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0337 0338 0339 QTest::touchEvent(&mWidget, mDev) 0340 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0341 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0342 0343 QTest::touchEvent(&mWidget, mDev) 0344 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0345 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0346 0347 QTest::touchEvent(&mWidget, mDev) 0348 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0349 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0350 0351 if (mSpySwipeStarted->count() == 0) { 0352 QVERIFY(mSpySwipeStarted->wait(1000)); 0353 } 0354 0355 QCOMPARE(mSpySwipeStarted->count(), 1); 0356 QCOMPARE(mSpySwipeFinished->count(), 0); 0357 QCOMPARE(mSpySwipeCanceled->count(), 1); 0358 QVERIFY(mSpySwipeUpdated->count() > 0); 0359 QCOMPARE(mAngel, 0); 0360 } 0361 0362 0363 void testFailingGesture_threeFingers() 0364 { 0365 clearSignalSpys(); 0366 0367 const int length = mTwoFingerRec->minSswipeDistance(); 0368 const QPoint swipeDistance = QPoint(length, 0); 0369 0370 QTest::touchEvent(&mWidget, mDev) 0371 .press(0, mTouchPointPos, (QWidget *) nullptr) 0372 .press(1, mTouchPointPos, (QWidget *) nullptr); 0373 0374 QTest::touchEvent(&mWidget, mDev) 0375 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0376 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0377 0378 QTest::touchEvent(&mWidget, mDev) 0379 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0380 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0381 .press(2, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0382 0383 QTest::touchEvent(&mWidget, mDev) 0384 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0385 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0386 .move(2, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0387 0388 QTest::touchEvent(&mWidget, mDev) 0389 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0390 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0391 .release(2, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0392 0393 if (mSpySwipeCanceled->count() == 0) { 0394 QVERIFY(mSpySwipeCanceled->wait(1000)); 0395 } 0396 0397 QCOMPARE(mSpySwipeStarted->count(), 1); 0398 QCOMPARE(mSpySwipeFinished->count(), 0); 0399 QCOMPARE(mSpySwipeCanceled->count(), 1); 0400 QVERIFY(mSpySwipeUpdated->count() >= 0); 0401 QCOMPARE(mAngel, 0); 0402 } 0403 0404 void testFailingGesture_oneFinger() 0405 { 0406 clearSignalSpys(); 0407 0408 const int length = mTwoFingerRec->minSswipeDistance(); 0409 const QPoint swipeDistance = QPoint(length, 0); 0410 0411 QTest::touchEvent(&mWidget, mDev) 0412 .press(0, mTouchPointPos, (QWidget *) nullptr); 0413 0414 QTest::touchEvent(&mWidget, mDev) 0415 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0416 0417 QTest::touchEvent(&mWidget, mDev) 0418 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0419 0420 QTest::touchEvent(&mWidget, mDev) 0421 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0422 0423 QTest::touchEvent(&mWidget, mDev) 0424 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0425 0426 QCOMPARE(mSpySwipeStarted->count(), 0); 0427 QCOMPARE(mSpySwipeFinished->count(), 0); 0428 QCOMPARE(mSpySwipeCanceled->count(), 0); 0429 QVERIFY(mSpySwipeUpdated->count() == 0); 0430 } 0431 0432 void testSomeRandomSwipes() 0433 { 0434 for (int i = 0; i < 50; ++i) { 0435 const int x = rand() % 200 + 150; 0436 const int y = rand() % 200 + 150; 0437 mTouchPointPos = QPoint(x, y); 0438 testSuccessfulGesture_right(); 0439 testSuccessfulGesture_up(); 0440 } 0441 } 0442 }; 0443 0444 QTEST_MAIN(KTwoFingerSwipeTest) 0445 0446 #include "ktwofingerswipetest.moc"