Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/config/ConfigDescriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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?
},
Expand Down
57 changes: 44 additions & 13 deletions src/devices/IKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 +
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion src/devices/IKeyboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
1 change: 0 additions & 1 deletion src/managers/input/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 5 additions & 5 deletions src/protocols/InputMethodV2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/protocols/VirtualKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions src/protocols/core/Seat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading