keybinds: better follow xkb translation state

fixes #4908
This commit is contained in:
Vaxry 2024-03-02 01:46:16 +00:00
parent b2c3440477
commit 7ce781e87c
3 changed files with 70 additions and 3 deletions

View file

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

View file

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

View file

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