mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
input: remove the concept of "significant" modifiers
For the purpose of matching key bindings, "significant" modifiers are no more. We're really only interested in filtering out "locked" modifiers. We're already doing this, so there's no need to *also* match against a set of "significant" modifiers. Furthermore, we *never* want to consider locked keys (e.g. when emitting escapes to the client application), thus we can filter those out already when retrieving the set of active modifiers. The exception is the kitty keyboard protocol, which has support for CapsLock and NumLock. Since we're already re-retrieving the "consumed" modifiers (using the GTK style, rather than normal "XKB" style, to better match the kitty terminal), we might as well re-retrieve the effective modifiers as well.
This commit is contained in:
parent
4730ff8d08
commit
0aefc2c65d
8 changed files with 28 additions and 52 deletions
52
input.c
52
input.c
|
|
@ -597,15 +597,6 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
if (seat->kbd.mod_num != XKB_MOD_INVALID)
|
||||
seat->kbd.kitty_significant |= 1 << seat->kbd.mod_num;
|
||||
|
||||
/* Significant modifiers when handling shortcuts - use all available */
|
||||
seat->kbd.bind_significant = 0;
|
||||
const xkb_mod_index_t mod_count = xkb_keymap_num_mods(seat->kbd.xkb_keymap);
|
||||
for (xkb_mod_index_t i = 0; i < mod_count; i++) {
|
||||
LOG_DBG("significant modifier: %s",
|
||||
xkb_keymap_mod_get_name(seat->kbd.xkb_keymap, i));
|
||||
seat->kbd.bind_significant |= 1 << i;
|
||||
}
|
||||
|
||||
seat->kbd.key_arrow_up = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "UP");
|
||||
seat->kbd.key_arrow_down = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "DOWN");
|
||||
}
|
||||
|
|
@ -887,7 +878,8 @@ UNITTEST
|
|||
void
|
||||
get_current_modifiers(const struct seat *seat,
|
||||
xkb_mod_mask_t *effective,
|
||||
xkb_mod_mask_t *consumed, uint32_t key)
|
||||
xkb_mod_mask_t *consumed, uint32_t key,
|
||||
bool filter_locked)
|
||||
{
|
||||
if (unlikely(seat->kbd.xkb_state == NULL)) {
|
||||
if (effective != NULL)
|
||||
|
|
@ -897,24 +889,27 @@ get_current_modifiers(const struct seat *seat,
|
|||
}
|
||||
|
||||
else {
|
||||
const xkb_mod_mask_t locked =
|
||||
xkb_state_serialize_mods(seat->kbd.xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
|
||||
if (effective != NULL) {
|
||||
*effective = xkb_state_serialize_mods(
|
||||
seat->kbd.xkb_state, XKB_STATE_MODS_EFFECTIVE);
|
||||
|
||||
if (filter_locked)
|
||||
*effective &= ~locked;
|
||||
}
|
||||
|
||||
if (consumed != NULL) {
|
||||
*consumed = xkb_state_key_get_consumed_mods2(
|
||||
seat->kbd.xkb_state, key, XKB_CONSUMED_MODE_XKB);
|
||||
|
||||
if (filter_locked)
|
||||
*consumed &= ~locked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static xkb_mod_mask_t
|
||||
get_locked_modifiers(const struct seat *seat)
|
||||
{
|
||||
return xkb_state_serialize_mods(seat->kbd.xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
}
|
||||
|
||||
struct kbd_ctx {
|
||||
xkb_layout_index_t layout;
|
||||
xkb_keycode_t key;
|
||||
|
|
@ -1184,7 +1179,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
|||
xkb_state_update_key(
|
||||
seat->kbd.xkb_state, ctx->key, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
|
||||
get_current_modifiers(seat, &mods, NULL, ctx->key);
|
||||
get_current_modifiers(seat, &mods, NULL, ctx->key, false);
|
||||
consumed = xkb_state_key_get_consumed_mods2(
|
||||
seat->kbd.xkb_state, ctx->key, XKB_CONSUMED_MODE_GTK);
|
||||
|
||||
|
|
@ -1201,7 +1196,9 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
|||
seat->kbd.xkb_state, ctx->key, pressed ? XKB_KEY_UP : XKB_KEY_DOWN);
|
||||
#endif
|
||||
} else {
|
||||
mods = ctx->mods;
|
||||
/* Same as ctx->mods, but without locked modifiers being
|
||||
filtered out */
|
||||
get_current_modifiers(seat, &mods, NULL, ctx->key, false);
|
||||
|
||||
/* Re-retrieve the consumed modifiers using the GTK mode, to
|
||||
better match kitty. */
|
||||
|
|
@ -1490,13 +1487,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
const bool composed = compose_status == XKB_COMPOSE_COMPOSED;
|
||||
|
||||
xkb_mod_mask_t mods, consumed;
|
||||
get_current_modifiers(seat, &mods, &consumed, key);
|
||||
|
||||
const xkb_mod_mask_t locked = get_locked_modifiers(seat);
|
||||
const xkb_mod_mask_t bind_mods
|
||||
= mods & seat->kbd.bind_significant & ~locked;
|
||||
const xkb_mod_mask_t bind_consumed =
|
||||
consumed & seat->kbd.bind_significant & ~locked;
|
||||
get_current_modifiers(seat, &mods, &consumed, key, true);
|
||||
|
||||
xkb_layout_index_t layout_idx =
|
||||
xkb_state_key_get_layout(seat->kbd.xkb_state, key);
|
||||
|
|
@ -1520,7 +1511,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
start_repeater(seat, key);
|
||||
|
||||
search_input(
|
||||
seat, term, bindings, key, sym, mods, consumed, locked,
|
||||
seat, term, bindings, key, sym, mods, consumed,
|
||||
raw_syms, raw_count, serial);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1530,7 +1521,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
start_repeater(seat, key);
|
||||
|
||||
urls_input(
|
||||
seat, term, bindings, key, sym, mods, consumed, locked,
|
||||
seat, term, bindings, key, sym, mods, consumed,
|
||||
raw_syms, raw_count, serial);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1563,14 +1554,14 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
|
||||
/* Match translated symbol */
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (bind_mods & ~bind_consumed) &&
|
||||
bind->mods == (mods & ~consumed) &&
|
||||
execute_binding(seat, term, bind, serial, 1))
|
||||
{
|
||||
LOG_WARN("matched translated symbol");
|
||||
goto maybe_repeat;
|
||||
}
|
||||
|
||||
if (bind->mods != bind_mods || bind_mods != (mods & ~locked))
|
||||
if (bind->mods != mods)
|
||||
continue;
|
||||
|
||||
/* Match untranslated symbols */
|
||||
|
|
@ -2253,8 +2244,7 @@ static const struct key_binding *
|
|||
xassert(bindings != NULL);
|
||||
|
||||
xkb_mod_mask_t mods;
|
||||
get_current_modifiers(seat, &mods, NULL, 0);
|
||||
mods &= seat->kbd.bind_significant;
|
||||
get_current_modifiers(seat, &mods, NULL, 0, true);
|
||||
|
||||
/* Ignore selection override modifiers when
|
||||
* matching modifiers */
|
||||
|
|
|
|||
2
input.h
2
input.h
|
|
@ -33,6 +33,6 @@ void input_repeat(struct seat *seat, uint32_t key);
|
|||
void get_current_modifiers(const struct seat *seat,
|
||||
xkb_mod_mask_t *effective,
|
||||
xkb_mod_mask_t *consumed,
|
||||
uint32_t key);
|
||||
uint32_t key, bool filter_locked);
|
||||
|
||||
enum cursor_shape xcursor_for_csd_border(struct terminal *term, int x, int y);
|
||||
|
|
|
|||
9
search.c
9
search.c
|
|
@ -1374,17 +1374,12 @@ void
|
|||
search_input(struct seat *seat, struct terminal *term,
|
||||
const struct key_binding_set *bindings, uint32_t key,
|
||||
xkb_keysym_t sym, xkb_mod_mask_t mods, xkb_mod_mask_t consumed,
|
||||
xkb_mod_mask_t locked,
|
||||
const xkb_keysym_t *raw_syms, size_t raw_count,
|
||||
uint32_t serial)
|
||||
{
|
||||
LOG_DBG("search: input: sym=%d/0x%x, mods=0x%08x, consumed=0x%08x",
|
||||
sym, sym, mods, consumed);
|
||||
|
||||
const xkb_mod_mask_t bind_mods =
|
||||
mods & seat->kbd.bind_significant & ~locked;
|
||||
const xkb_mod_mask_t bind_consumed =
|
||||
consumed & seat->kbd.bind_significant & ~locked;
|
||||
enum xkb_compose_status compose_status = seat->kbd.xkb_compose_state != NULL
|
||||
? xkb_compose_state_get_status(seat->kbd.xkb_compose_state)
|
||||
: XKB_COMPOSE_NOTHING;
|
||||
|
|
@ -1399,7 +1394,7 @@ search_input(struct seat *seat, struct terminal *term,
|
|||
|
||||
/* Match translated symbol */
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (bind_mods & ~bind_consumed)) {
|
||||
bind->mods == (mods & ~consumed)) {
|
||||
|
||||
if (execute_binding(seat, term, bind, serial,
|
||||
&update_search_result, &search_direction,
|
||||
|
|
@ -1410,7 +1405,7 @@ search_input(struct seat *seat, struct terminal *term,
|
|||
return;
|
||||
}
|
||||
|
||||
if (bind->mods != bind_mods || bind_mods != (mods & ~locked))
|
||||
if (bind->mods != mods)
|
||||
continue;
|
||||
|
||||
/* Match untranslated symbols */
|
||||
|
|
|
|||
1
search.h
1
search.h
|
|
@ -11,7 +11,6 @@ void search_input(
|
|||
struct seat *seat, struct terminal *term,
|
||||
const struct key_binding_set *bindings, uint32_t key,
|
||||
xkb_keysym_t sym, xkb_mod_mask_t mods, xkb_mod_mask_t consumed,
|
||||
xkb_mod_mask_t locked,
|
||||
const xkb_keysym_t *raw_syms, size_t raw_count,
|
||||
uint32_t serial);
|
||||
void search_add_chars(struct terminal *term, const char *text, size_t len);
|
||||
|
|
|
|||
|
|
@ -3039,7 +3039,7 @@ term_mouse_grabbed(const struct terminal *term, const struct seat *seat)
|
|||
*/
|
||||
|
||||
xkb_mod_mask_t mods;
|
||||
get_current_modifiers(seat, &mods, NULL, 0);
|
||||
get_current_modifiers(seat, &mods, NULL, 0, true);
|
||||
|
||||
const struct key_binding_set *bindings =
|
||||
key_binding_for(term->wl->key_binding_manager, term->conf, seat);
|
||||
|
|
|
|||
12
url-mode.c
12
url-mode.c
|
|
@ -145,28 +145,22 @@ void
|
|||
urls_input(struct seat *seat, struct terminal *term,
|
||||
const struct key_binding_set *bindings, uint32_t key,
|
||||
xkb_keysym_t sym, xkb_mod_mask_t mods, xkb_mod_mask_t consumed,
|
||||
xkb_mod_mask_t locked,
|
||||
const xkb_keysym_t *raw_syms, size_t raw_count,
|
||||
uint32_t serial)
|
||||
{
|
||||
const xkb_mod_mask_t bind_mods =
|
||||
mods & seat->kbd.bind_significant & ~locked;
|
||||
const xkb_mod_mask_t bind_consumed =
|
||||
consumed & seat->kbd.bind_significant & ~locked;
|
||||
|
||||
/* Key bindings */
|
||||
tll_foreach(bindings->url, it) {
|
||||
const struct key_binding *bind = &it->item;
|
||||
|
||||
/* Match translated symbol */
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (bind_mods & ~bind_consumed))
|
||||
bind->mods == (mods & ~consumed))
|
||||
{
|
||||
execute_binding(seat, term, bind, serial);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bind->mods != bind_mods || bind_mods != (mods & ~locked))
|
||||
if (bind->mods != mods)
|
||||
continue;
|
||||
|
||||
for (size_t i = 0; i < raw_count; i++) {
|
||||
|
|
@ -196,7 +190,7 @@ urls_input(struct seat *seat, struct terminal *term,
|
|||
return;
|
||||
}
|
||||
|
||||
if (mods & ~consumed & ~locked)
|
||||
if (mods & ~consumed)
|
||||
return;
|
||||
|
||||
char32_t wc = xkb_state_key_get_utf32(seat->kbd.xkb_state, key);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,5 @@ void urls_reset(struct terminal *term);
|
|||
void urls_input(struct seat *seat, struct terminal *term,
|
||||
const struct key_binding_set *bindings, uint32_t key,
|
||||
xkb_keysym_t sym, xkb_mod_mask_t mods, xkb_mod_mask_t consumed,
|
||||
xkb_mod_mask_t locked,
|
||||
const xkb_keysym_t *raw_syms, size_t raw_count,
|
||||
uint32_t serial);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ struct seat {
|
|||
xkb_mod_index_t mod_caps;
|
||||
xkb_mod_index_t mod_num;
|
||||
|
||||
xkb_mod_mask_t bind_significant; /* Significant modifiers for shortcut handling */
|
||||
xkb_mod_mask_t legacy_significant; /* Significant modifiers for the legacy keyboard protocol */
|
||||
xkb_mod_mask_t kitty_significant; /* Significant modifiers for the kitty keyboard protocol */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue