Skip to content

Commit 63db755

Browse files
New latches break existing latches only if the modifier wasn't preserved
Signed-off-by: Jules Bertholet <[email protected]>
1 parent 6eecc63 commit 63db755

File tree

4 files changed

+87
-65
lines changed

4 files changed

+87
-65
lines changed

changes/api/+latches-sometimes-break-other-latches.breaking.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changed latching behavior so that latching a modifier or group now breaks existing modifier latches,
22
but only if the type of the key responsible for the latter latch
3-
has the modifier of the pre-existing latch in its modifiers list.
3+
has the modifier of the pre-existing latch in its modifiers list,
4+
and did not `preserve` the modifier.
45

56
For example, if a new latch is triggered by pressing a key of type `ALPHABETIC`,
67
existing `Shift` and `Lock` latches will now be broken, but other latches

src/state.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,17 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
590590
}
591591
else if (actions->type == ACTION_TYPE_GROUP_LATCH ||
592592
actions->type == ACTION_TYPE_MOD_LATCH) {
593-
/* We break latches only for mods that are part of the type's mod mask. */
593+
/* We break latches only for mods that are part of the type's mod mask,
594+
and are not preserved. */
594595
xkb_layout_index_t group = xkb_state_xkb_key_get_layout(state, key);
595596
const struct xkb_key_type *type = key->groups[group].type;
596597
xkb_mod_mask_t type_mod_mask = type->mods.mask;
597598

599+
const struct xkb_key_type_entry *entry = get_entry_for_mods(type, state->components.mods & type_mod_mask);
600+
if (entry) {
601+
type_mod_mask &= ~entry->preserve.mask;
602+
}
603+
598604
xkb_mod_mask_t filter_mod_mask = filter->action.mods.mods.mask;
599605
xkb_mod_mask_t mods_to_unlatch_mask = filter_mod_mask & type_mod_mask;
600606
xkb_mod_mask_t mods_to_keep_mask = filter_mod_mask & ~type_mod_mask;

test/data/symbols/latch

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,30 @@ xkb_symbols "base" {
66

77
key <AD01> { [ q, Q ], type[Group1] = "ALPHABETIC" };
88

9-
key <CAPS> { [ Caps_Lock ] };
9+
key <AC01> { [ a, A, ISO_Level5_Latch, NoSymbol ], type[Group1] = "FOUR_LEVEL_SEMIALPHABETIC" };
10+
11+
key <CAPS> { [ Caps_Lock ], type[Group1] = "ONE_LEVEL" };
1012

1113
key <LFSH> {
1214
symbols[Group1] = [ Shift_L, Caps_Lock ],
13-
actions[Group1] = [ LatchMods(modifiers=Shift), LockMods(modifiers=Lock) ]
15+
actions[Group1] = [ LatchMods(modifiers=Shift), LockMods(modifiers=Lock) ],
16+
type[Group1] = "TWO_LEVEL"
1417
};
1518

1619
key <LCTL> {
1720
symbols[Group1] = [ Control_L ],
18-
actions[Group1] = [ LatchMods(modifiers=Control) ]
21+
actions[Group1] = [ LatchMods(modifiers=Control) ],
22+
type[Group1] = "ONE_LEVEL"
1923
};
2024

2125
key <LALT> {
2226
symbols[Group1] = [ Alt_L ],
23-
actions[Group1] = [ LatchMods(modifiers=Alt) ]
27+
actions[Group1] = [ LatchMods(modifiers=Alt) ],
28+
type[Group1] = "ONE_LEVEL"
2429
};
2530

31+
key <RCTL> { [ ISO_Level3_Latch ], type[Group1] = "ONE_LEVEL" };
32+
2633
key <RTSH> {
2734
symbols[Group1] = [ Shift_R, Shift_R, Shift_R, Shift_R, Shift_R ],
2835
actions[Group1] = [ LatchMods(modifiers=Lock), LatchMods(modifiers=Lock), LatchMods(modifiers=Lock), LatchMods(modifiers=Lock), LatchMods(modifiers=Lock) ],

test/keyseq.c

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -374,78 +374,86 @@ test_latch_mod_cancel(struct xkb_context *context)
374374
assert(keymap);
375375

376376
assert(test_key_seq(keymap,
377-
KEY_Q, BOTH, XKB_KEY_q,
378-
NEXT, KEY_1, BOTH, XKB_KEY_1,
377+
KEY_Q , BOTH, XKB_KEY_q ,
378+
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
379379

380380
// Basic latch/unlatch
381381

382-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, // Latch Shift
383-
NEXT, KEY_Q , BOTH, XKB_KEY_Q , // Unlatch Shift
384-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
382+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
383+
NEXT, KEY_Q , BOTH, XKB_KEY_Q , // Unlatch Shift
384+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
385385

386-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, // Latch Shift
387-
NEXT, KEY_1 , BOTH, XKB_KEY_exclam , // Unlatch Shift
388-
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
386+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
387+
NEXT, KEY_1 , BOTH, XKB_KEY_exclam , // Unlatch Shift
388+
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
389389

390390
// Lock/unlock cancels latch
391391

392-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
393-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Caps_Lock, // Lock Caps, unlatch Shift
394-
NEXT, KEY_Q , BOTH, XKB_KEY_Q ,
395-
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
396-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
397-
NEXT, KEY_1 , BOTH, XKB_KEY_exclam , // Unlatch Shift
398-
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
399-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
400-
NEXT, KEY_Q , BOTH, XKB_KEY_q , // Unlatch Shift
401-
NEXT, KEY_Q , BOTH, XKB_KEY_Q ,
402-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
403-
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Caps_Lock, // Unlock Caps, unlatch Shift
404-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
392+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
393+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Caps_Lock , // Lock Caps, unlatch Shift
394+
NEXT, KEY_Q , BOTH, XKB_KEY_Q ,
395+
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
396+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
397+
NEXT, KEY_1 , BOTH, XKB_KEY_exclam , // Unlatch Shift
398+
NEXT, KEY_1 , BOTH, XKB_KEY_1 ,
399+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
400+
NEXT, KEY_Q , BOTH, XKB_KEY_q , // Unlatch Shift
401+
NEXT, KEY_Q , BOTH, XKB_KEY_Q ,
402+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , // Latch Shift
403+
NEXT, KEY_LEFTSHIFT , BOTH, XKB_KEY_Caps_Lock , // Unlock Caps, unlatch Shift
404+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
405405

406406
// Double latch/unlatch
407407

408-
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, // Latch Control
409-
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
410-
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
411-
412-
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock
413-
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, // Latch Control
414-
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
415-
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Lock, Unlatch Alt
416-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
417-
418-
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
419-
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, unlatch Alt
420-
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, // Latch Control
421-
NEXT, KEY_1 , BOTH, XKB_KEY_1 , // Unlatch Control, Unlatch Lock
422-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
423-
424-
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
425-
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, // Latch Control
426-
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, Unlatch Control, Unlatch Alt
427-
NEXT, KEY_1 , BOTH, XKB_KEY_1 , // Unlatch Lock
428-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
429-
430-
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
431-
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, // Latch Control
432-
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, Unlatch Control, Unlatch Alt
433-
NEXT, KEY_Q , BOTH, XKB_KEY_Q , // Unlatch Lock
434-
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
408+
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L , // Latch Control
409+
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
410+
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
411+
412+
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock
413+
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L , // Latch Control
414+
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
415+
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Lock, Unlatch Alt
416+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
417+
418+
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
419+
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, unlatch Alt
420+
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L , // Latch Control
421+
NEXT, KEY_1 , BOTH, XKB_KEY_1 , // Unlatch Control, Unlatch Lock
422+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
423+
424+
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
425+
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L , // Latch Control
426+
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, Unlatch Control, Unlatch Alt
427+
NEXT, KEY_1 , BOTH, XKB_KEY_1 , // Unlatch Lock
428+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
429+
430+
NEXT, KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , // Latch Alt
431+
NEXT, KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L , // Latch Control
432+
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock, Unlatch Control, Unlatch Alt
433+
NEXT, KEY_Q , BOTH, XKB_KEY_Q , // Unlatch Lock
434+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
435435

436436
// Simultaneous latch
437437

438-
NEXT, KEY_LEFTCTRL , DOWN, XKB_KEY_Control_L, // Set Control
439-
NEXT, KEY_LEFTALT , DOWN, XKB_KEY_Alt_L , // Latch Alt
440-
NEXT, KEY_LEFTCTRL , UP , XKB_KEY_Control_L, // Latch Control
441-
NEXT, KEY_LEFTALT , UP , XKB_KEY_Alt_L , // Latch Alt
442-
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
443-
444-
NEXT, KEY_LEFTCTRL , DOWN, XKB_KEY_Control_L, // Set Control
445-
NEXT, KEY_LEFTALT , DOWN, XKB_KEY_Alt_L , // Latch Alt
446-
NEXT, KEY_LEFTALT , UP , XKB_KEY_Alt_L , // Latch Alt
447-
NEXT, KEY_LEFTCTRL , UP , XKB_KEY_Control_L, // Latch Control
448-
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
438+
NEXT, KEY_LEFTCTRL , DOWN, XKB_KEY_Control_L , // Set Control
439+
NEXT, KEY_LEFTALT , DOWN, XKB_KEY_Alt_L , // Latch Alt
440+
NEXT, KEY_LEFTCTRL , UP , XKB_KEY_Control_L , // Latch Control
441+
NEXT, KEY_LEFTALT , UP , XKB_KEY_Alt_L , // Latch Alt
442+
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
443+
444+
NEXT, KEY_LEFTCTRL , DOWN, XKB_KEY_Control_L , // Set Control
445+
NEXT, KEY_LEFTALT , DOWN, XKB_KEY_Alt_L , // Latch Alt
446+
NEXT, KEY_LEFTALT , UP , XKB_KEY_Alt_L , // Latch Alt
447+
NEXT, KEY_LEFTCTRL , UP , XKB_KEY_Control_L , // Latch Control
448+
NEXT, KEY_1 , BOTH, XKB_KEY_plus , // Unlatch Control, Unlatch Alt
449+
450+
// Preserved latches are not broken by new latches
451+
452+
NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , // Latch Lock
453+
NEXT, KEY_RIGHTCTRL , BOTH, XKB_KEY_ISO_Level3_Latch, // Latch LevelThree
454+
NEXT, KEY_A , BOTH, XKB_KEY_ISO_Level5_Latch, // Latch LevelFive, unnlatch LevelThree
455+
NEXT, KEY_Q , BOTH, XKB_KEY_Q , // Unlatch Lock, unlatch LevelFive
456+
NEXT, KEY_Q , BOTH, XKB_KEY_q ,
449457

450458
FINISH));
451459

0 commit comments

Comments
 (0)