diff options
author | Ran Benita <ran234@gmail.com> | 2014-08-18 20:27:07 +0300 |
---|---|---|
committer | Ran Benita <ran234@gmail.com> | 2014-08-18 21:46:39 +0300 |
commit | a1f0595a683a167901a2f1d9f02b9b637bd762a6 (patch) | |
tree | 7e21cc7ff33fd45b879d41b29404c2a623d79bc1 | |
parent | 99184f1614548722e3531e55bb19ac74327c98cb (diff) | |
download | libxkbcommon-a1f0595a683a167901a2f1d9f02b9b637bd762a6.tar.gz libxkbcommon-a1f0595a683a167901a2f1d9f02b9b637bd762a6.tar.bz2 libxkbcommon-a1f0595a683a167901a2f1d9f02b9b637bd762a6.zip |
state: make sure the mods are fully resolved after xkb_state_update_mask()
Virtual modifiers can have "mappings" to real modifiers, e.g. NumLock
may also set Mod2. In a normal turn of events, the various components
(depressed, latched, locked, and consequently effective) include the
mapped mods, because the masks are pre-resolved everywhere. However,
xkb_state_update_mask() accepts arbitrary mod masks, which may not be
resolved (if it comes from somewhere other than
xkb_state_serialize_mods()). So let's always resolve them ourselves.
Signed-off-by: Ran Benita <ran234@gmail.com>
-rw-r--r-- | src/state.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/state.c b/src/state.c index 279a646..6613969 100644 --- a/src/state.c +++ b/src/state.c @@ -797,6 +797,27 @@ xkb_state_update_mask(struct xkb_state *state, state->components.latched_mods = latched_mods & mask; state->components.locked_mods = locked_mods & mask; + /* Make sure the mods are fully resolved - since we get arbitrary + * input, they might not be. + * + * It might seem more reasonable to do this only for components.mods + * in xkb_state_update_derived(), rather than for each component + * seperately. That would allow to distinguish between "really" + * depressed mods (would be in MODS_DEPRESSED) and indirectly + * depressed to to a mapping (would only be in MODS_EFFECTIVE). + * However, the traditional behavior of xkb_state_update_key() is that + * if a vmod is depressed, its mappings are depressed with it; so we're + * expected to do the same here. Also, LEDs (usually) look if a real + * mod is locked, not just effective; otherwise it won't be lit. + * + * We OR here because mod_mask_get_effective() drops vmods. */ + state->components.base_mods |= + mod_mask_get_effective(state->keymap, state->components.base_mods); + state->components.latched_mods |= + mod_mask_get_effective(state->keymap, state->components.latched_mods); + state->components.locked_mods |= + mod_mask_get_effective(state->keymap, state->components.locked_mods); + state->components.base_group = base_group; state->components.latched_group = latched_group; state->components.locked_group = locked_group; |