File indexing completed on 2024-11-10 04:56:09
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "kwin_wayland_test.h" 0010 0011 #include "core/output.h" 0012 #include "keyboard_input.h" 0013 #include "pointer_input.h" 0014 #include "wayland_server.h" 0015 #include "window.h" 0016 #include "workspace.h" 0017 0018 #include <KWayland/Client/compositor.h> 0019 #include <KWayland/Client/keyboard.h> 0020 #include <KWayland/Client/pointer.h> 0021 #include <KWayland/Client/seat.h> 0022 #include <KWayland/Client/shm_pool.h> 0023 #include <KWayland/Client/surface.h> 0024 #include <KWayland/Client/touch.h> 0025 0026 #include <linux/input.h> 0027 0028 using namespace KWin; 0029 0030 static const QString s_socketName = QStringLiteral("wayland_test_kwin_window_selection-0"); 0031 0032 class TestWindowSelection : public QObject 0033 { 0034 Q_OBJECT 0035 private Q_SLOTS: 0036 void initTestCase(); 0037 void init(); 0038 void cleanup(); 0039 0040 void testSelectOnWindowPointer(); 0041 void testSelectOnWindowKeyboard_data(); 0042 void testSelectOnWindowKeyboard(); 0043 void testSelectOnWindowTouch(); 0044 void testCancelOnWindowPointer(); 0045 void testCancelOnWindowKeyboard(); 0046 0047 void testSelectPointPointer(); 0048 void testSelectPointTouch(); 0049 }; 0050 0051 void TestWindowSelection::initTestCase() 0052 { 0053 qRegisterMetaType<KWin::Window *>(); 0054 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0055 QVERIFY(waylandServer()->init(s_socketName)); 0056 Test::setOutputConfig({ 0057 QRect(0, 0, 1280, 1024), 0058 QRect(1280, 0, 1280, 1024), 0059 }); 0060 qputenv("XKB_DEFAULT_RULES", "evdev"); 0061 0062 kwinApp()->start(); 0063 QVERIFY(applicationStartedSpy.wait()); 0064 const auto outputs = workspace()->outputs(); 0065 QCOMPARE(outputs.count(), 2); 0066 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024)); 0067 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024)); 0068 } 0069 0070 void TestWindowSelection::init() 0071 { 0072 QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); 0073 QVERIFY(Test::waitForWaylandPointer()); 0074 0075 workspace()->setActiveOutput(QPoint(640, 512)); 0076 KWin::input()->pointer()->warp(QPoint(640, 512)); 0077 } 0078 0079 void TestWindowSelection::cleanup() 0080 { 0081 Test::destroyWaylandConnection(); 0082 } 0083 0084 void TestWindowSelection::testSelectOnWindowPointer() 0085 { 0086 // this test verifies window selection through pointer works 0087 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0088 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0089 std::unique_ptr<KWayland::Client::Pointer> pointer(Test::waylandSeat()->createPointer()); 0090 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0091 QSignalSpy pointerEnteredSpy(pointer.get(), &KWayland::Client::Pointer::entered); 0092 QSignalSpy pointerLeftSpy(pointer.get(), &KWayland::Client::Pointer::left); 0093 QSignalSpy keyboardEnteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered); 0094 QSignalSpy keyboardLeftSpy(keyboard.get(), &KWayland::Client::Keyboard::left); 0095 0096 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0097 QVERIFY(window); 0098 QVERIFY(keyboardEnteredSpy.wait()); 0099 KWin::input()->pointer()->warp(window->frameGeometry().center()); 0100 QCOMPARE(input()->pointer()->focus(), window); 0101 QVERIFY(pointerEnteredSpy.wait()); 0102 0103 Window *selectedWindow = nullptr; 0104 auto callback = [&selectedWindow](Window *t) { 0105 selectedWindow = t; 0106 }; 0107 0108 // start the interaction 0109 QCOMPARE(input()->isSelectingWindow(), false); 0110 kwinApp()->startInteractiveWindowSelection(callback); 0111 QCOMPARE(input()->isSelectingWindow(), true); 0112 QVERIFY(!selectedWindow); 0113 QCOMPARE(keyboardLeftSpy.count(), 0); 0114 QVERIFY(pointerLeftSpy.wait()); 0115 if (keyboardLeftSpy.isEmpty()) { 0116 QVERIFY(keyboardLeftSpy.wait()); 0117 } 0118 QCOMPARE(pointerLeftSpy.count(), 1); 0119 QCOMPARE(keyboardLeftSpy.count(), 1); 0120 0121 // simulate left button press 0122 quint32 timestamp = 0; 0123 Test::pointerButtonPressed(BTN_LEFT, timestamp++); 0124 // should not have ended the mode 0125 QCOMPARE(input()->isSelectingWindow(), true); 0126 QVERIFY(!selectedWindow); 0127 QVERIFY(!input()->pointer()->focus()); 0128 0129 // updating the pointer should not change anything 0130 input()->pointer()->update(); 0131 QVERIFY(!input()->pointer()->focus()); 0132 // updating keyboard should also not change 0133 input()->keyboard()->update(); 0134 0135 // perform a right button click 0136 Test::pointerButtonPressed(BTN_RIGHT, timestamp++); 0137 Test::pointerButtonReleased(BTN_RIGHT, timestamp++); 0138 // should not have ended the mode 0139 QCOMPARE(input()->isSelectingWindow(), true); 0140 QVERIFY(!selectedWindow); 0141 // now release 0142 Test::pointerButtonReleased(BTN_LEFT, timestamp++); 0143 QCOMPARE(input()->isSelectingWindow(), false); 0144 QCOMPARE(selectedWindow, window); 0145 QCOMPARE(input()->pointer()->focus(), window); 0146 // should give back keyboard and pointer 0147 QVERIFY(pointerEnteredSpy.wait()); 0148 if (keyboardEnteredSpy.count() != 2) { 0149 QVERIFY(keyboardEnteredSpy.wait()); 0150 } 0151 QCOMPARE(pointerLeftSpy.count(), 1); 0152 QCOMPARE(keyboardLeftSpy.count(), 1); 0153 QCOMPARE(pointerEnteredSpy.count(), 2); 0154 QCOMPARE(keyboardEnteredSpy.count(), 2); 0155 } 0156 0157 void TestWindowSelection::testSelectOnWindowKeyboard_data() 0158 { 0159 QTest::addColumn<qint32>("key"); 0160 0161 QTest::newRow("enter") << KEY_ENTER; 0162 QTest::newRow("keypad enter") << KEY_KPENTER; 0163 QTest::newRow("space") << KEY_SPACE; 0164 } 0165 0166 void TestWindowSelection::testSelectOnWindowKeyboard() 0167 { 0168 // this test verifies window selection through keyboard key 0169 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0170 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0171 std::unique_ptr<KWayland::Client::Pointer> pointer(Test::waylandSeat()->createPointer()); 0172 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0173 QSignalSpy pointerEnteredSpy(pointer.get(), &KWayland::Client::Pointer::entered); 0174 QSignalSpy pointerLeftSpy(pointer.get(), &KWayland::Client::Pointer::left); 0175 QSignalSpy keyboardEnteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered); 0176 QSignalSpy keyboardLeftSpy(keyboard.get(), &KWayland::Client::Keyboard::left); 0177 0178 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0179 QVERIFY(window); 0180 QVERIFY(keyboardEnteredSpy.wait()); 0181 QVERIFY(!exclusiveContains(window->frameGeometry(), KWin::Cursors::self()->mouse()->pos())); 0182 0183 Window *selectedWindow = nullptr; 0184 auto callback = [&selectedWindow](Window *t) { 0185 selectedWindow = t; 0186 }; 0187 0188 // start the interaction 0189 QCOMPARE(input()->isSelectingWindow(), false); 0190 kwinApp()->startInteractiveWindowSelection(callback); 0191 QCOMPARE(input()->isSelectingWindow(), true); 0192 QVERIFY(!selectedWindow); 0193 QCOMPARE(keyboardLeftSpy.count(), 0); 0194 QVERIFY(keyboardLeftSpy.wait()); 0195 QCOMPARE(pointerLeftSpy.count(), 0); 0196 QCOMPARE(keyboardLeftSpy.count(), 1); 0197 0198 // simulate key press 0199 quint32 timestamp = 0; 0200 // move cursor through keys 0201 auto keyPress = [×tamp](qint32 key) { 0202 Test::keyboardKeyPressed(key, timestamp++); 0203 Test::keyboardKeyReleased(key, timestamp++); 0204 }; 0205 while (KWin::Cursors::self()->mouse()->pos().x() >= window->frameGeometry().x() + window->frameGeometry().width()) { 0206 keyPress(KEY_LEFT); 0207 } 0208 while (KWin::Cursors::self()->mouse()->pos().x() <= window->frameGeometry().x()) { 0209 keyPress(KEY_RIGHT); 0210 } 0211 while (KWin::Cursors::self()->mouse()->pos().y() <= window->frameGeometry().y()) { 0212 keyPress(KEY_DOWN); 0213 } 0214 while (KWin::Cursors::self()->mouse()->pos().y() >= window->frameGeometry().y() + window->frameGeometry().height()) { 0215 keyPress(KEY_UP); 0216 } 0217 QFETCH(qint32, key); 0218 Test::keyboardKeyPressed(key, timestamp++); 0219 QCOMPARE(input()->isSelectingWindow(), false); 0220 QCOMPARE(selectedWindow, window); 0221 QCOMPARE(input()->pointer()->focus(), window); 0222 // should give back keyboard and pointer 0223 QVERIFY(pointerEnteredSpy.wait()); 0224 if (keyboardEnteredSpy.count() != 2) { 0225 QVERIFY(keyboardEnteredSpy.wait()); 0226 } 0227 QCOMPARE(pointerLeftSpy.count(), 0); 0228 QCOMPARE(keyboardLeftSpy.count(), 1); 0229 QCOMPARE(pointerEnteredSpy.count(), 1); 0230 QCOMPARE(keyboardEnteredSpy.count(), 2); 0231 Test::keyboardKeyReleased(key, timestamp++); 0232 } 0233 0234 void TestWindowSelection::testSelectOnWindowTouch() 0235 { 0236 // this test verifies window selection through touch 0237 std::unique_ptr<KWayland::Client::Touch> touch(Test::waylandSeat()->createTouch()); 0238 QSignalSpy touchStartedSpy(touch.get(), &KWayland::Client::Touch::sequenceStarted); 0239 QSignalSpy touchCanceledSpy(touch.get(), &KWayland::Client::Touch::sequenceCanceled); 0240 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0241 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0242 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0243 QVERIFY(window); 0244 0245 Window *selectedWindow = nullptr; 0246 auto callback = [&selectedWindow](Window *t) { 0247 selectedWindow = t; 0248 }; 0249 0250 // start the interaction 0251 QCOMPARE(input()->isSelectingWindow(), false); 0252 kwinApp()->startInteractiveWindowSelection(callback); 0253 QCOMPARE(input()->isSelectingWindow(), true); 0254 QVERIFY(!selectedWindow); 0255 0256 // simulate touch down 0257 quint32 timestamp = 0; 0258 Test::touchDown(0, window->frameGeometry().center(), timestamp++); 0259 QVERIFY(!selectedWindow); 0260 Test::touchUp(0, timestamp++); 0261 QCOMPARE(input()->isSelectingWindow(), false); 0262 QCOMPARE(selectedWindow, window); 0263 0264 // with movement 0265 selectedWindow = nullptr; 0266 kwinApp()->startInteractiveWindowSelection(callback); 0267 Test::touchDown(0, window->frameGeometry().bottomRight() + QPoint(20, 20), timestamp++); 0268 QVERIFY(!selectedWindow); 0269 Test::touchMotion(0, window->frameGeometry().bottomRight() - QPoint(1, 1), timestamp++); 0270 QVERIFY(!selectedWindow); 0271 Test::touchUp(0, timestamp++); 0272 QCOMPARE(selectedWindow, window); 0273 QCOMPARE(input()->isSelectingWindow(), false); 0274 0275 // it cancels active touch sequence on the window 0276 Test::touchDown(0, window->frameGeometry().center(), timestamp++); 0277 QVERIFY(touchStartedSpy.wait()); 0278 selectedWindow = nullptr; 0279 kwinApp()->startInteractiveWindowSelection(callback); 0280 QCOMPARE(input()->isSelectingWindow(), true); 0281 QVERIFY(touchCanceledSpy.wait()); 0282 QVERIFY(!selectedWindow); 0283 // this touch up does not yet select the window, it was started prior to the selection 0284 Test::touchUp(0, timestamp++); 0285 QVERIFY(!selectedWindow); 0286 Test::touchDown(0, window->frameGeometry().center(), timestamp++); 0287 Test::touchUp(0, timestamp++); 0288 QCOMPARE(selectedWindow, window); 0289 QCOMPARE(input()->isSelectingWindow(), false); 0290 0291 QCOMPARE(touchStartedSpy.count(), 1); 0292 QCOMPARE(touchCanceledSpy.count(), 1); 0293 } 0294 0295 void TestWindowSelection::testCancelOnWindowPointer() 0296 { 0297 // this test verifies that window selection cancels through right button click 0298 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0299 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0300 std::unique_ptr<KWayland::Client::Pointer> pointer(Test::waylandSeat()->createPointer()); 0301 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0302 QSignalSpy pointerEnteredSpy(pointer.get(), &KWayland::Client::Pointer::entered); 0303 QSignalSpy pointerLeftSpy(pointer.get(), &KWayland::Client::Pointer::left); 0304 QSignalSpy keyboardEnteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered); 0305 QSignalSpy keyboardLeftSpy(keyboard.get(), &KWayland::Client::Keyboard::left); 0306 0307 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0308 QVERIFY(window); 0309 QVERIFY(keyboardEnteredSpy.wait()); 0310 KWin::input()->pointer()->warp(window->frameGeometry().center()); 0311 QCOMPARE(input()->pointer()->focus(), window); 0312 QVERIFY(pointerEnteredSpy.wait()); 0313 0314 Window *selectedWindow = nullptr; 0315 auto callback = [&selectedWindow](Window *t) { 0316 selectedWindow = t; 0317 }; 0318 0319 // start the interaction 0320 QCOMPARE(input()->isSelectingWindow(), false); 0321 kwinApp()->startInteractiveWindowSelection(callback); 0322 QCOMPARE(input()->isSelectingWindow(), true); 0323 QVERIFY(!selectedWindow); 0324 QCOMPARE(keyboardLeftSpy.count(), 0); 0325 QVERIFY(pointerLeftSpy.wait()); 0326 if (keyboardLeftSpy.isEmpty()) { 0327 QVERIFY(keyboardLeftSpy.wait()); 0328 } 0329 QCOMPARE(pointerLeftSpy.count(), 1); 0330 QCOMPARE(keyboardLeftSpy.count(), 1); 0331 0332 // simulate left button press 0333 quint32 timestamp = 0; 0334 Test::pointerButtonPressed(BTN_RIGHT, timestamp++); 0335 Test::pointerButtonReleased(BTN_RIGHT, timestamp++); 0336 QCOMPARE(input()->isSelectingWindow(), false); 0337 QVERIFY(!selectedWindow); 0338 QCOMPARE(input()->pointer()->focus(), window); 0339 // should give back keyboard and pointer 0340 QVERIFY(pointerEnteredSpy.wait()); 0341 if (keyboardEnteredSpy.count() != 2) { 0342 QVERIFY(keyboardEnteredSpy.wait()); 0343 } 0344 QCOMPARE(pointerLeftSpy.count(), 1); 0345 QCOMPARE(keyboardLeftSpy.count(), 1); 0346 QCOMPARE(pointerEnteredSpy.count(), 2); 0347 QCOMPARE(keyboardEnteredSpy.count(), 2); 0348 } 0349 0350 void TestWindowSelection::testCancelOnWindowKeyboard() 0351 { 0352 // this test verifies that cancel window selection through escape key works 0353 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0354 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0355 std::unique_ptr<KWayland::Client::Pointer> pointer(Test::waylandSeat()->createPointer()); 0356 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0357 QSignalSpy pointerEnteredSpy(pointer.get(), &KWayland::Client::Pointer::entered); 0358 QSignalSpy pointerLeftSpy(pointer.get(), &KWayland::Client::Pointer::left); 0359 QSignalSpy keyboardEnteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered); 0360 QSignalSpy keyboardLeftSpy(keyboard.get(), &KWayland::Client::Keyboard::left); 0361 0362 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0363 QVERIFY(window); 0364 QVERIFY(keyboardEnteredSpy.wait()); 0365 KWin::input()->pointer()->warp(window->frameGeometry().center()); 0366 QCOMPARE(input()->pointer()->focus(), window); 0367 QVERIFY(pointerEnteredSpy.wait()); 0368 0369 Window *selectedWindow = nullptr; 0370 auto callback = [&selectedWindow](Window *t) { 0371 selectedWindow = t; 0372 }; 0373 0374 // start the interaction 0375 QCOMPARE(input()->isSelectingWindow(), false); 0376 kwinApp()->startInteractiveWindowSelection(callback); 0377 QCOMPARE(input()->isSelectingWindow(), true); 0378 QVERIFY(!selectedWindow); 0379 QCOMPARE(keyboardLeftSpy.count(), 0); 0380 QVERIFY(pointerLeftSpy.wait()); 0381 if (keyboardLeftSpy.isEmpty()) { 0382 QVERIFY(keyboardLeftSpy.wait()); 0383 } 0384 QCOMPARE(pointerLeftSpy.count(), 1); 0385 QCOMPARE(keyboardLeftSpy.count(), 1); 0386 0387 // simulate left button press 0388 quint32 timestamp = 0; 0389 Test::keyboardKeyPressed(KEY_ESC, timestamp++); 0390 QCOMPARE(input()->isSelectingWindow(), false); 0391 QVERIFY(!selectedWindow); 0392 QCOMPARE(input()->pointer()->focus(), window); 0393 // should give back keyboard and pointer 0394 QVERIFY(pointerEnteredSpy.wait()); 0395 if (keyboardEnteredSpy.count() != 2) { 0396 QVERIFY(keyboardEnteredSpy.wait()); 0397 } 0398 QCOMPARE(pointerLeftSpy.count(), 1); 0399 QCOMPARE(keyboardLeftSpy.count(), 1); 0400 QCOMPARE(pointerEnteredSpy.count(), 2); 0401 QCOMPARE(keyboardEnteredSpy.count(), 2); 0402 Test::keyboardKeyReleased(KEY_ESC, timestamp++); 0403 } 0404 0405 void TestWindowSelection::testSelectPointPointer() 0406 { 0407 // this test verifies point selection through pointer works 0408 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0409 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0410 std::unique_ptr<KWayland::Client::Pointer> pointer(Test::waylandSeat()->createPointer()); 0411 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0412 QSignalSpy pointerEnteredSpy(pointer.get(), &KWayland::Client::Pointer::entered); 0413 QSignalSpy pointerLeftSpy(pointer.get(), &KWayland::Client::Pointer::left); 0414 QSignalSpy keyboardEnteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered); 0415 QSignalSpy keyboardLeftSpy(keyboard.get(), &KWayland::Client::Keyboard::left); 0416 0417 auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue); 0418 QVERIFY(window); 0419 QVERIFY(keyboardEnteredSpy.wait()); 0420 KWin::input()->pointer()->warp(window->frameGeometry().center()); 0421 QCOMPARE(input()->pointer()->focus(), window); 0422 QVERIFY(pointerEnteredSpy.wait()); 0423 0424 // start the interaction 0425 QCOMPARE(input()->isSelectingWindow(), false); 0426 QPointF point; 0427 kwinApp()->startInteractivePositionSelection([&point](const QPointF &p) { 0428 point = p; 0429 }); 0430 QCOMPARE(input()->isSelectingWindow(), true); 0431 QCOMPARE(point, QPoint()); 0432 QCOMPARE(keyboardLeftSpy.count(), 0); 0433 QVERIFY(pointerLeftSpy.wait()); 0434 if (keyboardLeftSpy.isEmpty()) { 0435 QVERIFY(keyboardLeftSpy.wait()); 0436 } 0437 QCOMPARE(pointerLeftSpy.count(), 1); 0438 QCOMPARE(keyboardLeftSpy.count(), 1); 0439 0440 // trying again should not be allowed 0441 QPointF point2; 0442 kwinApp()->startInteractivePositionSelection([&point2](const QPointF &p) { 0443 point2 = p; 0444 }); 0445 QCOMPARE(point2, QPoint(-1, -1)); 0446 0447 // simulate left button press 0448 quint32 timestamp = 0; 0449 Test::pointerButtonPressed(BTN_LEFT, timestamp++); 0450 // should not have ended the mode 0451 QCOMPARE(input()->isSelectingWindow(), true); 0452 QCOMPARE(point, QPoint()); 0453 QVERIFY(!input()->pointer()->focus()); 0454 0455 // updating the pointer should not change anything 0456 input()->pointer()->update(); 0457 QVERIFY(!input()->pointer()->focus()); 0458 // updating keyboard should also not change 0459 input()->keyboard()->update(); 0460 0461 // perform a right button click 0462 Test::pointerButtonPressed(BTN_RIGHT, timestamp++); 0463 Test::pointerButtonReleased(BTN_RIGHT, timestamp++); 0464 // should not have ended the mode 0465 QCOMPARE(input()->isSelectingWindow(), true); 0466 QCOMPARE(point, QPoint()); 0467 // now release 0468 Test::pointerButtonReleased(BTN_LEFT, timestamp++); 0469 QCOMPARE(input()->isSelectingWindow(), false); 0470 QCOMPARE(point, input()->globalPointer().toPoint()); 0471 QCOMPARE(input()->pointer()->focus(), window); 0472 // should give back keyboard and pointer 0473 QVERIFY(pointerEnteredSpy.wait()); 0474 if (keyboardEnteredSpy.count() != 2) { 0475 QVERIFY(keyboardEnteredSpy.wait()); 0476 } 0477 QCOMPARE(pointerLeftSpy.count(), 1); 0478 QCOMPARE(keyboardLeftSpy.count(), 1); 0479 QCOMPARE(pointerEnteredSpy.count(), 2); 0480 QCOMPARE(keyboardEnteredSpy.count(), 2); 0481 } 0482 0483 void TestWindowSelection::testSelectPointTouch() 0484 { 0485 // this test verifies point selection through touch works 0486 // start the interaction 0487 QCOMPARE(input()->isSelectingWindow(), false); 0488 QPointF point; 0489 kwinApp()->startInteractivePositionSelection([&point](const QPointF &p) { 0490 point = p; 0491 }); 0492 QCOMPARE(input()->isSelectingWindow(), true); 0493 QCOMPARE(point, QPoint()); 0494 0495 // let's create multiple touch points 0496 quint32 timestamp = 0; 0497 Test::touchDown(0, QPointF(0, 1), timestamp++); 0498 QCOMPARE(input()->isSelectingWindow(), true); 0499 Test::touchDown(1, QPointF(10, 20), timestamp++); 0500 QCOMPARE(input()->isSelectingWindow(), true); 0501 Test::touchDown(2, QPointF(30, 40), timestamp++); 0502 QCOMPARE(input()->isSelectingWindow(), true); 0503 0504 // let's move our points 0505 Test::touchMotion(0, QPointF(5, 10), timestamp++); 0506 Test::touchMotion(2, QPointF(20, 25), timestamp++); 0507 Test::touchMotion(1, QPointF(25, 35), timestamp++); 0508 QCOMPARE(input()->isSelectingWindow(), true); 0509 Test::touchUp(0, timestamp++); 0510 QCOMPARE(input()->isSelectingWindow(), true); 0511 Test::touchUp(2, timestamp++); 0512 QCOMPARE(input()->isSelectingWindow(), true); 0513 Test::touchUp(1, timestamp++); 0514 QCOMPARE(input()->isSelectingWindow(), false); 0515 QCOMPARE(point, QPoint(25, 35)); 0516 } 0517 0518 WAYLANDTEST_MAIN(TestWindowSelection) 0519 #include "window_selection_test.moc"