mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-19 05:33:44 -04:00
commit
a62e3cdb3d
3 changed files with 190 additions and 144 deletions
|
|
@ -41,6 +41,9 @@
|
||||||
* `[mouse-bindings].selection-override-modifiers` option, specifying
|
* `[mouse-bindings].selection-override-modifiers` option, specifying
|
||||||
which modifiers to hold to override mouse grabs by client
|
which modifiers to hold to override mouse grabs by client
|
||||||
applications and force selection instead.
|
applications and force selection instead.
|
||||||
|
* Kitty keyboard protocol:
|
||||||
|
- [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events)
|
||||||
|
(mode `0b10`)
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
@ -58,7 +61,7 @@
|
||||||
* New value, `max`, for `[tweak].grapheme-width-method`.
|
* New value, `max`, for `[tweak].grapheme-width-method`.
|
||||||
* Initial support for the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).
|
* Initial support for the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).
|
||||||
Modes supported:
|
Modes supported:
|
||||||
- [Disambiguate escape codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate)
|
- [Disambiguate escape codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) (mode `0b1`)
|
||||||
* “Window menu” (compositor provided) on right clicks on the CSD title
|
* “Window menu” (compositor provided) on right clicks on the CSD title
|
||||||
bar.
|
bar.
|
||||||
|
|
||||||
|
|
|
||||||
327
input.c
327
input.c
|
|
@ -1031,6 +1031,9 @@ static bool
|
||||||
legacy_kbd_protocol(struct seat *seat, struct terminal *term,
|
legacy_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
const struct kbd_ctx *ctx)
|
const struct kbd_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||||
|
return false;
|
||||||
|
|
||||||
enum modifier keymap_mods = MOD_NONE;
|
enum modifier keymap_mods = MOD_NONE;
|
||||||
keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE;
|
keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE;
|
||||||
keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE;
|
keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE;
|
||||||
|
|
@ -1145,6 +1148,25 @@ static bool
|
||||||
kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
const struct kbd_ctx *ctx)
|
const struct kbd_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
const bool repeating = seat->kbd.repeat.dont_re_repeat;
|
||||||
|
const bool pressed = ctx->key_state == WL_KEYBOARD_KEY_STATE_PRESSED && !repeating;
|
||||||
|
const bool released = ctx->key_state == WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||||
|
const bool composed = ctx->compose_status == XKB_COMPOSE_COMPOSED;
|
||||||
|
|
||||||
|
const enum kitty_kbd_flags flags = term->grid->kitty_kbd.flags[term->grid->kitty_kbd.idx];
|
||||||
|
const bool disambiguate = flags & KITTY_KBD_DISAMBIGUATE;
|
||||||
|
const bool report_events = flags & KITTY_KBD_REPORT_EVENT;
|
||||||
|
|
||||||
|
if (!report_events && released)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (composed && released)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* TODO: should we even bother with this, or just say it’s not supported? */
|
||||||
|
if (!disambiguate && pressed)
|
||||||
|
return legacy_kbd_protocol(seat, term, ctx);
|
||||||
|
|
||||||
const xkb_mod_mask_t mods = ctx->mods & seat->kbd.kitty_significant;
|
const xkb_mod_mask_t mods = ctx->mods & seat->kbd.kitty_significant;
|
||||||
const xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
|
const xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
|
||||||
seat->kbd.xkb_state, ctx->key, XKB_CONSUMED_MODE_GTK) & seat->kbd.kitty_significant;
|
seat->kbd.xkb_state, ctx->key, XKB_CONSUMED_MODE_GTK) & seat->kbd.kitty_significant;
|
||||||
|
|
@ -1157,11 +1179,6 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
const uint8_t *const utf8 = ctx->utf8.buf;
|
const uint8_t *const utf8 = ctx->utf8.buf;
|
||||||
const size_t count = ctx->utf8.count;
|
const size_t count = ctx->utf8.count;
|
||||||
|
|
||||||
if (ctx->compose_status == XKB_COMPOSE_COMPOSED) {
|
|
||||||
term_to_slave(term, utf8, count);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effective == 0) {
|
if (effective == 0) {
|
||||||
switch (sym) {
|
switch (sym) {
|
||||||
case XKB_KEY_Return: term_to_slave(term, "\r", 1); return true;
|
case XKB_KEY_Return: term_to_slave(term, "\r", 1); return true;
|
||||||
|
|
@ -1170,16 +1187,10 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Plain-text without modifiers, or commposed text, is emitted as-is */
|
||||||
* Printables without any modifiers are printed as is.
|
if (((iswprint(utf32) && (effective & ~caps_num) == 0) || composed)
|
||||||
*
|
&& !released)
|
||||||
* TODO: plain text keys (a-z, 0-9 etc) are still printed as text,
|
{
|
||||||
* even when NumLock is active, despite NumLock being a
|
|
||||||
* significant modifier, *and* despite NumLock affecting other
|
|
||||||
* keys, like Return and Backspace; figure out if there’s some
|
|
||||||
* better magic than filtering out Caps- and Num-Lock here..
|
|
||||||
*/
|
|
||||||
if (iswprint(utf32) && (effective & ~caps_num) == 0) {
|
|
||||||
term_to_slave(term, utf8, count);
|
term_to_slave(term, utf8, count);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1301,93 +1312,109 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
case XKB_KEY_XF86AudioRaiseVolume: key = 57439; final = 'u'; break;
|
case XKB_KEY_XF86AudioRaiseVolume: key = 57439; final = 'u'; break;
|
||||||
case XKB_KEY_XF86AudioMute: key = 57440; final = 'u'; break;
|
case XKB_KEY_XF86AudioMute: key = 57440; final = 'u'; break;
|
||||||
|
|
||||||
#if 0 /* TODO: enable when “Report all keys as escape codes” is enabled */
|
case XKB_KEY_Caps_Lock: if (false) {key = 57358; final = 'u';} break;
|
||||||
case XKB_KEY_Caps_Lock: key = 57358; final = 'u'; break;
|
case XKB_KEY_Num_Lock: if (false) {key = 57360; final = 'u';} break;
|
||||||
case XKB_KEY_Num_Lock: key = 57360; final = 'u'; break;
|
|
||||||
|
|
||||||
case XKB_KEY_Shift_L: key = 57441; final = 'u'; break;
|
case XKB_KEY_Shift_L: if (false) {key = 57441; final = 'u';} break;
|
||||||
case XKB_KEY_Control_L: key = 57442; final = 'u'; break;
|
case XKB_KEY_Control_L: if (false) {key = 57442; final = 'u';} break;
|
||||||
case XKB_KEY_Alt_L: key = 57443; final = 'u'; break;
|
case XKB_KEY_Alt_L: if (false) {key = 57443; final = 'u';} break;
|
||||||
case XKB_KEY_Super_L: key = 57444; final = 'u'; break;
|
case XKB_KEY_Super_L: if (false) {key = 57444; final = 'u';} break;
|
||||||
case XKB_KEY_Hyper_L: key = 57445; final = 'u'; break;
|
case XKB_KEY_Hyper_L: if (false) {key = 57445; final = 'u';} break;
|
||||||
case XKB_KEY_Meta_L: key = 57446; final = 'u'; break;
|
case XKB_KEY_Meta_L: if (false) {key = 57446; final = 'u';} break;
|
||||||
case XKB_KEY_Shift_R: key = 57447; final = 'u'; break;
|
case XKB_KEY_Shift_R: if (false) {key = 57447; final = 'u';} break;
|
||||||
case XKB_KEY_Control_R: key = 57448; final = 'u'; break;
|
case XKB_KEY_Control_R: if (false) {key = 57448; final = 'u';} break;
|
||||||
case XKB_KEY_Alt_R: key = 57449; final = 'u'; break;
|
case XKB_KEY_Alt_R: if (false) {key = 57449; final = 'u';} break;
|
||||||
case XKB_KEY_Super_R: key = 57450; final = 'u'; break;
|
case XKB_KEY_Super_R: if (false) {key = 57450; final = 'u';} break;
|
||||||
case XKB_KEY_Hyper_R: key = 57451; final = 'u'; break;
|
case XKB_KEY_Hyper_R: if (false) {key = 57451; final = 'u';} break;
|
||||||
case XKB_KEY_Meta_R: key = 57452; final = 'u'; break;
|
case XKB_KEY_Meta_R: if (false) {key = 57452; final = 'u';} break;
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
if (count > 0) {
|
/*
|
||||||
if (effective == 0) {
|
* Use keysym (typically its Unicode codepoint value).
|
||||||
term_to_slave(term, utf8, count);
|
*
|
||||||
return true;
|
* If the keysym is shifted, use its unshifted codepoint
|
||||||
|
* instead. In other words, ctrl+a and ctrl+shift+a should
|
||||||
|
* both use the same value for ‘key’ (97 - i.a. ‘a’).
|
||||||
|
*
|
||||||
|
* However, if a non-significant modifier was used to
|
||||||
|
* generate the symbol. This is needed since we cannot
|
||||||
|
* encode non-significant modifiers, and thus the “extra”
|
||||||
|
* modifier(s) would get lost.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* the Swedish layout has ‘2’, QUOTATION MARK (“double
|
||||||
|
* quote”), ‘@’, and ‘²’ on the same key. ‘2’ is the base
|
||||||
|
* symbol.
|
||||||
|
*
|
||||||
|
* Shift+2 results in QUOTATION MARK
|
||||||
|
* AltGr+2 results in ‘@’
|
||||||
|
* AltGr+Shift+2 results in ‘²’
|
||||||
|
*
|
||||||
|
* The kitty kbd protocol can’t encode AltGr. So, if we
|
||||||
|
* always used the base symbol (‘2’), Alt+Shift+2 would
|
||||||
|
* result in the same escape sequence as
|
||||||
|
* AltGr+Alt+Shift+2.
|
||||||
|
*
|
||||||
|
* (yes, this matches what kitty does, as of 0.23.1)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get the key’s shift level */
|
||||||
|
xkb_level_index_t lvl = xkb_state_key_get_level(
|
||||||
|
seat->kbd.xkb_state, ctx->key, ctx->layout);
|
||||||
|
|
||||||
|
/* And get all modifier combinations that, combined with
|
||||||
|
* the pressed key, results in the current shift level */
|
||||||
|
xkb_mod_mask_t masks[32];
|
||||||
|
size_t mask_count = xkb_keymap_key_get_mods_for_level(
|
||||||
|
seat->kbd.xkb_keymap, ctx->key, ctx->layout, lvl,
|
||||||
|
masks, ALEN(masks));
|
||||||
|
|
||||||
|
/* Check modifier combinations - if a combination has
|
||||||
|
* modifiers not in our set of ‘significant’ modifiers,
|
||||||
|
* use key sym as-is */
|
||||||
|
bool use_level0_sym = true;
|
||||||
|
for (size_t i = 0; i < mask_count; i++) {
|
||||||
|
if ((masks[i] & ~seat->kbd.kitty_significant) > 0) {
|
||||||
|
use_level0_sym = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Use keysym (typically its Unicode codepoint value).
|
|
||||||
*
|
|
||||||
* If the keysym is shifted, use its unshifted codepoint
|
|
||||||
* instead. In other words, ctrl+a and ctrl+shift+a should
|
|
||||||
* both use the same value for ‘key’ (97 - i.a. ‘a’).
|
|
||||||
*
|
|
||||||
* However, if a non-significant modifier was used to
|
|
||||||
* generate the symbol. This is needed since we cannot
|
|
||||||
* encode non-significant modifiers, and thus the “extra”
|
|
||||||
* modifier(s) would get lost.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* the Swedish layout has ‘2’, QUOTATION MARK (“double
|
|
||||||
* quote”), ‘@’, and ‘²’ on the same key. ‘2’ is the base
|
|
||||||
* symbol.
|
|
||||||
*
|
|
||||||
* Shift+2 results in QUOTATION MARK
|
|
||||||
* AltGr+2 results in ‘@’
|
|
||||||
* AltGr+Shift+2 results in ‘²’
|
|
||||||
*
|
|
||||||
* The kitty kbd protocol can’t encode AltGr. So, if we
|
|
||||||
* always used the base symbol (‘2’), Alt+Shift+2 would
|
|
||||||
* result in the same escape sequence as
|
|
||||||
* AltGr+Alt+Shift+2.
|
|
||||||
*
|
|
||||||
* (yes, this matches what kitty does, as of 0.23.1)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Get the key’s shift level */
|
|
||||||
xkb_level_index_t lvl = xkb_state_key_get_level(
|
|
||||||
seat->kbd.xkb_state, ctx->key, ctx->layout);
|
|
||||||
|
|
||||||
/* And get all modifier combinations that, combined with
|
|
||||||
* the pressed key, results in the current shift level */
|
|
||||||
xkb_mod_mask_t masks[32];
|
|
||||||
size_t mask_count = xkb_keymap_key_get_mods_for_level(
|
|
||||||
seat->kbd.xkb_keymap, ctx->key, ctx->layout, lvl,
|
|
||||||
masks, ALEN(masks));
|
|
||||||
|
|
||||||
/* Check modifier combinations - if a combination has
|
|
||||||
* modifiers not in our set of ‘significant’ modifiers,
|
|
||||||
* use key sym as-is */
|
|
||||||
bool use_level0_sym = true;
|
|
||||||
for (size_t i = 0; i < mask_count; i++) {
|
|
||||||
if ((masks[i] & ~seat->kbd.kitty_significant) > 0) {
|
|
||||||
use_level0_sym = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key = use_level0_sym && ctx->level0_syms.count > 0
|
|
||||||
? ctx->level0_syms.syms[0]
|
|
||||||
: sym;
|
|
||||||
final = 'u';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xkb_keysym_t sym_to_use = use_level0_sym && ctx->level0_syms.count > 0
|
||||||
|
? ctx->level0_syms.syms[0]
|
||||||
|
: sym;
|
||||||
|
|
||||||
|
if (composed) {
|
||||||
|
wchar_t wc;
|
||||||
|
if (mbtowc(&wc, (const char *)utf8, count) == count) {
|
||||||
|
xassert(false);
|
||||||
|
key = wc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key < 0) {
|
||||||
|
key = xkb_keysym_to_utf32(sym_to_use);
|
||||||
|
if (key == 0)
|
||||||
|
key = sym_to_use;
|
||||||
|
}
|
||||||
|
final = 'u';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xassert(encoded_mods >= 1);
|
xassert(encoded_mods >= 1);
|
||||||
|
|
||||||
|
char event[4];
|
||||||
|
if (report_events) {
|
||||||
|
/* Note: this deviates slightly from Kitty, which omits the
|
||||||
|
* “:1” subparameter for key press events */
|
||||||
|
event[0] = ':';
|
||||||
|
event[1] = '0' + (pressed ? 1 : repeating ? 2 : 3);
|
||||||
|
event[2] = '\0';
|
||||||
|
} else
|
||||||
|
event[0] = '\0';
|
||||||
|
|
||||||
char buf[16];
|
char buf[16];
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
|
|
@ -1395,14 +1422,14 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (final == 'u' || final == '~') {
|
if (final == 'u' || final == '~') {
|
||||||
if (encoded_mods > 1)
|
if (encoded_mods > 1 || event[0] != '\0')
|
||||||
bytes = snprintf(buf, sizeof(buf), "\x1b[%u;%u%c",
|
bytes = snprintf(buf, sizeof(buf), "\x1b[%u;%u%s%c",
|
||||||
key, encoded_mods, final);
|
key, encoded_mods, event, final);
|
||||||
else
|
else
|
||||||
bytes = snprintf(buf, sizeof(buf), "\x1b[%u%c", key, final);
|
bytes = snprintf(buf, sizeof(buf), "\x1b[%u%c", key, final);
|
||||||
} else {
|
} else {
|
||||||
if (encoded_mods > 1)
|
if (encoded_mods > 1 || event[0] != '\0')
|
||||||
bytes = snprintf(buf, sizeof(buf), "\x1b[1;%u%c", encoded_mods, final);
|
bytes = snprintf(buf, sizeof(buf), "\x1b[1;%u%s%c", encoded_mods, event, final);
|
||||||
else
|
else
|
||||||
bytes = snprintf(buf, sizeof(buf), "\x1b[%c", final);
|
bytes = snprintf(buf, sizeof(buf), "\x1b[%c", final);
|
||||||
}
|
}
|
||||||
|
|
@ -1423,15 +1450,20 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == XKB_KEY_UP) {
|
const bool pressed = state == WL_KEYBOARD_KEY_STATE_PRESSED;
|
||||||
stop_repeater(seat, key);
|
//const bool repeated = pressed && seat->kbd.repeat.dont_re_repeat;
|
||||||
return;
|
const bool released = state == WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||||
}
|
|
||||||
|
if (released)
|
||||||
|
stop_repeater(seat, key);
|
||||||
|
|
||||||
|
bool should_repeat =
|
||||||
|
pressed && xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key);
|
||||||
|
|
||||||
bool should_repeat = xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key);
|
|
||||||
xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->kbd.xkb_state, key);
|
xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->kbd.xkb_state, key);
|
||||||
|
|
||||||
if (state == XKB_KEY_DOWN && term->conf->mouse.hide_when_typing &&
|
if (pressed && term->conf->mouse.hide_when_typing &&
|
||||||
|
|
||||||
/* TODO: better way to detect modifiers */
|
/* TODO: better way to detect modifiers */
|
||||||
sym != XKB_KEY_Shift_L && sym != XKB_KEY_Shift_R &&
|
sym != XKB_KEY_Shift_L && sym != XKB_KEY_Shift_R &&
|
||||||
sym != XKB_KEY_Control_L && sym != XKB_KEY_Control_R &&
|
sym != XKB_KEY_Control_L && sym != XKB_KEY_Control_R &&
|
||||||
|
|
@ -1448,7 +1480,8 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
enum xkb_compose_status compose_status = XKB_COMPOSE_NOTHING;
|
enum xkb_compose_status compose_status = XKB_COMPOSE_NOTHING;
|
||||||
|
|
||||||
if (seat->kbd.xkb_compose_state != NULL) {
|
if (seat->kbd.xkb_compose_state != NULL) {
|
||||||
xkb_compose_state_feed(seat->kbd.xkb_compose_state, sym);
|
if (pressed)
|
||||||
|
xkb_compose_state_feed(seat->kbd.xkb_compose_state, sym);
|
||||||
compose_status = xkb_compose_state_get_status(
|
compose_status = xkb_compose_state_get_status(
|
||||||
seat->kbd.xkb_compose_state);
|
seat->kbd.xkb_compose_state);
|
||||||
}
|
}
|
||||||
|
|
@ -1469,18 +1502,26 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
size_t raw_count = xkb_keymap_key_get_syms_by_level(
|
size_t raw_count = xkb_keymap_key_get_syms_by_level(
|
||||||
seat->kbd.xkb_keymap, key, layout_idx, 0, &raw_syms);
|
seat->kbd.xkb_keymap, key, layout_idx, 0, &raw_syms);
|
||||||
|
|
||||||
if (term->is_searching) {
|
if (pressed) {
|
||||||
if (should_repeat)
|
if (term->is_searching) {
|
||||||
start_repeater(seat, key);
|
if (should_repeat)
|
||||||
search_input(
|
start_repeater(seat, key);
|
||||||
seat, term, key, sym, bind_mods, bind_consumed, raw_syms, raw_count, serial);
|
|
||||||
return;
|
search_input(
|
||||||
} else if (urls_mode_is_active(term)) {
|
seat, term, key, sym, bind_mods, bind_consumed,
|
||||||
if (should_repeat)
|
raw_syms, raw_count, serial);
|
||||||
start_repeater(seat, key);
|
return;
|
||||||
urls_input(
|
}
|
||||||
seat, term, key, sym, bind_mods, bind_consumed, raw_syms, raw_count, serial);
|
|
||||||
return;
|
else if (urls_mode_is_active(term)) {
|
||||||
|
if (should_repeat)
|
||||||
|
start_repeater(seat, key);
|
||||||
|
|
||||||
|
urls_input(
|
||||||
|
seat, term, key, sym, bind_mods, bind_consumed,
|
||||||
|
raw_syms, raw_count, serial);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -1504,36 +1545,38 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
/*
|
/*
|
||||||
* User configurable bindings
|
* User configurable bindings
|
||||||
*/
|
*/
|
||||||
tll_foreach(seat->kbd.bindings.key, it) {
|
if (pressed) {
|
||||||
const struct key_binding *bind = &it->item;
|
tll_foreach(seat->kbd.bindings.key, it) {
|
||||||
|
const struct key_binding *bind = &it->item;
|
||||||
|
|
||||||
/* Match translated symbol */
|
/* Match translated symbol */
|
||||||
if (bind->sym == sym &&
|
if (bind->sym == sym &&
|
||||||
bind->mods == (bind_mods & ~bind_consumed) &&
|
bind->mods == (bind_mods & ~bind_consumed) &&
|
||||||
execute_binding(
|
execute_binding(
|
||||||
seat, term, bind->action, bind->pipe_argv, serial))
|
|
||||||
{
|
|
||||||
goto maybe_repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind->mods != bind_mods)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Match untranslated symbols */
|
|
||||||
for (size_t i = 0; i < raw_count; i++) {
|
|
||||||
if (bind->sym == raw_syms[i] && execute_binding(
|
|
||||||
seat, term, bind->action, bind->pipe_argv, serial))
|
seat, term, bind->action, bind->pipe_argv, serial))
|
||||||
{
|
{
|
||||||
goto maybe_repeat;
|
goto maybe_repeat;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Match raw key code */
|
if (bind->mods != bind_mods)
|
||||||
tll_foreach(bind->key_codes, code) {
|
continue;
|
||||||
if (code->item == key && execute_binding(
|
|
||||||
seat, term, bind->action, bind->pipe_argv, serial))
|
/* Match untranslated symbols */
|
||||||
{
|
for (size_t i = 0; i < raw_count; i++) {
|
||||||
goto maybe_repeat;
|
if (bind->sym == raw_syms[i] && execute_binding(
|
||||||
|
seat, term, bind->action, bind->pipe_argv, serial))
|
||||||
|
{
|
||||||
|
goto maybe_repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Match raw key code */
|
||||||
|
tll_foreach(bind->key_codes, code) {
|
||||||
|
if (code->item == key && execute_binding(
|
||||||
|
seat, term, bind->action, bind->pipe_argv, serial))
|
||||||
|
{
|
||||||
|
goto maybe_repeat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1595,7 +1638,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
? kitty_kbd_protocol(seat, term, &ctx)
|
? kitty_kbd_protocol(seat, term, &ctx)
|
||||||
: legacy_kbd_protocol(seat, term, &ctx);
|
: legacy_kbd_protocol(seat, term, &ctx);
|
||||||
|
|
||||||
if (seat->kbd.xkb_compose_state != NULL)
|
if (seat->kbd.xkb_compose_state != NULL && released)
|
||||||
xkb_compose_state_reset(seat->kbd.xkb_compose_state);
|
xkb_compose_state_reset(seat->kbd.xkb_compose_state);
|
||||||
|
|
||||||
if (utf8 != buf)
|
if (utf8 != buf)
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ enum kitty_kbd_flags {
|
||||||
KITTY_KBD_REPORT_ALTERNATE = 0x04,
|
KITTY_KBD_REPORT_ALTERNATE = 0x04,
|
||||||
KITTY_KBD_REPORT_ALL = 0x08,
|
KITTY_KBD_REPORT_ALL = 0x08,
|
||||||
KITTY_KBD_REPORT_ASSOCIATED = 0x10,
|
KITTY_KBD_REPORT_ASSOCIATED = 0x10,
|
||||||
KITTY_KBD_SUPPORTED = KITTY_KBD_DISAMBIGUATE,
|
KITTY_KBD_SUPPORTED = KITTY_KBD_DISAMBIGUATE | KITTY_KBD_REPORT_EVENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grid {
|
struct grid {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue