summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusering-around <useruseringaround@proton.me>2025-09-11 20:42:20 +0300
committerGitHub <noreply@github.com>2025-09-11 19:42:20 +0200
commit38169c8fddcd21bd2c4ccebfa0c32100d5356aa0 (patch)
treee268f85e575db585db80133cbd8b036a6d1c63ca /src
parentc7b99691290ef16e04cf0cb4a5007ef29fccc229 (diff)
input: support xkb v2 format (#11482)
Diffstat (limited to 'src')
-rw-r--r--src/config/ConfigDescriptions.hpp2
-rw-r--r--src/devices/IKeyboard.cpp57
-rw-r--r--src/devices/IKeyboard.hpp6
-rw-r--r--src/managers/KeybindManager.cpp6
-rw-r--r--src/managers/input/InputManager.cpp1
-rw-r--r--src/protocols/InputMethodV2.cpp10
-rw-r--r--src/protocols/VirtualKeyboard.cpp2
-rw-r--r--src/protocols/core/Seat.cpp6
8 files changed, 62 insertions, 28 deletions
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<SConfigOptionDescription> 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();
+ 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();
- if (keymapFDDest == MAP_FAILED) {
+ 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<IKeyboard> 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<IKeyboard> 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<CZwpVirtualKeyboardV1>
return;
}
- auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, sc<const char*>(keymapData), XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, sc<const char*>(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<IKeyboard> 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;