diff options
author | Vaxry <[email protected]> | 2024-03-02 01:46:16 +0000 |
---|---|---|
committer | Vaxry <[email protected]> | 2024-03-02 01:46:55 +0000 |
commit | 7ce781e87cf7cf789a54d37af7d78f1c11d66dbc (patch) | |
tree | df83040065961dcfd48eb713da1355c652238d77 | |
parent | b2c34404777ea0850f90f4c38f64484f03599d14 (diff) | |
download | Hyprland-7ce781e87cf7cf789a54d37af7d78f1c11d66dbc.tar.gz Hyprland-7ce781e87cf7cf789a54d37af7d78f1c11d66dbc.zip |
keybinds: better follow xkb translation state
fixes #4908
-rw-r--r-- | src/helpers/WLClasses.cpp | 64 | ||||
-rw-r--r-- | src/helpers/WLClasses.hpp | 2 | ||||
-rw-r--r-- | src/managers/input/InputManager.cpp | 7 |
3 files changed, 70 insertions, 3 deletions
diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 31db2c55..3cf170bf 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -242,3 +242,67 @@ Vector2D SConstraint::getLogicConstraintSize() { return SIZE; } + +void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { + xkb_state_unref(xkbTranslationState); + + if (keymap) { + Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this); + xkbTranslationState = xkb_state_new(keymap); + return; + } + + const auto WLRKB = wlr_keyboard_from_input_device(keyboard); + const auto KEYMAP = WLRKB->keymap; + const auto STATE = WLRKB->xkb_state; + const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP); + + const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + + for (uint32_t i = 0; i < LAYOUTSNUM; ++i) { + if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) { + Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i); + + CVarList keyboardLayouts(currentRules.layout, 0, ','); + CVarList keyboardModels(currentRules.model, 0, ','); + CVarList keyboardVariants(currentRules.variant, 0, ','); + + xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""}; + + std::string layout, model, variant; + layout = keyboardLayouts[i % keyboardLayouts.size()]; + model = keyboardModels[i % keyboardLayouts.size()]; + variant = keyboardVariants[i % keyboardLayouts.size()]; + + rules.layout = layout.c_str(); + rules.model = model.c_str(); + rules.variant = variant.c_str(); + + const auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + + xkbTranslationState = xkb_state_new(KEYMAP); + + xkb_keymap_unref(KEYMAP); + xkb_context_unref(PCONTEXT); + + return; + } + } + + Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this); + + xkb_rule_names rules = { + .rules = currentRules.rules.c_str(), + .model = currentRules.model.c_str(), + .layout = currentRules.layout.c_str(), + .variant = currentRules.variant.c_str(), + .options = currentRules.options.c_str(), + }; + + const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + + xkbTranslationState = xkb_state_new(NEWKEYMAP); + + xkb_keymap_unref(NEWKEYMAP); + xkb_context_unref(PCONTEXT); +} diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index c9cb47e4..b1c6c9d7 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -148,6 +148,8 @@ struct SKeyboard { int numlockOn = -1; bool resolveBindsBySym = false; + void updateXKBTranslationState(xkb_keymap* const keymap = nullptr); + // For the list lookup bool operator==(const SKeyboard& rhs) const { return keyboard == rhs.keyboard; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 5944ba87..989d863a 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -908,11 +908,10 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) { KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); } - xkb_state_unref(pKeyboard->xkbTranslationState); - pKeyboard->xkbTranslationState = xkb_state_new(KEYMAP); - wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP); + pKeyboard->updateXKBTranslationState(); + wlr_keyboard_modifiers wlrMods = {0}; if (NUMLOCKON == 1) { @@ -1246,6 +1245,8 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) { const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard); + pKeyboard->updateXKBTranslationState(); + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT}); EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT})); } |