fix: Account for more modifiers in the EI keymap calculation
Some modifiers, notably LevelThree, were not accounted for in the modifier mask calculation. This leads to an incorrect keymap where some key symbols were listed for keys without (or insufficient) modifiers. Emulating those keys can then produce the wrong keysyms. Reproducible with server and client on English(UK) layout and typing e.g. [. That key has its own key AD11 (right of P) but is also on the third level of AE08 (the 8 key). When the server sends the keyid 91 (for [) the client looks it up in the pre-generated keymap. It is found first on the 8 key with no modifiers (because LevelThree was previously ignored), hence the client simulates a key 8 press without modifiers. This erroneously produced an 8 instead of the wanted [. Fix this by ensuring that all modifiers are accounted for in the key map. This fix is likely incomplete as it does not account for the full virtual modifier to real modifier mappings possible (e.g. Mod5 *may* be something other than AltGr) but it does push the can a bit further down the road, for someone else to release the worms. Closes: #8168
This commit is contained in:
parent
a8bf217e62
commit
a5c9744258
1 changed files with 27 additions and 2 deletions
|
|
@ -119,6 +119,19 @@ std::uint32_t EiKeyState::convertModMask(std::uint32_t xkb_mask) const
|
|||
if ((xkb_mask & (1 << xkbmod)) == 0)
|
||||
continue;
|
||||
|
||||
/* added in libxkbcommon 1.8.0 in the same commit so we have all or none */
|
||||
#ifndef XKB_VMOD_NAME_ALT
|
||||
static const auto XKB_VMOD_NAME_ALT = "Alt";
|
||||
static const auto XKB_VMOD_NAME_HYPER = "Hyper";
|
||||
static const auto XKB_VMOD_NAME_LEVEL3 = "LevelThree";
|
||||
static const auto XKB_VMOD_NAME_LEVEL5 = "LevelFive";
|
||||
static const auto XKB_VMOD_NAME_META = "Meta";
|
||||
static const auto XKB_VMOD_NAME_NUM = "NumLock";
|
||||
static const auto XKB_VMOD_NAME_SCROLL = "ScrollLock";
|
||||
static const auto XKB_VMOD_NAME_SUPER = "Super";
|
||||
static const auto XKB_MOD_NAME_MOD5 = "Mod5";
|
||||
#endif
|
||||
|
||||
const char *name = xkb_keymap_mod_get_name(m_xkbKeymap, xkbmod);
|
||||
if (strcmp(XKB_MOD_NAME_SHIFT, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitShift);
|
||||
|
|
@ -126,10 +139,22 @@ std::uint32_t EiKeyState::convertModMask(std::uint32_t xkb_mask) const
|
|||
barrier_mask |= (1 << kKeyModifierBitCapsLock);
|
||||
else if (strcmp(XKB_MOD_NAME_CTRL, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitControl);
|
||||
else if (strcmp(XKB_MOD_NAME_ALT, name) == 0)
|
||||
else if (strcmp(XKB_MOD_NAME_ALT, name) == 0 || strcmp(XKB_VMOD_NAME_ALT, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitAlt);
|
||||
else if (strcmp(XKB_MOD_NAME_LOGO, name) == 0)
|
||||
else if (strcmp(XKB_MOD_NAME_LOGO, name) == 0 || strcmp(XKB_VMOD_NAME_SUPER, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitSuper);
|
||||
else if (strcmp(XKB_MOD_NAME_MOD5, name) == 0 || strcmp(XKB_VMOD_NAME_LEVEL3, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitAltGr);
|
||||
else if (strcmp(XKB_VMOD_NAME_LEVEL5, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitLevel5Lock);
|
||||
else if (strcmp(XKB_VMOD_NAME_META, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitMeta);
|
||||
else if (strcmp(XKB_VMOD_NAME_NUM, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitNumLock);
|
||||
else if (strcmp(XKB_VMOD_NAME_SCROLL, name) == 0)
|
||||
barrier_mask |= (1 << kKeyModifierBitScrollLock);
|
||||
else
|
||||
LOG_WARN("modifier mask %s not accounted for, this is a bug", name);
|
||||
}
|
||||
|
||||
return barrier_mask;
|
||||
|
|
|
|||
Loading…
Reference in a new issue