diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index ee8fa240..70d3dfc9 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -429,7 +429,7 @@ inline static const std::vector CONFIG_OPTIONS = { }, SConfigOptionDescription{ .value = "input:kb_file", - .description = "Appropriate XKB keymap parameter", + .description = "Appropriate XKB keymap file", .type = CONFIG_OPTION_STRING_LONG, .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? }, diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index ad9e40d8..0fc30ca9 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -43,14 +43,19 @@ void IKeyboard::clearManuallyAllocd() { if (m_xkbKeymap) xkb_keymap_unref(m_xkbKeymap); + if (m_xkbKeymapV1) + xkb_keymap_unref(m_xkbKeymapV1); + if (m_xkbSymState) xkb_state_unref(m_xkbSymState); m_xkbSymState = nullptr; m_xkbKeymap = nullptr; + m_xkbKeymapV1 = nullptr; m_xkbState = nullptr; m_xkbStaticState = nullptr; m_xkbKeymapFD.reset(); + m_xkbKeymapV1FD.reset(); } void IKeyboard::setKeymap(const SStringRuleNames& rules) { @@ -86,13 +91,13 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { if (FILE* const KEYMAPFILE = fopen(path.c_str(), "r"); !KEYMAPFILE) Debug::log(ERR, "Cannot open input:kb_file= file for reading"); else { - m_xkbKeymap = xkb_keymap_new_from_file(CONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + m_xkbKeymap = xkb_keymap_new_from_file(CONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); fclose(KEYMAPFILE); } } if (!m_xkbKeymap) - m_xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS); + m_xkbKeymap = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!m_xkbKeymap) { g_pConfigManager->addParseError("Invalid keyboard layout passed. ( rules: " + rules.rules + ", model: " + rules.model + ", variant: " + rules.variant + @@ -108,7 +113,16 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { m_currentRules.options = ""; m_currentRules.layout = "us"; - m_xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS); + m_xkbKeymap = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); + } + + auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (!cKeymapStr) { + Debug::log(ERR, "Couldn't convert keymap to V1 format"); + m_xkbKeymapV1 = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + } else { + m_xkbKeymapV1 = xkb_keymap_new_from_string(CONTEXT, cKeymapStr, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + free(cKeymapStr); } updateXKBTranslationState(m_xkbKeymap); @@ -149,27 +163,44 @@ void IKeyboard::updateKeymapFD() { if (m_xkbKeymapFD.isValid()) m_xkbKeymapFD.reset(); - auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (m_xkbKeymapV1FD.isValid()) + m_xkbKeymapV1FD.reset(); + + auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V2); m_xkbKeymapString = cKeymapStr; free(cKeymapStr); + auto cKeymapV1Str = xkb_keymap_get_as_string(m_xkbKeymapV1, XKB_KEYMAP_FORMAT_TEXT_V1); + m_xkbKeymapV1String = cKeymapV1Str; + free(cKeymapV1Str); - CFileDescriptor rw, ro; + CFileDescriptor rw, ro, rwV1, roV1; if (!allocateSHMFilePair(m_xkbKeymapString.length() + 1, rw, ro)) Debug::log(ERR, "IKeyboard: failed to allocate shm pair for the keymap"); - else { - auto keymapFDDest = mmap(nullptr, m_xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0); + else if (!allocateSHMFilePair(m_xkbKeymapV1String.length() + 1, rwV1, roV1)) { + ro.reset(); rw.reset(); - if (keymapFDDest == MAP_FAILED) { + Debug::log(ERR, "IKeyboard: failed to allocate shm pair for keymap V1"); + } else { + auto keymapFDDest = mmap(nullptr, m_xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0); + auto keymapV1FDDest = mmap(nullptr, m_xkbKeymapV1String.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rwV1.get(), 0); + rw.reset(); + rwV1.reset(); + + if (keymapFDDest == MAP_FAILED || keymapV1FDDest == MAP_FAILED) { Debug::log(ERR, "IKeyboard: failed to mmap a shm pair for the keymap"); ro.reset(); + roV1.reset(); } else { memcpy(keymapFDDest, m_xkbKeymapString.c_str(), m_xkbKeymapString.length()); munmap(keymapFDDest, m_xkbKeymapString.length() + 1); m_xkbKeymapFD = std::move(ro); + memcpy(keymapV1FDDest, m_xkbKeymapV1String.c_str(), m_xkbKeymapV1String.length()); + munmap(keymapV1FDDest, m_xkbKeymapV1String.length() + 1); + m_xkbKeymapV1FD = std::move(roV1); } } - Debug::log(LOG, "Updated keymap fd to {}", m_xkbKeymapFD.get()); + Debug::log(LOG, "Updated keymap fd to {}, keymap V1 to: {}", m_xkbKeymapFD.get(), m_xkbKeymapV1FD.get()); } void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { @@ -220,19 +251,19 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { rules.model = model.c_str(); rules.variant = variant.c_str(); - auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + auto KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!KEYMAP) { Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant"); rules.model = ""; rules.variant = ""; - KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); } if (!KEYMAP) { Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us"); rules.layout = "us"; - KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); } m_xkbState = xkb_state_new(KEYMAP); @@ -256,7 +287,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { .options = m_currentRules.options.c_str(), }; - const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + const auto NEWKEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); m_xkbState = xkb_state_new(NEWKEYMAP); m_xkbStaticState = xkb_state_new(NEWKEYMAP); diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp index c7832548..9e4bea4e 100644 --- a/src/devices/IKeyboard.hpp +++ b/src/devices/IKeyboard.hpp @@ -99,7 +99,8 @@ class IKeyboard : public IHID { xkb_state* m_xkbStaticState = nullptr; xkb_state* m_xkbSymState = nullptr; // same as static but gets layouts - xkb_keymap* m_xkbKeymap = nullptr; + xkb_keymap* m_xkbKeymap = nullptr; + xkb_keymap* m_xkbKeymapV1 = nullptr; struct { uint32_t depressed = 0, latched = 0, locked = 0, group = 0; @@ -113,6 +114,9 @@ class IKeyboard : public IHID { std::string m_xkbKeymapString = ""; Hyprutils::OS::CFileDescriptor m_xkbKeymapFD; + std::string m_xkbKeymapV1String = ""; + Hyprutils::OS::CFileDescriptor m_xkbKeymapV1FD; + SStringRuleNames m_currentRules; int m_repeatRate = 0; int m_repeatDelay = 0; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 536f85b1..c0696d52 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -291,8 +291,8 @@ void CKeybindManager::updateXKBTranslationState() { const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS); FILE* const KEYMAPFILE = FILEPATH.empty() ? nullptr : fopen(absolutePath(FILEPATH, g_pConfigManager->m_configCurrentPath).c_str(), "r"); - auto PKEYMAP = KEYMAPFILE ? xkb_keymap_new_from_file(PCONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS) : - xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + auto PKEYMAP = KEYMAPFILE ? xkb_keymap_new_from_file(PCONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS) : + xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); if (KEYMAPFILE) fclose(KEYMAPFILE); @@ -305,7 +305,7 @@ void CKeybindManager::updateXKBTranslationState() { rules.rules, rules.model, rules.options); memset(&rules, 0, sizeof(rules)); - PKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + PKEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); } xkb_context_unref(PCONTEXT); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 6e975043..fa6acf15 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1108,7 +1108,6 @@ void CInputManager::applyConfigToKeyboard(SP pKeyboard) { pKeyboard->m_repeatDelay = std::max(0, REPEATDELAY); pKeyboard->m_numlockOn = NUMLOCKON; pKeyboard->m_xkbFilePath = FILEPATH; - pKeyboard->setKeymap(IKeyboard::SStringRuleNames{LAYOUT, MODEL, VARIANT, OPTIONS, RULES}); const auto LAYOUTSTR = pKeyboard->getActiveLayout(); diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp index 6eb419dc..d66d1f24 100644 --- a/src/protocols/InputMethodV2.cpp +++ b/src/protocols/InputMethodV2.cpp @@ -33,22 +33,22 @@ void CInputMethodKeyboardGrabV2::sendKeyboardData(SP keyboard) { m_lastKeyboard = keyboard; - auto keymapFD = allocateSHMFile(keyboard->m_xkbKeymapString.length() + 1); + auto keymapFD = allocateSHMFile(keyboard->m_xkbKeymapV1String.length() + 1); if UNLIKELY (!keymapFD.isValid()) { LOGM(ERR, "Failed to create a keymap file for keyboard grab"); return; } - void* data = mmap(nullptr, keyboard->m_xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD.get(), 0); + void* data = mmap(nullptr, keyboard->m_xkbKeymapV1String.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD.get(), 0); if UNLIKELY (data == MAP_FAILED) { LOGM(ERR, "Failed to mmap a keymap file for keyboard grab"); return; } - memcpy(data, keyboard->m_xkbKeymapString.c_str(), keyboard->m_xkbKeymapString.length()); - munmap(data, keyboard->m_xkbKeymapString.length() + 1); + memcpy(data, keyboard->m_xkbKeymapV1String.c_str(), keyboard->m_xkbKeymapV1String.length()); + munmap(data, keyboard->m_xkbKeymapV1String.length() + 1); - m_resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD.get(), keyboard->m_xkbKeymapString.length() + 1); + m_resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD.get(), keyboard->m_xkbKeymapV1String.length() + 1); sendMods(keyboard->m_modifiersState.depressed, keyboard->m_modifiersState.latched, keyboard->m_modifiersState.locked, keyboard->m_modifiersState.group); diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp index 6fe3eed5..2acc2298 100644 --- a/src/protocols/VirtualKeyboard.cpp +++ b/src/protocols/VirtualKeyboard.cpp @@ -88,7 +88,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP return; } - auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, sc(keymapData), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, sc(keymapData), XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(keymapData, len); if UNLIKELY (!xkbKeymap) { diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index 0b356c6f..7e1ff53b 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -333,9 +333,9 @@ void CWLKeyboardResource::sendKeymap(SP keyboard) { if (!(PROTO::seat->m_currentCaps & eHIDCapabilityType::HID_INPUT_CAPABILITY_KEYBOARD)) return; - std::string_view keymap = keyboard->m_xkbKeymapString; - Hyprutils::OS::CFileDescriptor& fd = keyboard->m_xkbKeymapFD; - uint32_t size = keyboard->m_xkbKeymapString.length() + 1; + std::string_view keymap = keyboard->m_xkbKeymapV1String; + Hyprutils::OS::CFileDescriptor& fd = keyboard->m_xkbKeymapV1FD; + uint32_t size = keyboard->m_xkbKeymapV1String.length() + 1; if (keymap == m_lastKeymap) return;