Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
wismill committed Dec 7, 2024
1 parent 01b64bb commit fc28d09
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 248 deletions.
3 changes: 3 additions & 0 deletions src/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ enum xkb_internal_action_flags {
struct xkb_internal_action {
enum xkb_action_type type;
enum xkb_internal_action_flags flags;
union {
xkb_mod_mask_t clear_latched_mods;
};
};

union xkb_action {
Expand Down
61 changes: 32 additions & 29 deletions src/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ xkb_filter_group_lock_func(struct xkb_state *state,

static bool
xkb_action_breaks_latch(const union xkb_action *action,
enum xkb_internal_action_flags flag)
enum xkb_internal_action_flags flag,
xkb_mod_mask_t mask)
{
switch (action->type) {
case ACTION_TYPE_NONE:
Expand All @@ -335,7 +336,8 @@ xkb_action_breaks_latch(const union xkb_action *action,
case ACTION_TYPE_TERMINATE:
return true;
case ACTION_TYPE_INTERNAL:
return action->internal.flags & flag;
return (action->internal.flags & flag) &&
((action->internal.clear_latched_mods & mask) == mask);
default:
return false;
}
Expand Down Expand Up @@ -419,7 +421,7 @@ xkb_filter_group_latch_func(struct xkb_state *state,
return XKB_FILTER_CONSUME;
}
else if (xkb_action_breaks_latch(&(actions[k]),
INTERNAL_BREAKS_GROUP_LATCH)) {
INTERNAL_BREAKS_GROUP_LATCH, 0)) {
/* Breaks the latch */
state->components.latched_group = 0;
filter->func = NULL;
Expand Down Expand Up @@ -576,7 +578,8 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
return XKB_FILTER_CONSUME;
}
else if (xkb_action_breaks_latch(&(actions[k]),
INTERNAL_BREAKS_MOD_LATCH)) {
INTERNAL_BREAKS_MOD_LATCH,
filter->action.mods.mods.mask)) {
/* XXX: This may be totally broken, we might need to break the
* latch in the next run after this press? */
state->components.latched_mods &= ~filter->action.mods.mods.mask;
Expand Down Expand Up @@ -934,39 +937,40 @@ static const struct xkb_key synthetic_key_break_group_latch = {
.num_groups = 1,
.groups = &synthetic_key_group_break_group_latch
};
static struct xkb_level synthetic_key_level_break_mod_latch = {
.num_syms = 1,
.s = { XKB_KEY_NoSymbol },
.a = { { .internal = {
.type = ACTION_TYPE_INTERNAL,
.flags = INTERNAL_BREAKS_MOD_LATCH
} } }
};
static struct xkb_group synthetic_key_group_break_mod_latch = {
.type = &synthetic_key_type,
.levels = &synthetic_key_level_break_mod_latch
};
static const struct xkb_key synthetic_key_break_mod_latch = {
.num_groups = 1,
.groups = &synthetic_key_group_break_mod_latch
};
static const struct xkb_key synthetic_key = { 0 };

/* Transcription from xserver: XkbLatchModifiers */
static void
update_latch_modifiers(struct xkb_state *state,
xkb_mod_mask_t mask, xkb_mod_mask_t latches)
{
const struct xkb_key *key = &synthetic_key_break_mod_latch;

/* Clear affected latched modifiers */
const xkb_mod_mask_t clear =
mod_mask_get_effective(state->keymap, mask & ~latches);
state->components.latched_mods &= ~clear;

/* Clear any pending latch to locks. */
xkb_filter_apply_all(state, key, XKB_KEY_DOWN);
const struct xkb_level synthetic_key_level_break_mod_latch = {
.num_syms = 1,
.s = { XKB_KEY_NoSymbol },
.a = { { .internal = {
.type = ACTION_TYPE_INTERNAL,
.flags = INTERNAL_BREAKS_MOD_LATCH,
.clear_latched_mods = clear
} } }
};
const struct xkb_group synthetic_key_group_break_mod_latch = {
.type = &synthetic_key_type,
.levels = &synthetic_key_level_break_mod_latch
};
const const struct xkb_key synthetic_key_break_mod_latch = {
.num_groups = 1,
.groups = &synthetic_key_group_break_mod_latch
};
xkb_filter_apply_all(state, &synthetic_key_break_mod_latch, XKB_KEY_DOWN);

/* Simulate tapping a key with a modifier latch action */
const struct xkb_key *key = &synthetic_key;
const union xkb_action latch_mods = {
.mods = {
.type = ACTION_TYPE_MOD_LATCH,
Expand All @@ -989,17 +993,16 @@ update_latch_modifiers(struct xkb_state *state,
static void
update_latch_group(struct xkb_state *state, int32_t group)
{
/* Simulate tapping a key with a group latch action, but in isolation: i.e.
* without affecting the other filters. */
const struct xkb_key *key = &synthetic_key_break_group_latch;

/* Clear any pending latch to locks. */
xkb_filter_apply_all(state, key, XKB_KEY_DOWN);
xkb_filter_apply_all(state, &synthetic_key_break_group_latch, XKB_KEY_DOWN);

/* Simulate tapping a key with a group latch action, but in isolation: i.e.
* without affecting the other filters. */
const struct xkb_key *key = &synthetic_key;
const union xkb_action latch_group = {
.group = {
.type = ACTION_TYPE_GROUP_LATCH,
.flags = 0,
.flags = ACTION_ABSOLUTE_SWITCH,
.group = group,
},
};
Expand Down
1 change: 1 addition & 0 deletions test/data/rules/evdev
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,7 @@
lv3:caps_switch_latch = +level3(caps_switch_latch)
lv3:bksl_switch_latch = +level3(bksl_switch_latch)
lv3:lsgt_switch_latch = +level3(lsgt_switch_latch)
lv3:lsgt_latch = +level3(lsgt_latch)
lv5:lsgt_switch = +level5(lsgt_switch)
lv5:ralt_switch = +level5(ralt_switch)
lv5:lsgt_switch_lock = +level5(lsgt_switch_lock)
Expand Down
8 changes: 8 additions & 0 deletions test/data/symbols/level3
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ xkb_symbols "lsgt_switch_latch" {
include "level3(modifier_mapping)"
};

partial modifier_keys
xkb_symbols "lsgt_latch" {
key <LSGT> {
type[Group1]="ONE_LEVEL",
symbols[Group1] = [ ISO_Level3_Latch ]
};
};

// Number key 4 chooses third shift level when pressed in isolation.
partial modifier_keys
xkb_symbols "4_switch_isolated" {
Expand Down
Loading

0 comments on commit fc28d09

Please sign in to comment.