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: 2016 Martin Gräßlin <mgraesslin@kde.org> 0006 SPDX-FileCopyrightText: 2023 Nicolas Fella <nicolas.fella@gmx.de> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 #include "kwin_wayland_test.h" 0011 0012 #include "keyboard_input.h" 0013 #include "pluginmanager.h" 0014 #include "pointer_input.h" 0015 #include "wayland_server.h" 0016 #include "window.h" 0017 #include "workspace.h" 0018 0019 #include <KWayland/Client/keyboard.h> 0020 #include <KWayland/Client/seat.h> 0021 0022 #include <linux/input.h> 0023 0024 namespace KWin 0025 { 0026 0027 static const QString s_socketName = QStringLiteral("wayland_test_kwin_sticky_keys-0"); 0028 0029 class StickyKeysTest : public QObject 0030 { 0031 Q_OBJECT 0032 private Q_SLOTS: 0033 void initTestCase(); 0034 void init(); 0035 void cleanup(); 0036 void testStick(); 0037 void testLock(); 0038 }; 0039 0040 void StickyKeysTest::initTestCase() 0041 { 0042 KConfig kaccessConfig("kaccessrc"); 0043 kaccessConfig.group(QStringLiteral("Keyboard")).writeEntry("StickyKeys", true); 0044 kaccessConfig.sync(); 0045 0046 qRegisterMetaType<KWin::Window *>(); 0047 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0048 QVERIFY(waylandServer()->init(s_socketName)); 0049 Test::setOutputConfig({ 0050 QRect(0, 0, 1280, 1024), 0051 QRect(1280, 0, 1280, 1024), 0052 }); 0053 0054 qputenv("XKB_DEFAULT_RULES", "evdev"); 0055 0056 kwinApp()->start(); 0057 QVERIFY(applicationStartedSpy.wait()); 0058 } 0059 0060 void StickyKeysTest::init() 0061 { 0062 QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); 0063 QVERIFY(Test::waitForWaylandKeyboard()); 0064 } 0065 0066 void StickyKeysTest::cleanup() 0067 { 0068 Test::destroyWaylandConnection(); 0069 } 0070 0071 void StickyKeysTest::testStick() 0072 { 0073 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0074 0075 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0076 QVERIFY(surface != nullptr); 0077 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0078 QVERIFY(shellSurface != nullptr); 0079 Window *waylandWindow = Test::renderAndWaitForShown(surface.get(), QSize(10, 10), Qt::blue); 0080 QVERIFY(waylandWindow); 0081 0082 QSignalSpy modifierSpy(keyboard.get(), &KWayland::Client::Keyboard::modifiersChanged); 0083 QVERIFY(modifierSpy.wait()); 0084 modifierSpy.clear(); 0085 0086 quint32 timestamp = 0; 0087 0088 // press Ctrl to latch it 0089 Test::keyboardKeyPressed(KEY_LEFTCTRL, ++timestamp); 0090 QVERIFY(modifierSpy.wait()); 0091 // arguments are: quint32 depressed, quint32 latched, quint32 locked, quint32 group 0092 QCOMPARE(modifierSpy.first()[0], 4); // verify that Ctrl is depressed 0093 QCOMPARE(modifierSpy.first()[1], 4); // verify that Ctrl is latched 0094 0095 modifierSpy.clear(); 0096 // release Ctrl, the modified should still be latched 0097 Test::keyboardKeyReleased(KEY_LEFTCTRL, ++timestamp); 0098 QVERIFY(modifierSpy.wait()); 0099 QCOMPARE(modifierSpy.first()[0], 0); // verify that Ctrl is not depressed 0100 QCOMPARE(modifierSpy.first()[1], 4); // verify that Ctrl is still latched 0101 0102 // press and release a letter, this unlatches the modifier 0103 modifierSpy.clear(); 0104 Test::keyboardKeyPressed(KEY_A, ++timestamp); 0105 QVERIFY(modifierSpy.wait()); 0106 QCOMPARE(modifierSpy.first()[0], 0); // verify that Ctrl is not depressed 0107 QCOMPARE(modifierSpy.first()[1], 0); // verify that Ctrl is not latched any more 0108 0109 Test::keyboardKeyReleased(KEY_A, ++timestamp); 0110 } 0111 0112 void StickyKeysTest::testLock() 0113 { 0114 KConfig kaccessConfig("kaccessrc"); 0115 kaccessConfig.group(QStringLiteral("Keyboard")).writeEntry("StickyKeysLatch", true); 0116 kaccessConfig.sync(); 0117 0118 // reload the plugin to pick up the new config 0119 kwinApp()->pluginManager()->unloadPlugin("StickyKeysPlugin"); 0120 kwinApp()->pluginManager()->loadPlugin("StickyKeysPlugin"); 0121 0122 QVERIFY(Test::waylandSeat()->hasKeyboard()); 0123 std::unique_ptr<KWayland::Client::Keyboard> keyboard(Test::waylandSeat()->createKeyboard()); 0124 0125 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0126 QVERIFY(surface != nullptr); 0127 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0128 QVERIFY(shellSurface != nullptr); 0129 Window *waylandWindow = Test::renderAndWaitForShown(surface.get(), QSize(10, 10), Qt::blue); 0130 QVERIFY(waylandWindow); 0131 waylandWindow->move(QPoint(0, 0)); 0132 0133 QSignalSpy modifierSpy(keyboard.get(), &KWayland::Client::Keyboard::modifiersChanged); 0134 QVERIFY(modifierSpy.wait()); 0135 modifierSpy.clear(); 0136 0137 quint32 timestamp = 0; 0138 0139 // press Ctrl to latch it 0140 Test::keyboardKeyPressed(KEY_LEFTCTRL, ++timestamp); 0141 QVERIFY(modifierSpy.wait()); 0142 // arguments are: quint32 depressed, quint32 latched, quint32 locked, quint32 group 0143 QCOMPARE(modifierSpy.first()[0], 4); // verify that Ctrl is depressed 0144 QCOMPARE(modifierSpy.first()[1], 4); // verify that Ctrl is latched 0145 0146 modifierSpy.clear(); 0147 // release Ctrl, the modified should still be latched 0148 Test::keyboardKeyReleased(KEY_LEFTCTRL, ++timestamp); 0149 QVERIFY(modifierSpy.wait()); 0150 QCOMPARE(modifierSpy.first()[0], 0); // verify that Ctrl is not depressed 0151 QCOMPARE(modifierSpy.first()[1], 4); // verify that Ctrl is still latched 0152 0153 // press Ctrl again to lock it 0154 modifierSpy.clear(); 0155 Test::keyboardKeyPressed(KEY_LEFTCTRL, ++timestamp); 0156 QVERIFY(modifierSpy.wait()); 0157 QCOMPARE(modifierSpy.first()[0], 4); // verify that Ctrl is depressed 0158 // TODO should it be latched? 0159 QCOMPARE(modifierSpy.first()[2], 4); // verify that Ctrl is locked 0160 0161 // press and release a letter, this does not unlock the modifier 0162 modifierSpy.clear(); 0163 Test::keyboardKeyPressed(KEY_A, ++timestamp); 0164 QVERIFY(!modifierSpy.wait(10)); 0165 0166 Test::keyboardKeyReleased(KEY_A, ++timestamp); 0167 QVERIFY(!modifierSpy.wait(10)); 0168 0169 // press Ctrl again to unlock it 0170 Test::keyboardKeyPressed(KEY_LEFTCTRL, ++timestamp); 0171 QVERIFY(modifierSpy.wait()); 0172 QCOMPARE(modifierSpy.first()[0], 4); // verify that Ctrl is depressed 0173 QCOMPARE(modifierSpy.first()[2], 0); // verify that Ctrl is locked 0174 0175 Test::keyboardKeyReleased(KEY_LEFTCTRL, ++timestamp); 0176 } 0177 } 0178 0179 WAYLANDTEST_MAIN(KWin::StickyKeysTest) 0180 #include "sticky_keys_test.moc"