diff --git a/src/keymap.h b/src/keymap.h index 613f955..ac688e2 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -461,6 +461,9 @@ XkbWrapGroupIntoRange(int32_t group, enum xkb_range_exceed_type out_of_range_group_action, xkb_layout_index_t out_of_range_group_number); +xkb_mod_mask_t +mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods); + struct xkb_keymap_format_ops { bool (*keymap_new_from_names)(struct xkb_keymap *keymap, const struct xkb_rule_names *names); diff --git a/src/state.c b/src/state.c index 03463c8..279a646 100644 --- a/src/state.c +++ b/src/state.c @@ -1071,6 +1071,28 @@ xkb_state_serialize_layout(struct xkb_state *state, return ret; } +/** + * Gets a modifier mask and returns the resolved effective mask; this + * is needed because some modifiers can also map to other modifiers, e.g. + * the "NumLock" modifier usually also sets the "Mod2" modifier. + */ +xkb_mod_mask_t +mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods) +{ + const struct xkb_mod *mod; + xkb_mod_index_t i; + xkb_mod_mask_t mask; + + /* The effective mask is only real mods for now. */ + mask = mods & MOD_REAL_MASK_ALL; + + xkb_mods_enumerate(i, mod, &keymap->mods) + if (mods & (1u << i)) + mask |= mod->mapping; + + return mask; +} + /** * Returns 1 if the given modifier is active with the specified type(s), 0 if * not, or -1 if the modifier is invalid. diff --git a/src/xkbcomp/keymap.c b/src/xkbcomp/keymap.c index cc5bc83..ec93ee4 100644 --- a/src/xkbcomp/keymap.c +++ b/src/xkbcomp/keymap.c @@ -32,15 +32,7 @@ static void ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods) { - const struct xkb_mod *mod; - xkb_mod_index_t i; - - /* The effective mask is only real mods for now. */ - mods->mask = mods->mods & MOD_REAL_MASK_ALL; - - xkb_mods_enumerate(i, mod, &keymap->mods) - if (mods->mods & (1u << i)) - mods->mask |= mod->mapping; + mods->mask = mod_mask_get_effective(keymap, mods->mods); } static void