File indexing completed on 2024-04-28 07:42:53

0001 /*
0002     SPDX-FileCopyrightText: 2019 Aleix Pol Gonzalez <aleixpol@kde.org>
0003     SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "kmodifierkeyinfoprovider_wayland.h"
0009 #include <QDebug>
0010 #include <QGuiApplication>
0011 
0012 #include <QWaylandClientExtensionTemplate>
0013 #include <wayland-client-core.h>
0014 
0015 #include "qwayland-keystate.h"
0016 
0017 class KeyState : public QWaylandClientExtensionTemplate<KeyState>, public QtWayland::org_kde_kwin_keystate
0018 {
0019     Q_OBJECT
0020 public:
0021     KeyState()
0022         : QWaylandClientExtensionTemplate<KeyState>(4)
0023     {
0024     }
0025 
0026     ~KeyState()
0027     {
0028         if (isInitialized() && qGuiApp) {
0029             if (QtWayland::org_kde_kwin_keystate::version() >= ORG_KDE_KWIN_KEYSTATE_DESTROY_SINCE_VERSION) {
0030                 destroy();
0031             } else {
0032                 wl_proxy_destroy(reinterpret_cast<struct wl_proxy *>(object()));
0033             }
0034         }
0035     }
0036 
0037     void org_kde_kwin_keystate_stateChanged(uint32_t key, uint32_t state) override
0038     {
0039         Q_EMIT stateChanged(toKey(static_cast<KeyState::key>(key)), toState(static_cast<KeyState::state>(state)));
0040     }
0041 
0042     KModifierKeyInfoProvider::ModifierState toState(KeyState::state state)
0043     {
0044         switch (state) {
0045         case KeyState::state::state_unlocked:
0046             return KModifierKeyInfoProvider::Nothing;
0047         case KeyState::state::state_locked:
0048             return KModifierKeyInfoProvider::Locked;
0049         case KeyState::state::state_latched:
0050             return KModifierKeyInfoProvider::Latched;
0051         }
0052         Q_UNREACHABLE();
0053         return KModifierKeyInfoProvider::Nothing;
0054     }
0055 
0056     Qt::Key toKey(KeyState::key key)
0057     {
0058         switch (key) {
0059         case KeyState::key::key_capslock:
0060             return Qt::Key_CapsLock;
0061         case KeyState::key::key_numlock:
0062             return Qt::Key_NumLock;
0063         case KeyState::key::key_scrolllock:
0064             return Qt::Key_ScrollLock;
0065         }
0066         Q_UNREACHABLE();
0067         return {};
0068     }
0069 
0070     Q_SIGNAL void stateChanged(Qt::Key key, KModifierKeyInfoProvider::ModifierState state);
0071 };
0072 
0073 KModifierKeyInfoProviderWayland::KModifierKeyInfoProviderWayland()
0074 {
0075     m_keystate = new KeyState;
0076 
0077     QObject::connect(m_keystate, &KeyState::activeChanged, this, [this]() {
0078         if (m_keystate->isActive()) {
0079             m_keystate->fetchStates();
0080         }
0081     });
0082 
0083     connect(m_keystate, &KeyState::stateChanged, this, &KModifierKeyInfoProviderWayland::stateUpdated);
0084 
0085     stateUpdated(Qt::Key_CapsLock, KModifierKeyInfoProvider::Nothing);
0086     stateUpdated(Qt::Key_NumLock, KModifierKeyInfoProvider::Nothing);
0087     stateUpdated(Qt::Key_ScrollLock, KModifierKeyInfoProvider::Nothing);
0088 }
0089 
0090 KModifierKeyInfoProviderWayland::~KModifierKeyInfoProviderWayland()
0091 {
0092     delete m_keystate;
0093 }
0094 
0095 bool KModifierKeyInfoProviderWayland::setKeyLatched(Qt::Key /*key*/, bool /*latched*/)
0096 {
0097     return false;
0098 }
0099 
0100 bool KModifierKeyInfoProviderWayland::setKeyLocked(Qt::Key /*key*/, bool /*locked*/)
0101 {
0102     return false;
0103 }
0104 
0105 #include "kmodifierkeyinfoprovider_wayland.moc"
0106 #include "moc_kmodifierkeyinfoprovider_wayland.cpp"