File indexing completed on 2024-11-10 04:56:07
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016 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 "input.h" 0012 #include "pointer_input.h" 0013 #include "tabbox/tabbox.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 #include <linux/input.h> 0022 0023 using namespace KWin; 0024 0025 static const QString s_socketName = QStringLiteral("wayland_test_kwin_tabbox-0"); 0026 0027 class TabBoxTest : public QObject 0028 { 0029 Q_OBJECT 0030 private Q_SLOTS: 0031 void initTestCase(); 0032 void init(); 0033 void cleanup(); 0034 0035 void testMoveForward(); 0036 void testMoveBackward(); 0037 void testCapsLock(); 0038 }; 0039 0040 void TabBoxTest::initTestCase() 0041 { 0042 qRegisterMetaType<KWin::Window *>(); 0043 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0044 QVERIFY(waylandServer()->init(s_socketName)); 0045 Test::setOutputConfig({ 0046 QRect(0, 0, 1280, 1024), 0047 QRect(1280, 0, 1280, 1024), 0048 }); 0049 0050 KSharedConfigPtr c = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); 0051 c->group(QStringLiteral("TabBox")).writeEntry("ShowTabBox", false); 0052 c->sync(); 0053 kwinApp()->setConfig(c); 0054 qputenv("KWIN_XKB_DEFAULT_KEYMAP", "1"); 0055 0056 kwinApp()->start(); 0057 QVERIFY(applicationStartedSpy.wait()); 0058 } 0059 0060 void TabBoxTest::init() 0061 { 0062 QVERIFY(Test::setupWaylandConnection()); 0063 workspace()->setActiveOutput(QPoint(640, 512)); 0064 KWin::input()->pointer()->warp(QPoint(640, 512)); 0065 } 0066 0067 void TabBoxTest::cleanup() 0068 { 0069 Test::destroyWaylandConnection(); 0070 } 0071 0072 void TabBoxTest::testCapsLock() 0073 { 0074 #if !KWIN_BUILD_GLOBALSHORTCUTS 0075 QSKIP("Can't test shortcuts without shortcuts"); 0076 return; 0077 #endif 0078 0079 // this test verifies that Alt+tab works correctly also when Capslock is on 0080 // bug 368590 0081 0082 // first create three windows 0083 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0084 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0085 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0086 QVERIFY(c1); 0087 QVERIFY(c1->isActive()); 0088 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0089 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0090 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red); 0091 QVERIFY(c2); 0092 QVERIFY(c2->isActive()); 0093 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0094 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0095 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red); 0096 QVERIFY(c3); 0097 QVERIFY(c3->isActive()); 0098 0099 // Setup tabbox signal spies 0100 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded); 0101 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed); 0102 0103 // enable capslock 0104 quint32 timestamp = 0; 0105 Test::keyboardKeyPressed(KEY_CAPSLOCK, timestamp++); 0106 Test::keyboardKeyReleased(KEY_CAPSLOCK, timestamp++); 0107 QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier); 0108 0109 // press alt+tab 0110 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++); 0111 QCOMPARE(input()->keyboardModifiers(), Qt::ShiftModifier | Qt::AltModifier); 0112 Test::keyboardKeyPressed(KEY_TAB, timestamp++); 0113 Test::keyboardKeyReleased(KEY_TAB, timestamp++); 0114 0115 QVERIFY(tabboxAddedSpy.wait()); 0116 QVERIFY(workspace()->tabbox()->isGrabbed()); 0117 0118 // release alt 0119 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++); 0120 QCOMPARE(tabboxClosedSpy.count(), 1); 0121 QCOMPARE(workspace()->tabbox()->isGrabbed(), false); 0122 0123 // release caps lock 0124 Test::keyboardKeyPressed(KEY_CAPSLOCK, timestamp++); 0125 Test::keyboardKeyReleased(KEY_CAPSLOCK, timestamp++); 0126 QCOMPARE(input()->keyboardModifiers(), Qt::NoModifier); 0127 QCOMPARE(tabboxClosedSpy.count(), 1); 0128 QCOMPARE(workspace()->tabbox()->isGrabbed(), false); 0129 QCOMPARE(workspace()->activeWindow(), c2); 0130 0131 surface3.reset(); 0132 QVERIFY(Test::waitForWindowClosed(c3)); 0133 surface2.reset(); 0134 QVERIFY(Test::waitForWindowClosed(c2)); 0135 surface1.reset(); 0136 QVERIFY(Test::waitForWindowClosed(c1)); 0137 } 0138 0139 void TabBoxTest::testMoveForward() 0140 { 0141 #if !KWIN_BUILD_GLOBALSHORTCUTS 0142 QSKIP("Can't test shortcuts without shortcuts"); 0143 return; 0144 #endif 0145 0146 // this test verifies that Alt+tab works correctly moving forward 0147 0148 // first create three windows 0149 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0150 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0151 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0152 QVERIFY(c1); 0153 QVERIFY(c1->isActive()); 0154 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0155 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0156 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red); 0157 QVERIFY(c2); 0158 QVERIFY(c2->isActive()); 0159 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0160 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0161 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red); 0162 QVERIFY(c3); 0163 QVERIFY(c3->isActive()); 0164 0165 // Setup tabbox signal spies 0166 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded); 0167 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed); 0168 0169 // press alt+tab 0170 quint32 timestamp = 0; 0171 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++); 0172 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier); 0173 Test::keyboardKeyPressed(KEY_TAB, timestamp++); 0174 Test::keyboardKeyReleased(KEY_TAB, timestamp++); 0175 0176 QVERIFY(tabboxAddedSpy.wait()); 0177 QVERIFY(workspace()->tabbox()->isGrabbed()); 0178 0179 // release alt 0180 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++); 0181 QCOMPARE(tabboxClosedSpy.count(), 1); 0182 QCOMPARE(workspace()->tabbox()->isGrabbed(), false); 0183 QCOMPARE(workspace()->activeWindow(), c2); 0184 0185 surface3.reset(); 0186 QVERIFY(Test::waitForWindowClosed(c3)); 0187 surface2.reset(); 0188 QVERIFY(Test::waitForWindowClosed(c2)); 0189 surface1.reset(); 0190 QVERIFY(Test::waitForWindowClosed(c1)); 0191 } 0192 0193 void TabBoxTest::testMoveBackward() 0194 { 0195 #if !KWIN_BUILD_GLOBALSHORTCUTS 0196 QSKIP("Can't test shortcuts without shortcuts"); 0197 return; 0198 #endif 0199 0200 // this test verifies that Alt+Shift+tab works correctly moving backward 0201 0202 // first create three windows 0203 std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface()); 0204 std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get())); 0205 auto c1 = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue); 0206 QVERIFY(c1); 0207 QVERIFY(c1->isActive()); 0208 std::unique_ptr<KWayland::Client::Surface> surface2(Test::createSurface()); 0209 std::unique_ptr<Test::XdgToplevel> shellSurface2(Test::createXdgToplevelSurface(surface2.get())); 0210 auto c2 = Test::renderAndWaitForShown(surface2.get(), QSize(100, 50), Qt::red); 0211 QVERIFY(c2); 0212 QVERIFY(c2->isActive()); 0213 std::unique_ptr<KWayland::Client::Surface> surface3(Test::createSurface()); 0214 std::unique_ptr<Test::XdgToplevel> shellSurface3(Test::createXdgToplevelSurface(surface3.get())); 0215 auto c3 = Test::renderAndWaitForShown(surface3.get(), QSize(100, 50), Qt::red); 0216 QVERIFY(c3); 0217 QVERIFY(c3->isActive()); 0218 0219 // Setup tabbox signal spies 0220 QSignalSpy tabboxAddedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxAdded); 0221 QSignalSpy tabboxClosedSpy(workspace()->tabbox(), &TabBox::TabBox::tabBoxClosed); 0222 0223 // press alt+shift+tab 0224 quint32 timestamp = 0; 0225 Test::keyboardKeyPressed(KEY_LEFTALT, timestamp++); 0226 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier); 0227 Test::keyboardKeyPressed(KEY_LEFTSHIFT, timestamp++); 0228 QCOMPARE(input()->keyboardModifiers(), Qt::AltModifier | Qt::ShiftModifier); 0229 Test::keyboardKeyPressed(KEY_TAB, timestamp++); 0230 Test::keyboardKeyReleased(KEY_TAB, timestamp++); 0231 0232 QVERIFY(tabboxAddedSpy.wait()); 0233 QVERIFY(workspace()->tabbox()->isGrabbed()); 0234 0235 // release alt 0236 Test::keyboardKeyReleased(KEY_LEFTSHIFT, timestamp++); 0237 QCOMPARE(tabboxClosedSpy.count(), 0); 0238 Test::keyboardKeyReleased(KEY_LEFTALT, timestamp++); 0239 QCOMPARE(tabboxClosedSpy.count(), 1); 0240 QCOMPARE(workspace()->tabbox()->isGrabbed(), false); 0241 QCOMPARE(workspace()->activeWindow(), c1); 0242 0243 surface3.reset(); 0244 QVERIFY(Test::waitForWindowClosed(c3)); 0245 surface2.reset(); 0246 QVERIFY(Test::waitForWindowClosed(c2)); 0247 surface1.reset(); 0248 QVERIFY(Test::waitForWindowClosed(c1)); 0249 } 0250 0251 WAYLANDTEST_MAIN(TabBoxTest) 0252 #include "tabbox_test.moc"