input: support xkb v2 format (#11482)
This commit is contained in:
parent
c7b9969129
commit
38169c8fdd
8 changed files with 62 additions and 28 deletions
|
|
@ -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?
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue