virtualkeyboard: Add options to skip releasing pressed keys on close and to skip sharing key states (#11214)

This commit is contained in:
JS Deck 2025-08-04 16:29:39 -03:00 committed by GitHub
parent 6491bb4fb7
commit 2be309de1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 416 additions and 137 deletions

View file

@ -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;
}

View file

@ -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<Aquamarine::IKeyboard> aq() = 0;
virtual uint32_t getCapabilities();
virtual eHIDType getType();
virtual bool isVirtual() = 0;
virtual wl_client* getClient() {
return nullptr;
};
virtual SP<Aquamarine::IKeyboard> 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<uint32_t> m_pressedXKB;
std::vector<uint32_t> m_pressed;
protected:
bool updatePressed(uint32_t key, bool pressed);
bool m_shareStates = true;
};

View file

@ -29,13 +29,16 @@ CKeyboard::CKeyboard(SP<Aquamarine::IKeyboard> 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] {

View file

@ -1,6 +1,8 @@
#include "VirtualKeyboard.hpp"
#include "../defines.hpp"
#include "../protocols/VirtualKeyboard.hpp"
#include "../config/ConfigManager.hpp"
#include <wayland-server-protocol.h>
SP<CVirtualKeyboard> CVirtualKeyboard::create(SP<CVirtualKeyboardV1Resource> keeb) {
SP<CVirtualKeyboard> pKeeb = SP<CVirtualKeyboard>(new CVirtualKeyboard(keeb));
@ -19,7 +21,10 @@ CVirtualKeyboard::CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> 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<CVirtualKeyboardV1Resource> 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() {

View file

@ -11,7 +11,7 @@ class CVirtualKeyboard : public IKeyboard {
virtual bool isVirtual();
virtual SP<Aquamarine::IKeyboard> aq();
wl_client* getClient();
virtual wl_client* getClient();
private:
CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb);