File indexing completed on 2024-05-19 09:23:02

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_bounce_keys-0");
0028 
0029 class BounceKeysTest : public QObject
0030 {
0031     Q_OBJECT
0032 private Q_SLOTS:
0033     void initTestCase();
0034     void init();
0035     void cleanup();
0036     void testBounce();
0037 };
0038 
0039 void BounceKeysTest::initTestCase()
0040 {
0041     KConfig kaccessConfig("kaccessrc");
0042     kaccessConfig.group(QStringLiteral("Keyboard")).writeEntry("BounceKeys", true);
0043     kaccessConfig.group(QStringLiteral("Keyboard")).writeEntry("BounceKeysDelay", 200);
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 BounceKeysTest::init()
0061 {
0062     QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat));
0063     QVERIFY(Test::waitForWaylandKeyboard());
0064 }
0065 
0066 void BounceKeysTest::cleanup()
0067 {
0068     Test::destroyWaylandConnection();
0069 }
0070 
0071 void BounceKeysTest::testBounce()
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     QVERIFY(keyboard);
0083     QSignalSpy enteredSpy(keyboard.get(), &KWayland::Client::Keyboard::entered);
0084     QVERIFY(enteredSpy.wait());
0085 
0086     QSignalSpy keySpy(keyboard.get(), &KWayland::Client::Keyboard::keyChanged);
0087     QVERIFY(keySpy.isValid());
0088 
0089     quint32 timestamp = 0;
0090 
0091     // Press a key, verify that it goes through
0092     Test::keyboardKeyPressed(KEY_A, timestamp);
0093     QVERIFY(keySpy.wait());
0094     QCOMPARE(keySpy.first()[0], KEY_A);
0095     QCOMPARE(keySpy.first()[1].value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Pressed);
0096     keySpy.clear();
0097 
0098     Test::keyboardKeyReleased(KEY_A, timestamp++);
0099     QVERIFY(keySpy.wait());
0100     QCOMPARE(keySpy.first()[0], KEY_A);
0101     QCOMPARE(keySpy.first()[1].value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
0102     keySpy.clear();
0103 
0104     // Press it again within the bounce interval, verify that it does *not* go through
0105     timestamp += 100;
0106     Test::keyboardKeyPressed(KEY_A, timestamp);
0107     QVERIFY(!keySpy.wait(100));
0108     keySpy.clear();
0109 
0110     // Press it again after the bouce interval, verify that it does go through
0111     timestamp += 1000;
0112     Test::keyboardKeyPressed(KEY_A, timestamp);
0113     QVERIFY(keySpy.wait());
0114     QCOMPARE(keySpy.first()[0], KEY_A);
0115     QCOMPARE(keySpy.first()[1].value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Pressed);
0116     keySpy.clear();
0117 
0118     Test::keyboardKeyReleased(KEY_A, timestamp++);
0119     QVERIFY(keySpy.wait());
0120     QCOMPARE(keySpy.first()[0], KEY_A);
0121     QCOMPARE(keySpy.first()[1].value<KWayland::Client::Keyboard::KeyState>(), KWayland::Client::Keyboard::KeyState::Released);
0122     keySpy.clear();
0123 }
0124 }
0125 
0126 WAYLANDTEST_MAIN(KWin::BounceKeysTest)
0127 #include "bounce_keys_test.moc"