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