diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS IdleTime WindowSystem + GuiAddons ) find_package(KF5Wayland CONFIG REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(idletime) add_subdirectory(windowsystem) +add_subdirectory(kmodifierkeyinfoprovider) diff --git a/src/kmodifierkeyinfoprovider/CMakeLists.txt b/src/kmodifierkeyinfoprovider/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/kmodifierkeyinfoprovider/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(kmodifierkey_wayland MODULE kmodifierkeyinfoprovider_wayland.cpp) +target_link_libraries(kmodifierkey_wayland PRIVATE KF5::WaylandClient KF5::GuiAddons) +install(TARGETS kmodifierkey_wayland DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kguiaddons/kmodifierkey/) diff --git a/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.h b/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.h new file mode 100644 --- /dev/null +++ b/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.h @@ -0,0 +1,45 @@ +/* + Copyright 2019 Aleix Pol Gonzalez + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef KMODIFIERKEYINFOPROVIDERWAYLAND_H +#define KMODIFIERKEYINFOPROVIDERWAYLAND_H + +#include +#include +#include + +class KModifierKeyInfoProviderWayland : public KModifierKeyInfoProvider +{ +Q_OBJECT +Q_PLUGIN_METADATA(IID "org.kde.kguiaddons.KModifierKeyInfoProvider.Wayland") +public: + KModifierKeyInfoProviderWayland(); + ~KModifierKeyInfoProviderWayland(); + + bool setKeyLatched(Qt::Key key, bool latched) override; + bool setKeyLocked(Qt::Key key, bool locked) override; + +private: + void updateModifiers(KWayland::Client::Keystate::Key key, KWayland::Client::Keystate::State state); + + QPointer m_keystate; +}; + +#endif diff --git a/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.cpp b/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.cpp new file mode 100644 --- /dev/null +++ b/src/kmodifierkeyinfoprovider/kmodifierkeyinfoprovider_wayland.cpp @@ -0,0 +1,97 @@ +/* + Copyright 2019 Aleix Pol Gonzalez + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRAKModifierKeyInfoProviderNTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "kmodifierkeyinfoprovider_wayland.h" +#include +#include +#include +#include +#include + +using namespace KWayland::Client; + +KModifierKeyInfoProviderWayland::KModifierKeyInfoProviderWayland() +{ + auto registry = new Registry(this); + + auto m_waylandConnection = ConnectionThread::fromApplication(this); + if (!m_waylandConnection) { + qWarning() << "Failed getting Wayland connection from QPA"; + return; + } + registry->create(m_waylandConnection); + registry->setup(); + + const auto ifaces = registry->interfaces(KWayland::Client::Registry::Interface::Keystate); + connect(registry, &Registry::keystateAnnounced, this, [this, registry](quint32 name, quint32 version) { + m_keystate = registry->createKeystate(name, version, this); + connect(m_keystate, &Keystate::stateChanged, this, &KModifierKeyInfoProviderWayland::updateModifiers); + m_keystate->fetchStates(); + }); + + stateUpdated(Qt::Key_CapsLock, KModifierKeyInfoProvider::Nothing); + stateUpdated(Qt::Key_NumLock, KModifierKeyInfoProvider::Nothing); + stateUpdated(Qt::Key_ScrollLock, KModifierKeyInfoProvider::Nothing); +} + +KModifierKeyInfoProviderWayland::~KModifierKeyInfoProviderWayland() = default; + +bool KModifierKeyInfoProviderWayland::setKeyLatched(Qt::Key /*key*/, bool /*latched*/) +{ + return false; +} + +bool KModifierKeyInfoProviderWayland::setKeyLocked(Qt::Key /*key*/, bool /*locked*/) +{ + return false; +} + +KModifierKeyInfoProvider::ModifierState toState(Keystate::State state) +{ + switch(state) { + case Keystate::State::Unlocked: + return KModifierKeyInfoProvider::Nothing; + case Keystate::State::Latched: + return KModifierKeyInfoProvider::Latched; + case Keystate::State::Locked: + return KModifierKeyInfoProvider::Locked; + } + Q_UNREACHABLE(); + return KModifierKeyInfoProvider::Nothing; +} + +Qt::Key toKey(Keystate::Key key) +{ + switch(key) { + case Keystate::Key::CapsLock: + return Qt::Key_CapsLock; + case Keystate::Key::NumLock: + return Qt::Key_NumLock; + case Keystate::Key::ScrollLock: + return Qt::Key_ScrollLock; + } + Q_UNREACHABLE(); + return {}; +} + +void KModifierKeyInfoProviderWayland::updateModifiers(Keystate::Key key, Keystate::State state) +{ + stateUpdated(toKey(key), toState(state)); +}