Warning, file /plasma/kwin/autotests/integration/activation_test.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "kwin_wayland_test.h" 0011 0012 #include "core/output.h" 0013 #include "core/outputbackend.h" 0014 #include "cursor.h" 0015 #include "wayland_server.h" 0016 #include "window.h" 0017 #include "workspace.h" 0018 0019 #include <KWayland/Client/surface.h> 0020 0021 namespace KWin 0022 { 0023 0024 static const QString s_socketName = QStringLiteral("wayland_test_activation-0"); 0025 0026 class ActivationTest : public QObject 0027 { 0028 Q_OBJECT 0029 0030 private Q_SLOTS: 0031 void initTestCase(); 0032 void init(); 0033 void cleanup(); 0034 0035 void testSwitchToWindowToLeft(); 0036 void testSwitchToWindowToRight(); 0037 void testSwitchToWindowAbove(); 0038 void testSwitchToWindowBelow(); 0039 void testSwitchToWindowMaximized(); 0040 void testSwitchToWindowFullScreen(); 0041 0042 private: 0043 void stackScreensHorizontally(); 0044 void stackScreensVertically(); 0045 }; 0046 0047 void ActivationTest::initTestCase() 0048 { 0049 qRegisterMetaType<Window *>(); 0050 0051 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0052 QVERIFY(waylandServer()->init(s_socketName)); 0053 QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(QVector<QRect>, QVector<QRect>() << QRect(0, 0, 1280, 1024) << QRect(1280, 0, 1280, 1024))); 0054 0055 kwinApp()->start(); 0056 QVERIFY(applicationStartedSpy.wait()); 0057 const auto outputs = workspace()->outputs(); 0058 QCOMPARE(outputs.count(), 2); 0059 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024)); 0060 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024)); 0061 } 0062 0063 void ActivationTest::init() 0064 { 0065 QVERIFY(Test::setupWaylandConnection()); 0066 0067 workspace()->setActiveOutput(QPoint(640, 512)); 0068 Cursors::self()->mouse()->setPos(QPoint(640, 512)); 0069 } 0070 0071 void ActivationTest::cleanup() 0072 { 0073 Test::destroyWaylandConnection(); 0074 0075 stackScreensHorizontally(); 0076 } 0077 0078 void ActivationTest::testSwitchToWindowToLeft() 0079 { 0080 // This test verifies that "Switch to Window to the Left" shortcut works. 0081 0082 // Prepare the test environment. 0083 stackScreensHorizontally(); 0084 0085 // Create several windows on the left screen. 0086 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0087 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0088 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0089 QVERIFY(window1); 0090 QVERIFY(window1->isActive()); 0091 0092 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0093 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0094 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0095 QVERIFY(window2); 0096 QVERIFY(window2->isActive()); 0097 0098 window1->move(QPoint(300, 200)); 0099 window2->move(QPoint(500, 200)); 0100 0101 // Create several windows on the right screen. 0102 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0103 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0104 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0105 QVERIFY(window3); 0106 QVERIFY(window3->isActive()); 0107 0108 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0109 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0110 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0111 QVERIFY(window4); 0112 QVERIFY(window4->isActive()); 0113 0114 window3->move(QPoint(1380, 200)); 0115 window4->move(QPoint(1580, 200)); 0116 0117 // Switch to window to the left. 0118 workspace()->switchWindow(Workspace::DirectionWest); 0119 QVERIFY(window3->isActive()); 0120 0121 // Switch to window to the left. 0122 workspace()->switchWindow(Workspace::DirectionWest); 0123 QVERIFY(window2->isActive()); 0124 0125 // Switch to window to the left. 0126 workspace()->switchWindow(Workspace::DirectionWest); 0127 QVERIFY(window1->isActive()); 0128 0129 // Switch to window to the left. 0130 workspace()->switchWindow(Workspace::DirectionWest); 0131 QVERIFY(window4->isActive()); 0132 0133 // Destroy all windows. 0134 shellSurface1.reset(); 0135 QVERIFY(Test::waitForWindowDestroyed(window1)); 0136 shellSurface2.reset(); 0137 QVERIFY(Test::waitForWindowDestroyed(window2)); 0138 shellSurface3.reset(); 0139 QVERIFY(Test::waitForWindowDestroyed(window3)); 0140 shellSurface4.reset(); 0141 QVERIFY(Test::waitForWindowDestroyed(window4)); 0142 } 0143 0144 void ActivationTest::testSwitchToWindowToRight() 0145 { 0146 // This test verifies that "Switch to Window to the Right" shortcut works. 0147 0148 // Prepare the test environment. 0149 stackScreensHorizontally(); 0150 0151 // Create several windows on the left screen. 0152 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0153 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0154 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0155 QVERIFY(window1); 0156 QVERIFY(window1->isActive()); 0157 0158 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0159 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0160 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0161 QVERIFY(window2); 0162 QVERIFY(window2->isActive()); 0163 0164 window1->move(QPoint(300, 200)); 0165 window2->move(QPoint(500, 200)); 0166 0167 // Create several windows on the right screen. 0168 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0169 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0170 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0171 QVERIFY(window3); 0172 QVERIFY(window3->isActive()); 0173 0174 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0175 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0176 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0177 QVERIFY(window4); 0178 QVERIFY(window4->isActive()); 0179 0180 window3->move(QPoint(1380, 200)); 0181 window4->move(QPoint(1580, 200)); 0182 0183 // Switch to window to the right. 0184 workspace()->switchWindow(Workspace::DirectionEast); 0185 QVERIFY(window1->isActive()); 0186 0187 // Switch to window to the right. 0188 workspace()->switchWindow(Workspace::DirectionEast); 0189 QVERIFY(window2->isActive()); 0190 0191 // Switch to window to the right. 0192 workspace()->switchWindow(Workspace::DirectionEast); 0193 QVERIFY(window3->isActive()); 0194 0195 // Switch to window to the right. 0196 workspace()->switchWindow(Workspace::DirectionEast); 0197 QVERIFY(window4->isActive()); 0198 0199 // Destroy all windows. 0200 shellSurface1.reset(); 0201 QVERIFY(Test::waitForWindowDestroyed(window1)); 0202 shellSurface2.reset(); 0203 QVERIFY(Test::waitForWindowDestroyed(window2)); 0204 shellSurface3.reset(); 0205 QVERIFY(Test::waitForWindowDestroyed(window3)); 0206 shellSurface4.reset(); 0207 QVERIFY(Test::waitForWindowDestroyed(window4)); 0208 } 0209 0210 void ActivationTest::testSwitchToWindowAbove() 0211 { 0212 // This test verifies that "Switch to Window Above" shortcut works. 0213 0214 // Prepare the test environment. 0215 stackScreensVertically(); 0216 0217 // Create several windows on the top screen. 0218 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0219 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0220 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0221 QVERIFY(window1); 0222 QVERIFY(window1->isActive()); 0223 0224 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0225 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0226 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0227 QVERIFY(window2); 0228 QVERIFY(window2->isActive()); 0229 0230 window1->move(QPoint(200, 300)); 0231 window2->move(QPoint(200, 500)); 0232 0233 // Create several windows on the bottom screen. 0234 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0235 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0236 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0237 QVERIFY(window3); 0238 QVERIFY(window3->isActive()); 0239 0240 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0241 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0242 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0243 QVERIFY(window4); 0244 QVERIFY(window4->isActive()); 0245 0246 window3->move(QPoint(200, 1224)); 0247 window4->move(QPoint(200, 1424)); 0248 0249 // Switch to window above. 0250 workspace()->switchWindow(Workspace::DirectionNorth); 0251 QVERIFY(window3->isActive()); 0252 0253 // Switch to window above. 0254 workspace()->switchWindow(Workspace::DirectionNorth); 0255 QVERIFY(window2->isActive()); 0256 0257 // Switch to window above. 0258 workspace()->switchWindow(Workspace::DirectionNorth); 0259 QVERIFY(window1->isActive()); 0260 0261 // Switch to window above. 0262 workspace()->switchWindow(Workspace::DirectionNorth); 0263 QVERIFY(window4->isActive()); 0264 0265 // Destroy all windows. 0266 shellSurface1.reset(); 0267 QVERIFY(Test::waitForWindowDestroyed(window1)); 0268 shellSurface2.reset(); 0269 QVERIFY(Test::waitForWindowDestroyed(window2)); 0270 shellSurface3.reset(); 0271 QVERIFY(Test::waitForWindowDestroyed(window3)); 0272 shellSurface4.reset(); 0273 QVERIFY(Test::waitForWindowDestroyed(window4)); 0274 } 0275 0276 void ActivationTest::testSwitchToWindowBelow() 0277 { 0278 // This test verifies that "Switch to Window Bottom" shortcut works. 0279 0280 // Prepare the test environment. 0281 stackScreensVertically(); 0282 0283 // Create several windows on the top screen. 0284 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0285 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0286 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0287 QVERIFY(window1); 0288 QVERIFY(window1->isActive()); 0289 0290 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0291 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0292 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0293 QVERIFY(window2); 0294 QVERIFY(window2->isActive()); 0295 0296 window1->move(QPoint(200, 300)); 0297 window2->move(QPoint(200, 500)); 0298 0299 // Create several windows on the bottom screen. 0300 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0301 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0302 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0303 QVERIFY(window3); 0304 QVERIFY(window3->isActive()); 0305 0306 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0307 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0308 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0309 QVERIFY(window4); 0310 QVERIFY(window4->isActive()); 0311 0312 window3->move(QPoint(200, 1224)); 0313 window4->move(QPoint(200, 1424)); 0314 0315 // Switch to window below. 0316 workspace()->switchWindow(Workspace::DirectionSouth); 0317 QVERIFY(window1->isActive()); 0318 0319 // Switch to window below. 0320 workspace()->switchWindow(Workspace::DirectionSouth); 0321 QVERIFY(window2->isActive()); 0322 0323 // Switch to window below. 0324 workspace()->switchWindow(Workspace::DirectionSouth); 0325 QVERIFY(window3->isActive()); 0326 0327 // Switch to window below. 0328 workspace()->switchWindow(Workspace::DirectionSouth); 0329 QVERIFY(window4->isActive()); 0330 0331 // Destroy all windows. 0332 shellSurface1.reset(); 0333 QVERIFY(Test::waitForWindowDestroyed(window1)); 0334 shellSurface2.reset(); 0335 QVERIFY(Test::waitForWindowDestroyed(window2)); 0336 shellSurface3.reset(); 0337 QVERIFY(Test::waitForWindowDestroyed(window3)); 0338 shellSurface4.reset(); 0339 QVERIFY(Test::waitForWindowDestroyed(window4)); 0340 } 0341 0342 void ActivationTest::testSwitchToWindowMaximized() 0343 { 0344 // This test verifies that we switch to the top-most maximized window, i.e. 0345 // the one that user sees at the moment. See bug 411356. 0346 0347 // Prepare the test environment. 0348 stackScreensHorizontally(); 0349 0350 // Create several maximized windows on the left screen. 0351 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0352 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0353 QSignalSpy toplevelConfigureRequestedSpy1(shellSurface1.get(), &Test::XdgToplevel::configureRequested); 0354 QSignalSpy surfaceConfigureRequestedSpy1(shellSurface1->xdgSurface(), &Test::XdgSurface::configureRequested); 0355 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0356 QVERIFY(window1); 0357 QVERIFY(window1->isActive()); 0358 QVERIFY(surfaceConfigureRequestedSpy1.wait()); // Wait for the configure event with the activated state. 0359 workspace()->slotWindowMaximize(); 0360 QVERIFY(surfaceConfigureRequestedSpy1.wait()); 0361 QSignalSpy frameGeometryChangedSpy1(window1, &Window::frameGeometryChanged); 0362 shellSurface1->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy1.last().at(0).value<quint32>()); 0363 Test::render(surface1.get(), toplevelConfigureRequestedSpy1.last().at(0).toSize(), Qt::red); 0364 QVERIFY(frameGeometryChangedSpy1.wait()); 0365 0366 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0367 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0368 QSignalSpy toplevelConfigureRequestedSpy2(shellSurface2.get(), &Test::XdgToplevel::configureRequested); 0369 QSignalSpy surfaceConfigureRequestedSpy2(shellSurface2->xdgSurface(), &Test::XdgSurface::configureRequested); 0370 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0371 QVERIFY(window2); 0372 QVERIFY(window2->isActive()); 0373 QVERIFY(surfaceConfigureRequestedSpy2.wait()); // Wait for the configure event with the activated state. 0374 workspace()->slotWindowMaximize(); 0375 QVERIFY(surfaceConfigureRequestedSpy2.wait()); 0376 QSignalSpy frameGeometryChangedSpy2(window2, &Window::frameGeometryChanged); 0377 shellSurface2->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy2.last().at(0).value<quint32>()); 0378 Test::render(surface2.get(), toplevelConfigureRequestedSpy2.last().at(0).toSize(), Qt::red); 0379 QVERIFY(frameGeometryChangedSpy2.wait()); 0380 0381 const QList<Window *> stackingOrder = workspace()->stackingOrder(); 0382 QVERIFY(stackingOrder.indexOf(window1) < stackingOrder.indexOf(window2)); 0383 QCOMPARE(window1->maximizeMode(), MaximizeFull); 0384 QCOMPARE(window2->maximizeMode(), MaximizeFull); 0385 0386 // Create several windows on the right screen. 0387 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0388 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0389 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0390 QVERIFY(window3); 0391 QVERIFY(window3->isActive()); 0392 0393 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0394 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0395 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0396 QVERIFY(window4); 0397 QVERIFY(window4->isActive()); 0398 0399 window3->move(QPoint(1380, 200)); 0400 window4->move(QPoint(1580, 200)); 0401 0402 // Switch to window to the left. 0403 workspace()->switchWindow(Workspace::DirectionWest); 0404 QVERIFY(window3->isActive()); 0405 0406 // Switch to window to the left. 0407 workspace()->switchWindow(Workspace::DirectionWest); 0408 QVERIFY(window2->isActive()); 0409 0410 // Switch to window to the left. 0411 workspace()->switchWindow(Workspace::DirectionWest); 0412 QVERIFY(window4->isActive()); 0413 0414 // Destroy all windows. 0415 shellSurface1.reset(); 0416 QVERIFY(Test::waitForWindowDestroyed(window1)); 0417 shellSurface2.reset(); 0418 QVERIFY(Test::waitForWindowDestroyed(window2)); 0419 shellSurface3.reset(); 0420 QVERIFY(Test::waitForWindowDestroyed(window3)); 0421 shellSurface4.reset(); 0422 QVERIFY(Test::waitForWindowDestroyed(window4)); 0423 } 0424 0425 void ActivationTest::testSwitchToWindowFullScreen() 0426 { 0427 // This test verifies that we switch to the top-most fullscreen window, i.e. 0428 // the one that user sees at the moment. See bug 411356. 0429 0430 // Prepare the test environment. 0431 stackScreensVertically(); 0432 0433 // Create several maximized windows on the top screen. 0434 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0435 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0436 QSignalSpy toplevelConfigureRequestedSpy1(shellSurface1.get(), &Test::XdgToplevel::configureRequested); 0437 QSignalSpy surfaceConfigureRequestedSpy1(shellSurface1->xdgSurface(), &Test::XdgSurface::configureRequested); 0438 Window *window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0439 QVERIFY(window1); 0440 QVERIFY(window1->isActive()); 0441 QVERIFY(surfaceConfigureRequestedSpy1.wait()); // Wait for the configure event with the activated state. 0442 workspace()->slotWindowFullScreen(); 0443 QVERIFY(surfaceConfigureRequestedSpy1.wait()); 0444 QSignalSpy frameGeometryChangedSpy1(window1, &Window::frameGeometryChanged); 0445 shellSurface1->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy1.last().at(0).value<quint32>()); 0446 Test::render(surface1.get(), toplevelConfigureRequestedSpy1.last().at(0).toSize(), Qt::red); 0447 QVERIFY(frameGeometryChangedSpy1.wait()); 0448 0449 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0450 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0451 QSignalSpy toplevelConfigureRequestedSpy2(shellSurface2.get(), &Test::XdgToplevel::configureRequested); 0452 QSignalSpy surfaceConfigureRequestedSpy2(shellSurface2->xdgSurface(), &Test::XdgSurface::configureRequested); 0453 Window *window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue); 0454 QVERIFY(window2); 0455 QVERIFY(window2->isActive()); 0456 QVERIFY(surfaceConfigureRequestedSpy2.wait()); // Wait for the configure event with the activated state. 0457 workspace()->slotWindowFullScreen(); 0458 QVERIFY(surfaceConfigureRequestedSpy2.wait()); 0459 QSignalSpy frameGeometryChangedSpy2(window2, &Window::frameGeometryChanged); 0460 shellSurface2->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy2.last().at(0).value<quint32>()); 0461 Test::render(surface2.get(), toplevelConfigureRequestedSpy2.last().at(0).toSize(), Qt::red); 0462 QVERIFY(frameGeometryChangedSpy2.wait()); 0463 0464 const QList<Window *> stackingOrder = workspace()->stackingOrder(); 0465 QVERIFY(stackingOrder.indexOf(window1) < stackingOrder.indexOf(window2)); 0466 QVERIFY(window1->isFullScreen()); 0467 QVERIFY(window2->isFullScreen()); 0468 0469 // Create several windows on the bottom screen. 0470 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0471 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0472 Window *window3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::blue); 0473 QVERIFY(window3); 0474 QVERIFY(window3->isActive()); 0475 0476 std::unique_ptr<KWayland::Client::Surface> surface4(Test::createSurface()); 0477 std::unique_ptr<Test::XdgToplevel> shellSurface4(Test::createXdgToplevelSurface(surface4.get())); 0478 Window *window4 = Test::renderAndWaitForShown(surface4.get(), QSize(100, 50), Qt::blue); 0479 QVERIFY(window4); 0480 QVERIFY(window4->isActive()); 0481 0482 window3->move(QPoint(200, 1224)); 0483 window4->move(QPoint(200, 1424)); 0484 0485 // Switch to window above. 0486 workspace()->switchWindow(Workspace::DirectionNorth); 0487 QVERIFY(window3->isActive()); 0488 0489 // Switch to window above. 0490 workspace()->switchWindow(Workspace::DirectionNorth); 0491 QVERIFY(window2->isActive()); 0492 0493 // Switch to window above. 0494 workspace()->switchWindow(Workspace::DirectionNorth); 0495 QVERIFY(window4->isActive()); 0496 0497 // Destroy all windows. 0498 shellSurface1.reset(); 0499 QVERIFY(Test::waitForWindowDestroyed(window1)); 0500 shellSurface2.reset(); 0501 QVERIFY(Test::waitForWindowDestroyed(window2)); 0502 shellSurface3.reset(); 0503 QVERIFY(Test::waitForWindowDestroyed(window3)); 0504 shellSurface4.reset(); 0505 QVERIFY(Test::waitForWindowDestroyed(window4)); 0506 } 0507 0508 void ActivationTest::stackScreensHorizontally() 0509 { 0510 // Process pending wl_output bind requests before destroying all outputs. 0511 QTest::qWait(1); 0512 0513 const QVector<QRect> screenGeometries{ 0514 QRect(0, 0, 1280, 1024), 0515 QRect(1280, 0, 1280, 1024), 0516 }; 0517 0518 QMetaObject::invokeMethod(kwinApp()->outputBackend(), 0519 "setVirtualOutputs", 0520 Qt::DirectConnection, 0521 Q_ARG(QVector<QRect>, screenGeometries)); 0522 } 0523 0524 void ActivationTest::stackScreensVertically() 0525 { 0526 // Process pending wl_output bind requests before destroying all outputs. 0527 QTest::qWait(1); 0528 0529 const QVector<QRect> screenGeometries{ 0530 QRect(0, 0, 1280, 1024), 0531 QRect(0, 1024, 1280, 1024), 0532 }; 0533 0534 QMetaObject::invokeMethod(kwinApp()->outputBackend(), 0535 "setVirtualOutputs", 0536 Qt::DirectConnection, 0537 Q_ARG(QVector<QRect>, screenGeometries)); 0538 } 0539 0540 } 0541 0542 WAYLANDTEST_MAIN(KWin::ActivationTest) 0543 #include "activation_test.moc"