From e1adef12f52e14cfcdb395ef445a47a20cb20a71 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 26 Jun 2024 12:30:03 +0200 Subject: [PATCH] keyboard mod fixes --- src/debug/HyprCtl.cpp | 2 +- src/devices/IKeyboard.cpp | 65 +++++++++++++++++------------ src/devices/IKeyboard.hpp | 5 ++- src/devices/Keyboard.cpp | 7 +--- src/managers/KeybindManager.cpp | 6 +-- src/managers/input/InputManager.cpp | 17 +------- 6 files changed, 49 insertions(+), 53 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 17663c8f..7309ac87 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1114,7 +1114,7 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap); xkb_layout_index_t activeLayout = 0; while (activeLayout < LAYOUTS) { - if (xkb_state_layout_index_is_active(KEEB->xkbTranslationState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1) + if (xkb_state_layout_index_is_active(KEEB->xkbState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1) break; activeLayout++; diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index 5ecba556..eb475b73 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -27,11 +27,11 @@ IKeyboard::~IKeyboard() { } void IKeyboard::clearManuallyAllocd() { - if (xkbTranslationState) - xkb_state_unref(xkbTranslationState); + if (xkbStaticState) + xkb_state_unref(xkbStaticState); - if (xkbInternalTranslationState) - xkb_state_unref(xkbInternalTranslationState); + if (xkbState) + xkb_state_unref(xkbState); if (xkbKeymap) xkb_keymap_unref(xkbKeymap); @@ -39,9 +39,10 @@ void IKeyboard::clearManuallyAllocd() { if (xkbKeymapFD >= 0) close(xkbKeymapFD); - xkbKeymap = nullptr; - xkbTranslationState = nullptr; - xkbKeymapFD = -1; + xkbKeymap = nullptr; + xkbState = nullptr; + xkbStaticState = nullptr; + xkbKeymapFD = -1; } void IKeyboard::setKeymap(const SStringRuleNames& rules) { @@ -99,9 +100,9 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { // set internal translation state // demo sunao ni ienai - xkbInternalTranslationState = xkb_state_new(xkbKeymap); + xkbStaticState = xkb_state_new(xkbKeymap); - updateXKBTranslationState(); + updateXKBTranslationState(xkbKeymap); const auto NUMLOCKON = g_pConfigManager->getDeviceInt(hlName, "numlock_by_default", "input:numlock_by_default"); @@ -151,17 +152,17 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { - if (xkbTranslationState) - xkb_state_unref(xkbTranslationState); + if (xkbState) + xkb_state_unref(xkbState); if (keymap) { Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this); - xkbTranslationState = xkb_state_new(keymap); + xkbState = xkb_state_new(keymap); return; } const auto KEYMAP = xkbKeymap; - const auto STATE = xkbInternalTranslationState; + const auto STATE = xkbState; const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP); const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS); @@ -200,7 +201,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); } - xkbTranslationState = xkb_state_new(KEYMAP); + xkbState = xkb_state_new(KEYMAP); xkb_keymap_unref(KEYMAP); xkb_context_unref(PCONTEXT); @@ -221,7 +222,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); - xkbTranslationState = xkb_state_new(NEWKEYMAP); + xkbState = xkb_state_new(NEWKEYMAP); xkb_keymap_unref(NEWKEYMAP); xkb_context_unref(PCONTEXT); @@ -229,7 +230,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { std::string IKeyboard::getActiveLayout() { const auto KEYMAP = xkbKeymap; - const auto STATE = xkbTranslationState; + const auto STATE = xkbState; const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP); for (uint32_t i = 0; i < LAYOUTSNUM; ++i) { @@ -246,12 +247,12 @@ std::string IKeyboard::getActiveLayout() { } void IKeyboard::updateLEDs() { - if (xkbTranslationState == nullptr) + if (xkbState == nullptr) return; uint32_t leds = 0; for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { - if (xkb_state_led_index_is_active(xkbTranslationState, ledIndexes.at(i))) + if (xkb_state_led_index_is_active(xkbState, ledIndexes.at(i))) leds |= (1 << i); } @@ -259,7 +260,7 @@ void IKeyboard::updateLEDs() { } void IKeyboard::updateLEDs(uint32_t leds) { - if (!xkbTranslationState) + if (!xkbState) return; if (isVirtual() && g_pInputManager->shouldIgnoreVirtualKeyboard(self.lock())) @@ -288,10 +289,10 @@ uint32_t IKeyboard::getModifiers() { } void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { - if (!xkbTranslationState) + if (!xkbState) return; - xkb_state_update_mask(xkbTranslationState, depressed, latched, locked, 0, 0, group); + xkb_state_update_mask(xkbState, depressed, latched, locked, 0, 0, group); if (!updateModifiersState()) return; @@ -300,13 +301,13 @@ void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t l } bool IKeyboard::updateModifiersState() { - if (!xkbTranslationState) + if (!xkbState) return false; - auto depressed = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_DEPRESSED); - auto latched = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LATCHED); - auto locked = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LOCKED); - auto group = xkb_state_serialize_layout(xkbTranslationState, XKB_STATE_LAYOUT_EFFECTIVE); + auto depressed = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED); + auto latched = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED); + auto locked = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LOCKED); + auto group = xkb_state_serialize_layout(xkbState, XKB_STATE_LAYOUT_EFFECTIVE); if (depressed == modifiersState.depressed && latched == modifiersState.latched && locked == modifiersState.locked && group == modifiersState.group) return false; @@ -318,3 +319,15 @@ bool IKeyboard::updateModifiersState() { return true; } + +void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) { + xkb_state_update_key(xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP); + if (updateModifiersState()) { + keyboardEvents.modifiers.emit(SModifiersEvent{ + .depressed = modifiersState.depressed, + .latched = modifiersState.latched, + .locked = modifiersState.locked, + .group = modifiersState.group, + }); + } +} diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp index f1f355ec..332b8ca0 100644 --- a/src/devices/IKeyboard.hpp +++ b/src/devices/IKeyboard.hpp @@ -58,12 +58,13 @@ class IKeyboard : public IHID { uint32_t getModifiers(); void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group); bool updateModifiersState(); // rets whether changed + void updateXkbStateWithKey(uint32_t xkbKey, bool pressed); bool active = false; bool enabled = true; - xkb_layout_index_t activeLayout = 0; - xkb_state * xkbTranslationState = nullptr, *xkbInternalTranslationState = nullptr; + xkb_layout_index_t activeLayout = 0; + xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr; xkb_keymap* xkbKeymap = nullptr; struct { diff --git a/src/devices/Keyboard.cpp b/src/devices/Keyboard.cpp index 56ec7bfb..867d54a8 100644 --- a/src/devices/Keyboard.cpp +++ b/src/devices/Keyboard.cpp @@ -32,12 +32,7 @@ CKeyboard::CKeyboard(SP keeb) : keyboard(keeb) { listeners.key = keeb->events.key.registerListener([this](std::any d) { auto E = std::any_cast(d); - uint32_t xkbKeycode = E.key + 8; - xkb_state_update_key(xkbTranslationState, xkbKeycode, E.pressed ? XKB_KEY_DOWN : XKB_KEY_UP); - - // we have to do this for DRM sessions, as they never send modifiers events - if (g_pCompositor->m_pAqBackend->hasSession()) - updateModifiersState(); + updateXkbStateWithKey(E.key + 8, E.pressed); keyboardEvents.key.emit(SKeyEvent{ .timeMs = E.timeMs, diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 69b089d0..03149810 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -366,8 +366,8 @@ bool CKeybindManager::onKeyEvent(std::any event, SP pKeyboard) { const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput - const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbTranslationState : m_pXKBTranslationState, KEYCODE); - const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbInternalTranslationState, KEYCODE); + const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbStaticState : m_pXKBTranslationState, KEYCODE); + const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbState, KEYCODE); if (handleInternalKeybinds(internalKeysym)) return true; @@ -2121,7 +2121,7 @@ void CKeybindManager::sendshortcut(std::string args) { if (!g_pKeybindManager->m_mKeyToCodeCache.contains(KEYPAIRSTRING)) { xkb_keymap* km = KB->xkbKeymap; - xkb_state* ks = KB->xkbTranslationState; + xkb_state* ks = KB->xkbState; xkb_keycode_t keycode_min, keycode_max; keycode_min = xkb_keymap_min_keycode(km); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 28a050c1..cd3501b7 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1156,10 +1156,6 @@ static void removeFromHIDs(WP hid) { } void CInputManager::destroyKeyboard(SP pKeyboard) { - if (pKeyboard->xkbTranslationState) - xkb_state_unref(pKeyboard->xkbTranslationState); - pKeyboard->xkbTranslationState = nullptr; - std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; }); if (m_vKeyboards.size() > 0) { @@ -1225,19 +1221,10 @@ void CInputManager::destroyTabletPad(SP pad) { } void CInputManager::updateKeyboardsLeds(SP pKeyboard) { - if (!pKeyboard || !pKeyboard->xkbTranslationState) + if (!pKeyboard) return; - // FIXME: - // uint32_t leds = 0; - // for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { - // if (xkb_state_led_index_is_active(pKeyboard->xkbTranslationState, keyboard->led_indexes[i])) - // leds |= (1 << i); - // } - - // for (auto& k : m_vKeyboards) { - // k->updateLEDs(leds); - // } + pKeyboard->updateLEDs(); } void CInputManager::onKeyboardKey(std::any event, SP pKeyboard) {