Skip to content

Commit

Permalink
state: Fix LEDs driven by the group state
Browse files Browse the repository at this point in the history
When the indicator field `whichGroupState` is set to `Base` or `Latched`,
the group masks should be considered only as boolean values as per the
XKB specification.
  • Loading branch information
wismill committed Jan 14, 2025
1 parent 7d08bf4 commit 325ba10
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
2 changes: 2 additions & 0 deletions changes/api/579.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed incorrect handling of group indicators when `whichGroupState` is set with
`Base` or `Latched`.
49 changes: 34 additions & 15 deletions src/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,10 +743,9 @@ xkb_state_led_update_all(struct xkb_state *state)
state->components.leds = 0;

xkb_leds_enumerate(idx, led, state->keymap) {
xkb_mod_mask_t mod_mask = 0;
xkb_layout_mask_t group_mask = 0;

if (led->which_mods != 0 && led->mods.mask != 0) {
xkb_mod_mask_t mod_mask = 0;
if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
mod_mask |= state->components.mods;
if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
Expand All @@ -762,19 +761,39 @@ xkb_state_led_update_all(struct xkb_state *state)
}
}

if (led->which_groups != 0 && led->groups != 0) {
if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
group_mask |= (1u << state->components.group);
if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
group_mask |= (1u << state->components.base_group);
if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
group_mask |= (1u << state->components.latched_group);
if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
group_mask |= (1u << state->components.locked_group);

if (led->groups & group_mask) {
state->components.leds |= (1u << idx);
continue;
if (led->which_groups != 0) {
if (likely(led->groups) != 0) {
xkb_layout_mask_t group_mask = 0;
/* Effective and locked groups have been brought into range */
assert(state->components.group < XKB_MAX_GROUPS);
assert(state->components.locked_group >= 0 &&
state->components.locked_group < XKB_MAX_GROUPS);
/* Effective and locked groups are used as mask */
if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
group_mask |= (1u << state->components.group);
if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
group_mask |= (1u << state->components.locked_group);
/* Base and latched groups only have to be non-zero */
if ((led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) &&
state->components.base_group != 0)
group_mask |= led->groups;
if ((led->which_groups & XKB_STATE_LAYOUT_LATCHED) &&
state->components.latched_group != 0)
group_mask |= led->groups;

if (led->groups & group_mask) {
state->components.leds |= (1u << idx);
continue;
}
} else {
/* Special case for Base and latched groups */
if (((led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) &&
state->components.base_group == 0) ||
((led->which_groups & XKB_STATE_LAYOUT_LATCHED) &&
state->components.latched_group == 0)) {
state->components.leds |= (1u << idx);
continue;
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions test/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,9 +1204,7 @@ test_leds(struct xkb_context *ctx)
const xkb_led_index_t num_idx = _xkb_keymap_led_get_index(keymap, XKB_LED_NAME_NUM);
const xkb_led_index_t scroll_idx = _xkb_keymap_led_get_index(keymap, XKB_LED_NAME_SCROLL);
const xkb_led_index_t compose_idx = _xkb_keymap_led_get_index(keymap, XKB_LED_NAME_COMPOSE);
// const xkb_led_index_t kana_idx = _xkb_keymap_led_get_index(keymap, XKB_LED_NAME_KANA);
const xkb_led_index_t sleep_idx = _xkb_keymap_led_get_index(keymap, "Sleep");
// const xkb_led_index_t suspend_idx = _xkb_keymap_led_get_index(keymap, "Suspend");
const xkb_led_index_t mute_idx = _xkb_keymap_led_get_index(keymap, "Mute");
const xkb_led_index_t misc_idx = _xkb_keymap_led_get_index(keymap, "Misc");
const xkb_led_index_t mail_idx = _xkb_keymap_led_get_index(keymap, "Mail");
Expand All @@ -1216,9 +1214,7 @@ test_leds(struct xkb_context *ctx)
const xkb_led_mask_t num = 1u << num_idx;
const xkb_led_mask_t scroll = 1u << scroll_idx;
const xkb_led_mask_t compose = 1u << compose_idx;
// const xkb_led_mask_t kana = 1u << kana_idx;
const xkb_led_mask_t sleep = 1u << sleep_idx;
// const xkb_led_mask_t suspend = 1u << suspend_idx;
const xkb_led_mask_t mute = 1u << mute_idx;
const xkb_led_mask_t misc = 1u << misc_idx;
const xkb_led_mask_t mail = 1u << mail_idx;
Expand Down

0 comments on commit 325ba10

Please sign in to comment.