File indexing completed on 2024-11-10 04:56:06

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2017 Martin Flöser <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include "kwin_wayland_test.h"
0010 
0011 #include "wayland_server.h"
0012 #include "window.h"
0013 #include "workspace.h"
0014 
0015 #include <KWayland/Client/surface.h>
0016 
0017 using namespace KWin;
0018 
0019 static const QString s_socketName = QStringLiteral("wayland_test_kwin_showing_desktop-0");
0020 
0021 class ShowingDesktopTest : public QObject
0022 {
0023     Q_OBJECT
0024 private Q_SLOTS:
0025     void initTestCase();
0026     void init();
0027     void cleanup();
0028 
0029     void testRestoreFocus();
0030     void testRestoreFocusWithDesktopWindow();
0031     void testQuitAfterActivatingHiddenWindow();
0032     void testDontQuitAfterActivatingDock();
0033     void testQuitAfterAddingWindow();
0034     void testDontQuitAfterAddingDock();
0035 };
0036 
0037 void ShowingDesktopTest::initTestCase()
0038 {
0039     qRegisterMetaType<KWin::Window *>();
0040     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0041     QVERIFY(waylandServer()->init(s_socketName));
0042     Test::setOutputConfig({
0043         QRect(0, 0, 1280, 1024),
0044         QRect(1280, 0, 1280, 1024),
0045     });
0046 
0047     kwinApp()->start();
0048     QVERIFY(applicationStartedSpy.wait());
0049 }
0050 
0051 void ShowingDesktopTest::init()
0052 {
0053     QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1));
0054 }
0055 
0056 void ShowingDesktopTest::cleanup()
0057 {
0058     Test::destroyWaylandConnection();
0059 }
0060 
0061 void ShowingDesktopTest::testRestoreFocus()
0062 {
0063     std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
0064     std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
0065     auto window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
0066     std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
0067     std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
0068     auto window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue);
0069     QVERIFY(window1 != window2);
0070 
0071     QCOMPARE(workspace()->activeWindow(), window2);
0072     workspace()->slotToggleShowDesktop();
0073     QVERIFY(workspace()->showingDesktop());
0074     workspace()->slotToggleShowDesktop();
0075     QVERIFY(!workspace()->showingDesktop());
0076 
0077     QVERIFY(workspace()->activeWindow());
0078     QCOMPARE(workspace()->activeWindow(), window2);
0079 }
0080 
0081 void ShowingDesktopTest::testRestoreFocusWithDesktopWindow()
0082 {
0083     // first create a desktop window
0084 
0085     std::unique_ptr<KWayland::Client::Surface> desktopSurface(Test::createSurface());
0086     std::unique_ptr<Test::LayerSurfaceV1> desktopShellSurface(Test::createLayerSurfaceV1(desktopSurface.get(), QStringLiteral("desktop")));
0087     desktopShellSurface->set_keyboard_interactivity(1);
0088     desktopShellSurface->set_layer(Test::LayerShellV1::layer_background);
0089     desktopShellSurface->set_size(0, 0);
0090     desktopShellSurface->set_exclusive_zone(-1);
0091     desktopShellSurface->set_anchor(Test::LayerSurfaceV1::anchor_bottom
0092         | Test::LayerSurfaceV1::anchor_top
0093         | Test::LayerSurfaceV1::anchor_left
0094         | Test::LayerSurfaceV1::anchor_right);
0095     desktopSurface->commit(KWayland::Client::Surface::CommitFlag::None);
0096     QSignalSpy desktopConfigureRequestedSpy(desktopShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
0097     QVERIFY(desktopConfigureRequestedSpy.wait());
0098     auto desktop = Test::renderAndWaitForShown(desktopSurface.get(), desktopConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
0099     QVERIFY(desktop);
0100     QVERIFY(desktop->isDesktop());
0101 
0102     // now create some windows
0103     std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
0104     std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
0105     auto window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
0106     std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
0107     std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
0108     auto window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue);
0109     QVERIFY(window1 != window2);
0110 
0111     QCOMPARE(workspace()->activeWindow(), window2);
0112     workspace()->slotToggleShowDesktop();
0113     QVERIFY(workspace()->showingDesktop());
0114     QCOMPARE(workspace()->activeWindow(), desktop);
0115     workspace()->slotToggleShowDesktop();
0116     QVERIFY(!workspace()->showingDesktop());
0117 
0118     QVERIFY(workspace()->activeWindow());
0119     QCOMPARE(workspace()->activeWindow(), window2);
0120 }
0121 
0122 void ShowingDesktopTest::testQuitAfterActivatingHiddenWindow()
0123 {
0124     // This test verifies that the show desktop mode is deactivated after activating a hidden window.
0125 
0126     std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
0127     std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
0128     auto window1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
0129     std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
0130     std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
0131     auto window2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue);
0132     QCOMPARE(workspace()->activeWindow(), window2);
0133 
0134     workspace()->slotToggleShowDesktop();
0135     QVERIFY(workspace()->showingDesktop());
0136 
0137     workspace()->activateWindow(window1);
0138     QVERIFY(!workspace()->showingDesktop());
0139 }
0140 
0141 void ShowingDesktopTest::testDontQuitAfterActivatingDock()
0142 {
0143     // This test verifies that activating windows belonging to desktop doesn't break showing desktop mode.
0144 
0145     std::unique_ptr<KWayland::Client::Surface> desktopSurface(Test::createSurface());
0146     std::unique_ptr<Test::LayerSurfaceV1> desktopShellSurface(Test::createLayerSurfaceV1(desktopSurface.get(), QStringLiteral("desktop")));
0147     desktopShellSurface->set_keyboard_interactivity(1);
0148     desktopShellSurface->set_layer(Test::LayerShellV1::layer_background);
0149     desktopShellSurface->set_size(0, 0);
0150     desktopShellSurface->set_exclusive_zone(-1);
0151     desktopShellSurface->set_anchor(Test::LayerSurfaceV1::anchor_bottom
0152                                     | Test::LayerSurfaceV1::anchor_top
0153                                     | Test::LayerSurfaceV1::anchor_left
0154                                     | Test::LayerSurfaceV1::anchor_right);
0155     desktopSurface->commit(KWayland::Client::Surface::CommitFlag::None);
0156     QSignalSpy desktopConfigureRequestedSpy(desktopShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
0157     QVERIFY(desktopConfigureRequestedSpy.wait());
0158     auto desktop = Test::renderAndWaitForShown(desktopSurface.get(), desktopConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
0159 
0160     std::unique_ptr<KWayland::Client::Surface> dockSurface{Test::createSurface()};
0161     std::unique_ptr<Test::LayerSurfaceV1> dockShellSurface{Test::createLayerSurfaceV1(dockSurface.get(), QStringLiteral("dock"))};
0162     dockShellSurface->set_size(1280, 50);
0163     dockShellSurface->set_anchor(Test::LayerSurfaceV1::anchor_bottom);
0164     dockShellSurface->set_exclusive_zone(50);
0165     dockShellSurface->set_keyboard_interactivity(1);
0166     dockSurface->commit(KWayland::Client::Surface::CommitFlag::None);
0167     QSignalSpy dockConfigureRequestedSpy(dockShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
0168     QVERIFY(dockConfigureRequestedSpy.wait());
0169     auto dock = Test::renderAndWaitForShown(dockSurface.get(), dockConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
0170 
0171     std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
0172     std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
0173     auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
0174     QVERIFY(window->isActive());
0175 
0176     workspace()->slotToggleShowDesktop();
0177     QVERIFY(workspace()->showingDesktop());
0178     QVERIFY(desktop->isActive());
0179 
0180     workspace()->activateWindow(dock);
0181     QVERIFY(workspace()->showingDesktop());
0182     QVERIFY(dock->isActive());
0183 
0184     workspace()->activateWindow(desktop);
0185     QVERIFY(workspace()->showingDesktop());
0186     QVERIFY(desktop->isActive());
0187 
0188     workspace()->slotToggleShowDesktop();
0189     QVERIFY(!workspace()->showingDesktop());
0190 }
0191 
0192 void ShowingDesktopTest::testQuitAfterAddingWindow()
0193 {
0194     // This test verifies that the show desktop mode is deactivated after mapping a new window.
0195 
0196     std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
0197     std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
0198     Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
0199 
0200     workspace()->slotToggleShowDesktop();
0201     QVERIFY(workspace()->showingDesktop());
0202 
0203     std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface());
0204     std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get()));
0205     Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::blue);
0206 
0207     QVERIFY(!workspace()->showingDesktop());
0208 }
0209 
0210 void ShowingDesktopTest::testDontQuitAfterAddingDock()
0211 {
0212     // This test verifies that the show desktop mode is not broken after adding a dock.
0213 
0214     std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
0215     std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
0216     auto window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
0217     QVERIFY(window->isActive());
0218 
0219     workspace()->slotToggleShowDesktop();
0220     QVERIFY(workspace()->showingDesktop());
0221 
0222     std::unique_ptr<KWayland::Client::Surface> dockSurface{Test::createSurface()};
0223     std::unique_ptr<Test::LayerSurfaceV1> dockShellSurface{Test::createLayerSurfaceV1(dockSurface.get(), QStringLiteral("dock"))};
0224     dockShellSurface->set_size(1280, 50);
0225     dockShellSurface->set_anchor(Test::LayerSurfaceV1::anchor_bottom);
0226     dockShellSurface->set_exclusive_zone(50);
0227     dockShellSurface->set_keyboard_interactivity(1);
0228     dockSurface->commit(KWayland::Client::Surface::CommitFlag::None);
0229     QSignalSpy dockConfigureRequestedSpy(dockShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
0230     QVERIFY(dockConfigureRequestedSpy.wait());
0231     auto dock = Test::renderAndWaitForShown(dockSurface.get(), dockConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
0232     QVERIFY(dock->isActive());
0233 
0234     QVERIFY(workspace()->showingDesktop());
0235     workspace()->slotToggleShowDesktop();
0236 }
0237 
0238 WAYLANDTEST_MAIN(ShowingDesktopTest)
0239 #include "showing_desktop_test.moc"