From 2be309de1df5e4262175fbcc58e6dd8de4e0e6d3 Mon Sep 17 00:00:00 2001 From: JS Deck Date: Mon, 4 Aug 2025 16:29:39 -0300 Subject: virtualkeyboard: Add options to skip releasing pressed keys on close and to skip sharing key states (#11214) --- src/devices/IKeyboard.cpp | 37 ++++++++++++++++++++++++------------- src/devices/IKeyboard.hpp | 19 ++++++++++++++----- src/devices/Keyboard.cpp | 5 ++++- src/devices/VirtualKeyboard.cpp | 10 ++++++++-- src/devices/VirtualKeyboard.hpp | 2 +- 5 files changed, 51 insertions(+), 22 deletions(-) (limited to 'src/devices') diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index 89ad8c16..0a22eb6e 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -378,19 +378,6 @@ bool IKeyboard::updateModifiersState() { } void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) { - - const auto contains = std::ranges::find(m_pressedXKB, xkbKey) != m_pressedXKB.end(); - - if (contains && pressed) - return; - if (!contains && !pressed) - return; - - if (contains) - std::erase(m_pressedXKB, xkbKey); - else - m_pressedXKB.emplace_back(xkbKey); - xkb_state_update_key(m_xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP); if (updateModifiersState()) { @@ -405,3 +392,27 @@ void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) { }); } } + +bool IKeyboard::updatePressed(uint32_t key, bool pressed) { + const auto contains = getPressed(key); + + if (contains && pressed) + return false; + if (!contains && !pressed) + return false; + + if (contains) + std::erase(m_pressed, key); + else + m_pressed.emplace_back(key); + + return true; +} + +bool IKeyboard::getPressed(uint32_t key) { + return std::ranges::contains(m_pressed, key); +} + +bool IKeyboard::shareStates() { + return m_shareStates; +} diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp index 25a7efd1..f4fb667b 100644 --- a/src/devices/IKeyboard.hpp +++ b/src/devices/IKeyboard.hpp @@ -24,10 +24,13 @@ enum eKeyboardModifiers { class IKeyboard : public IHID { public: virtual ~IKeyboard(); - virtual uint32_t getCapabilities(); - virtual eHIDType getType(); - virtual bool isVirtual() = 0; - virtual SP aq() = 0; + virtual uint32_t getCapabilities(); + virtual eHIDType getType(); + virtual bool isVirtual() = 0; + virtual wl_client* getClient() { + return nullptr; + }; + virtual SP aq() = 0; struct SKeyEvent { uint32_t timeMs = 0; @@ -73,6 +76,8 @@ class IKeyboard : public IHID { bool updateModifiersState(); // rets whether changed void updateXkbStateWithKey(uint32_t xkbKey, bool pressed); void updateKeymapFD(); + bool getPressed(uint32_t key); + bool shareStates(); bool m_active = false; bool m_enabled = true; @@ -118,5 +123,9 @@ class IKeyboard : public IHID { private: void clearManuallyAllocd(); - std::vector m_pressedXKB; + std::vector m_pressed; + + protected: + bool updatePressed(uint32_t key, bool pressed); + bool m_shareStates = true; }; diff --git a/src/devices/Keyboard.cpp b/src/devices/Keyboard.cpp index 9ce37e6b..80f76c17 100644 --- a/src/devices/Keyboard.cpp +++ b/src/devices/Keyboard.cpp @@ -29,13 +29,16 @@ CKeyboard::CKeyboard(SP keeb) : m_keyboard(keeb) { }); m_listeners.key = keeb->events.key.listen([this](const Aquamarine::IKeyboard::SKeyEvent& event) { + const auto UPDATED = updatePressed(event.key, event.pressed); + m_keyboardEvents.key.emit(SKeyEvent{ .timeMs = event.timeMs, .keycode = event.key, .state = event.pressed ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED, }); - updateXkbStateWithKey(event.key + 8, event.pressed); + if (UPDATED) + updateXkbStateWithKey(event.key + 8, event.pressed); }); m_listeners.modifiers = keeb->events.modifiers.listen([this] { diff --git a/src/devices/VirtualKeyboard.cpp b/src/devices/VirtualKeyboard.cpp index ea21a22b..97b7626a 100644 --- a/src/devices/VirtualKeyboard.cpp +++ b/src/devices/VirtualKeyboard.cpp @@ -1,6 +1,8 @@ #include "VirtualKeyboard.hpp" #include "../defines.hpp" #include "../protocols/VirtualKeyboard.hpp" +#include "../config/ConfigManager.hpp" +#include SP CVirtualKeyboard::create(SP keeb) { SP pKeeb = SP(new CVirtualKeyboard(keeb)); @@ -19,7 +21,10 @@ CVirtualKeyboard::CVirtualKeyboard(SP keeb_) : m_key m_events.destroy.emit(); }); - m_listeners.key = keeb_->m_events.key.listen([this](const auto& event) { m_keyboardEvents.key.emit(event); }); + m_listeners.key = keeb_->m_events.key.listen([this](const auto& event) { + updatePressed(event.keycode, event.state == WL_KEYBOARD_KEY_STATE_PRESSED); + m_keyboardEvents.key.emit(event); + }); m_listeners.modifiers = keeb_->m_events.modifiers.listen([this](const SModifiersEvent& event) { updateModifiers(event.depressed, event.latched, event.locked, event.group); m_keyboardEvents.modifiers.emit(SModifiersEvent{ @@ -39,7 +44,8 @@ CVirtualKeyboard::CVirtualKeyboard(SP keeb_) : m_key m_keyboardEvents.keymap.emit(event); }); - m_deviceName = keeb_->m_name; + m_deviceName = keeb_->m_name; + m_shareStates = g_pConfigManager->getDeviceInt(m_deviceName, "share_states", "input:virtualkeyboard:share_states"); } bool CVirtualKeyboard::isVirtual() { diff --git a/src/devices/VirtualKeyboard.hpp b/src/devices/VirtualKeyboard.hpp index 05e0a255..a0783d93 100644 --- a/src/devices/VirtualKeyboard.hpp +++ b/src/devices/VirtualKeyboard.hpp @@ -11,7 +11,7 @@ class CVirtualKeyboard : public IKeyboard { virtual bool isVirtual(); virtual SP aq(); - wl_client* getClient(); + virtual wl_client* getClient(); private: CVirtualKeyboard(SP keeb); -- cgit v1.2.3