Skip to content

Commit fc28d09

Browse files
committed
wip
1 parent 01b64bb commit fc28d09

File tree

5 files changed

+385
-248
lines changed

5 files changed

+385
-248
lines changed

src/keymap.h

+3
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ enum xkb_internal_action_flags {
244244
struct xkb_internal_action {
245245
enum xkb_action_type type;
246246
enum xkb_internal_action_flags flags;
247+
union {
248+
xkb_mod_mask_t clear_latched_mods;
249+
};
247250
};
248251

249252
union xkb_action {

src/state.c

+32-29
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ xkb_filter_group_lock_func(struct xkb_state *state,
323323

324324
static bool
325325
xkb_action_breaks_latch(const union xkb_action *action,
326-
enum xkb_internal_action_flags flag)
326+
enum xkb_internal_action_flags flag,
327+
xkb_mod_mask_t mask)
327328
{
328329
switch (action->type) {
329330
case ACTION_TYPE_NONE:
@@ -335,7 +336,8 @@ xkb_action_breaks_latch(const union xkb_action *action,
335336
case ACTION_TYPE_TERMINATE:
336337
return true;
337338
case ACTION_TYPE_INTERNAL:
338-
return action->internal.flags & flag;
339+
return (action->internal.flags & flag) &&
340+
((action->internal.clear_latched_mods & mask) == mask);
339341
default:
340342
return false;
341343
}
@@ -419,7 +421,7 @@ xkb_filter_group_latch_func(struct xkb_state *state,
419421
return XKB_FILTER_CONSUME;
420422
}
421423
else if (xkb_action_breaks_latch(&(actions[k]),
422-
INTERNAL_BREAKS_GROUP_LATCH)) {
424+
INTERNAL_BREAKS_GROUP_LATCH, 0)) {
423425
/* Breaks the latch */
424426
state->components.latched_group = 0;
425427
filter->func = NULL;
@@ -576,7 +578,8 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
576578
return XKB_FILTER_CONSUME;
577579
}
578580
else if (xkb_action_breaks_latch(&(actions[k]),
579-
INTERNAL_BREAKS_MOD_LATCH)) {
581+
INTERNAL_BREAKS_MOD_LATCH,
582+
filter->action.mods.mods.mask)) {
580583
/* XXX: This may be totally broken, we might need to break the
581584
* latch in the next run after this press? */
582585
state->components.latched_mods &= ~filter->action.mods.mods.mask;
@@ -934,39 +937,40 @@ static const struct xkb_key synthetic_key_break_group_latch = {
934937
.num_groups = 1,
935938
.groups = &synthetic_key_group_break_group_latch
936939
};
937-
static struct xkb_level synthetic_key_level_break_mod_latch = {
938-
.num_syms = 1,
939-
.s = { XKB_KEY_NoSymbol },
940-
.a = { { .internal = {
941-
.type = ACTION_TYPE_INTERNAL,
942-
.flags = INTERNAL_BREAKS_MOD_LATCH
943-
} } }
944-
};
945-
static struct xkb_group synthetic_key_group_break_mod_latch = {
946-
.type = &synthetic_key_type,
947-
.levels = &synthetic_key_level_break_mod_latch
948-
};
949-
static const struct xkb_key synthetic_key_break_mod_latch = {
950-
.num_groups = 1,
951-
.groups = &synthetic_key_group_break_mod_latch
952-
};
940+
static const struct xkb_key synthetic_key = { 0 };
953941

954942
/* Transcription from xserver: XkbLatchModifiers */
955943
static void
956944
update_latch_modifiers(struct xkb_state *state,
957945
xkb_mod_mask_t mask, xkb_mod_mask_t latches)
958946
{
959-
const struct xkb_key *key = &synthetic_key_break_mod_latch;
960-
961947
/* Clear affected latched modifiers */
962948
const xkb_mod_mask_t clear =
963949
mod_mask_get_effective(state->keymap, mask & ~latches);
964950
state->components.latched_mods &= ~clear;
965951

966952
/* Clear any pending latch to locks. */
967-
xkb_filter_apply_all(state, key, XKB_KEY_DOWN);
953+
const struct xkb_level synthetic_key_level_break_mod_latch = {
954+
.num_syms = 1,
955+
.s = { XKB_KEY_NoSymbol },
956+
.a = { { .internal = {
957+
.type = ACTION_TYPE_INTERNAL,
958+
.flags = INTERNAL_BREAKS_MOD_LATCH,
959+
.clear_latched_mods = clear
960+
} } }
961+
};
962+
const struct xkb_group synthetic_key_group_break_mod_latch = {
963+
.type = &synthetic_key_type,
964+
.levels = &synthetic_key_level_break_mod_latch
965+
};
966+
const const struct xkb_key synthetic_key_break_mod_latch = {
967+
.num_groups = 1,
968+
.groups = &synthetic_key_group_break_mod_latch
969+
};
970+
xkb_filter_apply_all(state, &synthetic_key_break_mod_latch, XKB_KEY_DOWN);
968971

969972
/* Simulate tapping a key with a modifier latch action */
973+
const struct xkb_key *key = &synthetic_key;
970974
const union xkb_action latch_mods = {
971975
.mods = {
972976
.type = ACTION_TYPE_MOD_LATCH,
@@ -989,17 +993,16 @@ update_latch_modifiers(struct xkb_state *state,
989993
static void
990994
update_latch_group(struct xkb_state *state, int32_t group)
991995
{
992-
/* Simulate tapping a key with a group latch action, but in isolation: i.e.
993-
* without affecting the other filters. */
994-
const struct xkb_key *key = &synthetic_key_break_group_latch;
995-
996996
/* Clear any pending latch to locks. */
997-
xkb_filter_apply_all(state, key, XKB_KEY_DOWN);
997+
xkb_filter_apply_all(state, &synthetic_key_break_group_latch, XKB_KEY_DOWN);
998998

999+
/* Simulate tapping a key with a group latch action, but in isolation: i.e.
1000+
* without affecting the other filters. */
1001+
const struct xkb_key *key = &synthetic_key;
9991002
const union xkb_action latch_group = {
10001003
.group = {
10011004
.type = ACTION_TYPE_GROUP_LATCH,
1002-
.flags = 0,
1005+
.flags = ACTION_ABSOLUTE_SWITCH,
10031006
.group = group,
10041007
},
10051008
};

test/data/rules/evdev

+1
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,7 @@
11481148
lv3:caps_switch_latch = +level3(caps_switch_latch)
11491149
lv3:bksl_switch_latch = +level3(bksl_switch_latch)
11501150
lv3:lsgt_switch_latch = +level3(lsgt_switch_latch)
1151+
lv3:lsgt_latch = +level3(lsgt_latch)
11511152
lv5:lsgt_switch = +level5(lsgt_switch)
11521153
lv5:ralt_switch = +level5(ralt_switch)
11531154
lv5:lsgt_switch_lock = +level5(lsgt_switch_lock)

test/data/symbols/level3

+8
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,14 @@ xkb_symbols "lsgt_switch_latch" {
210210
include "level3(modifier_mapping)"
211211
};
212212

213+
partial modifier_keys
214+
xkb_symbols "lsgt_latch" {
215+
key <LSGT> {
216+
type[Group1]="ONE_LEVEL",
217+
symbols[Group1] = [ ISO_Level3_Latch ]
218+
};
219+
};
220+
213221
// Number key 4 chooses third shift level when pressed in isolation.
214222
partial modifier_keys
215223
xkb_symbols "4_switch_isolated" {

0 commit comments

Comments
 (0)