mirror of
https://github.com/hyprwm/Hyprland.git
synced 2024-12-27 01:34:24 +03:00
keyboard: properly update keymap state and fd on keymap changes
needed for virtual keyboards that impose their own layouts. fixes #6991
This commit is contained in:
parent
4beac91cbd
commit
daf5fad190
@ -51,6 +51,11 @@ void IKeyboard::clearManuallyAllocd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
||||||
|
if (keymapOverridden) {
|
||||||
|
Debug::log(LOG, "Ignoring setKeymap: keymap is overridden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentRules = rules;
|
currentRules = rules;
|
||||||
xkb_rule_names XKBRULES = {
|
xkb_rule_names XKBRULES = {
|
||||||
.rules = rules.rules.c_str(),
|
.rules = rules.rules.c_str(),
|
||||||
@ -103,10 +108,6 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
|||||||
xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set internal translation state
|
|
||||||
// demo sunao ni ienai
|
|
||||||
xkbStaticState = xkb_state_new(xkbKeymap);
|
|
||||||
|
|
||||||
updateXKBTranslationState(xkbKeymap);
|
updateXKBTranslationState(xkbKeymap);
|
||||||
|
|
||||||
const auto NUMLOCKON = g_pConfigManager->getDeviceInt(hlName, "numlock_by_default", "input:numlock_by_default");
|
const auto NUMLOCKON = g_pConfigManager->getDeviceInt(hlName, "numlock_by_default", "input:numlock_by_default");
|
||||||
@ -131,6 +132,20 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
|||||||
Debug::log(LOG, "xkb: Mod index {} (name {}) got index {}", i, MODNAMES.at(i), modIndexes.at(i));
|
Debug::log(LOG, "xkb: Mod index {} (name {}) got index {}", i, MODNAMES.at(i), modIndexes.at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateKeymapFD();
|
||||||
|
|
||||||
|
xkb_context_unref(CONTEXT);
|
||||||
|
|
||||||
|
g_pSeatManager->updateActiveKeyboardData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IKeyboard::updateKeymapFD() {
|
||||||
|
Debug::log(LOG, "Updating keymap fd for keyboard {}", deviceName);
|
||||||
|
|
||||||
|
if (xkbKeymapFD >= 0)
|
||||||
|
close(xkbKeymapFD);
|
||||||
|
xkbKeymapFD = -1;
|
||||||
|
|
||||||
auto cKeymapStr = xkb_keymap_get_as_string(xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
auto cKeymapStr = xkb_keymap_get_as_string(xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||||
xkbKeymapString = cKeymapStr;
|
xkbKeymapString = cKeymapStr;
|
||||||
free(cKeymapStr);
|
free(cKeymapStr);
|
||||||
@ -151,21 +166,24 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xkb_context_unref(CONTEXT);
|
Debug::log(LOG, "Updated keymap fd to {}", xkbKeymapFD);
|
||||||
|
|
||||||
g_pSeatManager->updateActiveKeyboardData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||||
|
|
||||||
|
if (xkbStaticState)
|
||||||
|
xkb_state_unref(xkbStaticState);
|
||||||
|
|
||||||
if (xkbState)
|
if (xkbState)
|
||||||
xkb_state_unref(xkbState);
|
xkb_state_unref(xkbState);
|
||||||
|
|
||||||
xkbState = nullptr;
|
xkbState = nullptr;
|
||||||
|
xkbStaticState = nullptr;
|
||||||
|
|
||||||
if (keymap) {
|
if (keymap) {
|
||||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
||||||
xkbState = xkb_state_new(keymap);
|
xkbStaticState = xkb_state_new(keymap);
|
||||||
|
xkbState = xkb_state_new(keymap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +227,8 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
|||||||
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
xkbState = xkb_state_new(KEYMAP);
|
xkbState = xkb_state_new(KEYMAP);
|
||||||
|
xkbStaticState = xkb_state_new(KEYMAP);
|
||||||
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
xkb_keymap_unref(KEYMAP);
|
||||||
xkb_context_unref(PCONTEXT);
|
xkb_context_unref(PCONTEXT);
|
||||||
@ -230,7 +249,8 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
|||||||
|
|
||||||
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
xkbState = xkb_state_new(NEWKEYMAP);
|
xkbState = xkb_state_new(NEWKEYMAP);
|
||||||
|
xkbStaticState = xkb_state_new(NEWKEYMAP);
|
||||||
|
|
||||||
xkb_keymap_unref(NEWKEYMAP);
|
xkb_keymap_unref(NEWKEYMAP);
|
||||||
xkb_context_unref(PCONTEXT);
|
xkb_context_unref(PCONTEXT);
|
||||||
|
@ -61,18 +61,24 @@ class IKeyboard : public IHID {
|
|||||||
std::string rules = "";
|
std::string rules = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
void setKeymap(const SStringRuleNames& rules);
|
void setKeymap(const SStringRuleNames& rules);
|
||||||
void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
|
void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
|
||||||
std::string getActiveLayout();
|
std::string getActiveLayout();
|
||||||
void updateLEDs();
|
void updateLEDs();
|
||||||
void updateLEDs(uint32_t leds);
|
void updateLEDs(uint32_t leds);
|
||||||
uint32_t getModifiers();
|
uint32_t getModifiers();
|
||||||
void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
|
void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
|
||||||
bool updateModifiersState(); // rets whether changed
|
bool updateModifiersState(); // rets whether changed
|
||||||
void updateXkbStateWithKey(uint32_t xkbKey, bool pressed);
|
void updateXkbStateWithKey(uint32_t xkbKey, bool pressed);
|
||||||
|
void updateKeymapFD();
|
||||||
|
|
||||||
bool active = false;
|
bool active = false;
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
|
||||||
|
// if the keymap is overridden by the implementation,
|
||||||
|
// don't try to set keyboard rules anymore, to avoid overwriting the requested one.
|
||||||
|
// e.g. Virtual keyboards with custom maps.
|
||||||
|
bool keymapOverridden = false;
|
||||||
|
|
||||||
xkb_layout_index_t activeLayout = 0;
|
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_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr;
|
||||||
|
@ -31,8 +31,13 @@ CVirtualKeyboard::CVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keeb_) : keybo
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
listeners.keymap = keeb_->events.keymap.registerListener([this](std::any d) {
|
listeners.keymap = keeb_->events.keymap.registerListener([this](std::any d) {
|
||||||
auto E = std::any_cast<SKeymapEvent>(d);
|
auto E = std::any_cast<SKeymapEvent>(d);
|
||||||
xkbKeymap = xkb_keymap_ref(E.keymap);
|
if (xkbKeymap)
|
||||||
|
xkb_keymap_unref(xkbKeymap);
|
||||||
|
xkbKeymap = xkb_keymap_ref(E.keymap);
|
||||||
|
keymapOverridden = true;
|
||||||
|
updateXKBTranslationState(xkbKeymap);
|
||||||
|
updateKeymapFD();
|
||||||
keyboardEvents.keymap.emit(d);
|
keyboardEvents.keymap.emit(d);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user