File indexing completed on 2024-05-12 05:30:30

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