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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2014 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 "pointer_input.h"
0013 #include "wayland_server.h"
0014 #include "window.h"
0015 #include "workspace.h"
0016 
0017 #include <KConfigGroup>
0018 #include <KWayland/Client/surface.h>
0019 
0020 namespace KWin
0021 {
0022 
0023 static const QString s_socketName = QStringLiteral("wayland_test_kwin_screens-0");
0024 
0025 class ScreensTest : public QObject
0026 {
0027     Q_OBJECT
0028 
0029 private Q_SLOTS:
0030     void initTestCase();
0031     void init();
0032     void cleanup();
0033     void testCurrent_data();
0034     void testCurrent();
0035     void testCurrentWithFollowsMouse_data();
0036     void testCurrentWithFollowsMouse();
0037     void testCurrentPoint_data();
0038     void testCurrentPoint();
0039 };
0040 
0041 void ScreensTest::initTestCase()
0042 {
0043     qRegisterMetaType<KWin::Window *>();
0044     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0045     QVERIFY(waylandServer()->init(s_socketName));
0046     Test::setOutputConfig({
0047         QRect(0, 0, 1280, 1024),
0048         QRect(1280, 0, 1280, 1024),
0049     });
0050 
0051     kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig));
0052 
0053     kwinApp()->start();
0054     QVERIFY(applicationStartedSpy.wait());
0055     const auto outputs = workspace()->outputs();
0056     QCOMPARE(outputs.count(), 2);
0057     QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
0058     QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
0059 }
0060 
0061 void ScreensTest::init()
0062 {
0063     workspace()->setActiveOutput(QPoint(640, 512));
0064     KWin::input()->pointer()->warp(QPoint(640, 512));
0065 
0066     QVERIFY(Test::setupWaylandConnection());
0067 }
0068 
0069 static void purge(KConfig *config)
0070 {
0071     const QStringList groups = config->groupList();
0072     for (const QString &group : groups) {
0073         config->deleteGroup(group);
0074     }
0075 }
0076 
0077 void ScreensTest::cleanup()
0078 {
0079     // Destroy the wayland connection of the test window.
0080     Test::destroyWaylandConnection();
0081 
0082     // Wipe the screens config clean.
0083     auto config = kwinApp()->config();
0084     purge(config.data());
0085     config->sync();
0086     workspace()->slotReconfigure();
0087 
0088     // Reset the screen layout of the test environment.
0089     Test::setOutputConfig({
0090         QRect(0, 0, 1280, 1024),
0091         QRect(1280, 0, 1280, 1024),
0092     });
0093 }
0094 
0095 void ScreensTest::testCurrent_data()
0096 {
0097     QTest::addColumn<int>("currentId");
0098 
0099     QTest::newRow("first") << 0;
0100     QTest::newRow("second") << 1;
0101 }
0102 
0103 void ScreensTest::testCurrent()
0104 {
0105     QFETCH(int, currentId);
0106     Output *output = workspace()->outputs().at(currentId);
0107 
0108     // Disable "active screen follows mouse"
0109     auto group = kwinApp()->config()->group(QStringLiteral("Windows"));
0110     group.writeEntry("ActiveMouseScreen", false);
0111     group.sync();
0112     workspace()->slotReconfigure();
0113 
0114     workspace()->setActiveOutput(output);
0115     QCOMPARE(workspace()->activeOutput(), output);
0116 }
0117 
0118 void ScreensTest::testCurrentWithFollowsMouse_data()
0119 {
0120     QTest::addColumn<QList<QRect>>("geometries");
0121     QTest::addColumn<QPoint>("cursorPos");
0122     QTest::addColumn<int>("expectedId");
0123 
0124     QTest::newRow("cloned") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{0, 0, 200, 100}}} << QPoint(50, 50) << 0;
0125     QTest::newRow("adjacent-0") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{200, 100, 400, 300}}} << QPoint(199, 99) << 0;
0126     QTest::newRow("adjacent-1") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{200, 100, 400, 300}}} << QPoint(200, 100) << 1;
0127     QTest::newRow("gap") << QList<QRect>{{QRect{0, 0, 10, 20}, QRect{20, 40, 10, 20}}} << QPoint(15, 30) << 1;
0128 }
0129 
0130 void ScreensTest::testCurrentWithFollowsMouse()
0131 {
0132     // Enable "active screen follows mouse"
0133     auto group = kwinApp()->config()->group(QStringLiteral("Windows"));
0134     group.writeEntry("ActiveMouseScreen", true);
0135     group.sync();
0136     workspace()->slotReconfigure();
0137 
0138     QFETCH(QList<QRect>, geometries);
0139     Test::setOutputConfig(geometries);
0140 
0141     QFETCH(QPoint, cursorPos);
0142     KWin::input()->pointer()->warp(cursorPos);
0143 
0144     QFETCH(int, expectedId);
0145     Output *expected = workspace()->outputs().at(expectedId);
0146     QCOMPARE(workspace()->activeOutput(), expected);
0147 }
0148 
0149 void ScreensTest::testCurrentPoint_data()
0150 {
0151     QTest::addColumn<QList<QRect>>("geometries");
0152     QTest::addColumn<QPoint>("cursorPos");
0153     QTest::addColumn<int>("expectedId");
0154 
0155     QTest::newRow("cloned") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{0, 0, 200, 100}}} << QPoint(50, 50) << 0;
0156     QTest::newRow("adjacent-0") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{200, 100, 400, 300}}} << QPoint(199, 99) << 0;
0157     QTest::newRow("adjacent-1") << QList<QRect>{{QRect{0, 0, 200, 100}, QRect{200, 100, 400, 300}}} << QPoint(200, 100) << 1;
0158     QTest::newRow("gap") << QList<QRect>{{QRect{0, 0, 10, 20}, QRect{20, 40, 10, 20}}} << QPoint(15, 30) << 1;
0159 }
0160 
0161 void ScreensTest::testCurrentPoint()
0162 {
0163     QFETCH(QList<QRect>, geometries);
0164     Test::setOutputConfig(geometries);
0165 
0166     // Disable "active screen follows mouse"
0167     auto group = kwinApp()->config()->group(QStringLiteral("Windows"));
0168     group.writeEntry("ActiveMouseScreen", false);
0169     group.sync();
0170     workspace()->slotReconfigure();
0171 
0172     QFETCH(QPoint, cursorPos);
0173     workspace()->setActiveOutput(cursorPos);
0174 
0175     QFETCH(int, expectedId);
0176     Output *expected = workspace()->outputs().at(expectedId);
0177     QCOMPARE(workspace()->activeOutput(), expected);
0178 }
0179 
0180 } // namespace KWin
0181 
0182 WAYLANDTEST_MAIN(KWin::ScreensTest)
0183 #include "screens_test.moc"