mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-28 01:40:17 -05:00
input: kitty: add support for “report all keys as escape codes”
This commit is contained in:
parent
8b260568fb
commit
4e34fb8fb7
3 changed files with 60 additions and 26 deletions
|
|
@ -41,6 +41,8 @@
|
||||||
* Kitty keyboard protocol:
|
* Kitty keyboard protocol:
|
||||||
- [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events)
|
- [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events)
|
||||||
(mode `0b10`)
|
(mode `0b10`)
|
||||||
|
- [Report all keys as escape codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-all-keys)
|
||||||
|
(mode `0b1000`)
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
||||||
80
input.c
80
input.c
|
|
@ -1028,6 +1028,8 @@ legacy_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
{
|
{
|
||||||
if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED)
|
if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||||
return false;
|
return false;
|
||||||
|
if (ctx->compose_status == XKB_COMPOSE_COMPOSING)
|
||||||
|
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;
|
||||||
|
|
@ -1146,11 +1148,13 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
const bool repeating = seat->kbd.repeat.dont_re_repeat;
|
const bool repeating = seat->kbd.repeat.dont_re_repeat;
|
||||||
const bool pressed = ctx->key_state == WL_KEYBOARD_KEY_STATE_PRESSED && !repeating;
|
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 released = ctx->key_state == WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||||
|
const bool composing = ctx->compose_status == XKB_COMPOSE_COMPOSING;
|
||||||
const bool composed = ctx->compose_status == XKB_COMPOSE_COMPOSED;
|
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 enum kitty_kbd_flags flags = term->grid->kitty_kbd.flags[term->grid->kitty_kbd.idx];
|
||||||
const bool disambiguate = flags & KITTY_KBD_DISAMBIGUATE;
|
const bool disambiguate = flags & KITTY_KBD_DISAMBIGUATE;
|
||||||
const bool report_events = flags & KITTY_KBD_REPORT_EVENT;
|
const bool report_events = flags & KITTY_KBD_REPORT_EVENT;
|
||||||
|
const bool report_all_as_escapes = flags & KITTY_KBD_REPORT_ALL;
|
||||||
|
|
||||||
if (!report_events && released)
|
if (!report_events && released)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1159,7 +1163,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* TODO: should we even bother with this, or just say it’s not supported? */
|
/* TODO: should we even bother with this, or just say it’s not supported? */
|
||||||
if (!disambiguate && pressed)
|
if (!disambiguate && !report_all_as_escapes && pressed)
|
||||||
return legacy_kbd_protocol(seat, term, ctx);
|
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;
|
||||||
|
|
@ -1174,6 +1178,34 @@ 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 (composing) {
|
||||||
|
/* We never emit anything while composing, *except* modifiers
|
||||||
|
* (and only in report-all-keys-as-escape-codes mode) */
|
||||||
|
switch (sym) {
|
||||||
|
case XKB_KEY_Caps_Lock:
|
||||||
|
case XKB_KEY_Num_Lock:
|
||||||
|
case XKB_KEY_Shift_L:
|
||||||
|
case XKB_KEY_Control_L:
|
||||||
|
case XKB_KEY_Alt_L:
|
||||||
|
case XKB_KEY_Super_L:
|
||||||
|
case XKB_KEY_Hyper_L:
|
||||||
|
case XKB_KEY_Meta_L:
|
||||||
|
case XKB_KEY_Shift_R:
|
||||||
|
case XKB_KEY_Control_R:
|
||||||
|
case XKB_KEY_Alt_R:
|
||||||
|
case XKB_KEY_Super_R:
|
||||||
|
case XKB_KEY_Hyper_R:
|
||||||
|
case XKB_KEY_Meta_R:
|
||||||
|
goto emit_escapes;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report_all_as_escapes)
|
||||||
|
goto emit_escapes;
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -1190,6 +1222,8 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit_escapes:
|
||||||
|
;
|
||||||
unsigned int encoded_mods = 0;
|
unsigned int encoded_mods = 0;
|
||||||
if (seat->kbd.mod_shift != XKB_MOD_INVALID)
|
if (seat->kbd.mod_shift != XKB_MOD_INVALID)
|
||||||
encoded_mods |= mods & (1 << seat->kbd.mod_shift) ? (1 << 0) : 0;
|
encoded_mods |= mods & (1 << seat->kbd.mod_shift) ? (1 << 0) : 0;
|
||||||
|
|
@ -1307,21 +1341,21 @@ 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;
|
||||||
|
|
||||||
case XKB_KEY_Caps_Lock: if (false) {key = 57358; final = 'u';} break;
|
case XKB_KEY_Caps_Lock: if (report_all_as_escapes) {key = 57358; final = 'u';} break;
|
||||||
case XKB_KEY_Num_Lock: if (false) {key = 57360; final = 'u';} break;
|
case XKB_KEY_Num_Lock: if (report_all_as_escapes) {key = 57360; final = 'u';} break;
|
||||||
|
|
||||||
case XKB_KEY_Shift_L: if (false) {key = 57441; final = 'u';} break;
|
case XKB_KEY_Shift_L: if (report_all_as_escapes) {key = 57441; final = 'u';} break;
|
||||||
case XKB_KEY_Control_L: if (false) {key = 57442; final = 'u';} break;
|
case XKB_KEY_Control_L: if (report_all_as_escapes) {key = 57442; final = 'u';} break;
|
||||||
case XKB_KEY_Alt_L: if (false) {key = 57443; final = 'u';} break;
|
case XKB_KEY_Alt_L: if (report_all_as_escapes) {key = 57443; final = 'u';} break;
|
||||||
case XKB_KEY_Super_L: if (false) {key = 57444; final = 'u';} break;
|
case XKB_KEY_Super_L: if (report_all_as_escapes) {key = 57444; final = 'u';} break;
|
||||||
case XKB_KEY_Hyper_L: if (false) {key = 57445; final = 'u';} break;
|
case XKB_KEY_Hyper_L: if (report_all_as_escapes) {key = 57445; final = 'u';} break;
|
||||||
case XKB_KEY_Meta_L: if (false) {key = 57446; final = 'u';} break;
|
case XKB_KEY_Meta_L: if (report_all_as_escapes) {key = 57446; final = 'u';} break;
|
||||||
case XKB_KEY_Shift_R: if (false) {key = 57447; final = 'u';} break;
|
case XKB_KEY_Shift_R: if (report_all_as_escapes) {key = 57447; final = 'u';} break;
|
||||||
case XKB_KEY_Control_R: if (false) {key = 57448; final = 'u';} break;
|
case XKB_KEY_Control_R: if (report_all_as_escapes) {key = 57448; final = 'u';} break;
|
||||||
case XKB_KEY_Alt_R: if (false) {key = 57449; final = 'u';} break;
|
case XKB_KEY_Alt_R: if (report_all_as_escapes) {key = 57449; final = 'u';} break;
|
||||||
case XKB_KEY_Super_R: if (false) {key = 57450; final = 'u';} break;
|
case XKB_KEY_Super_R: if (report_all_as_escapes) {key = 57450; final = 'u';} break;
|
||||||
case XKB_KEY_Hyper_R: if (false) {key = 57451; final = 'u';} break;
|
case XKB_KEY_Hyper_R: if (report_all_as_escapes) {key = 57451; final = 'u';} break;
|
||||||
case XKB_KEY_Meta_R: if (false) {key = 57452; final = 'u';} break;
|
case XKB_KEY_Meta_R: if (report_all_as_escapes) {key = 57452; final = 'u';} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
/*
|
/*
|
||||||
|
|
@ -1382,10 +1416,8 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
|
|
||||||
if (composed) {
|
if (composed) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
if (mbtowc(&wc, (const char *)utf8, count) == count) {
|
if (mbtowc(&wc, (const char *)utf8, count) == count)
|
||||||
xassert(false);
|
|
||||||
key = wc;
|
key = wc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
|
|
@ -1481,8 +1513,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
seat->kbd.xkb_compose_state);
|
seat->kbd.xkb_compose_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compose_status == XKB_COMPOSE_COMPOSING)
|
const bool composed = compose_status == XKB_COMPOSE_COMPOSED;
|
||||||
goto maybe_repeat;
|
|
||||||
|
|
||||||
xkb_mod_mask_t mods, consumed;
|
xkb_mod_mask_t mods, consumed;
|
||||||
get_current_modifiers(seat, &mods, &consumed, key);
|
get_current_modifiers(seat, &mods, &consumed, key);
|
||||||
|
|
@ -1585,13 +1616,12 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
* Compose, and maybe emit "normal" character
|
* Compose, and maybe emit "normal" character
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xassert(seat->kbd.xkb_compose_state != NULL ||
|
xassert(seat->kbd.xkb_compose_state != NULL || !composed);
|
||||||
compose_status != XKB_COMPOSE_COMPOSED);
|
|
||||||
|
|
||||||
if (compose_status == XKB_COMPOSE_CANCELLED)
|
if (compose_status == XKB_COMPOSE_CANCELLED)
|
||||||
goto maybe_repeat;
|
goto maybe_repeat;
|
||||||
|
|
||||||
int count = compose_status == XKB_COMPOSE_COMPOSED
|
int count = composed
|
||||||
? xkb_compose_state_get_utf8(seat->kbd.xkb_compose_state, NULL, 0)
|
? xkb_compose_state_get_utf8(seat->kbd.xkb_compose_state, NULL, 0)
|
||||||
: xkb_state_key_get_utf8(seat->kbd.xkb_state, key, NULL, 0);
|
: xkb_state_key_get_utf8(seat->kbd.xkb_state, key, NULL, 0);
|
||||||
|
|
||||||
|
|
@ -1601,7 +1631,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
uint8_t *utf8 = count < sizeof(buf) ? buf : xmalloc(count + 1);
|
uint8_t *utf8 = count < sizeof(buf) ? buf : xmalloc(count + 1);
|
||||||
uint32_t utf32 = (uint32_t)-1;
|
uint32_t utf32 = (uint32_t)-1;
|
||||||
|
|
||||||
if (compose_status == XKB_COMPOSE_COMPOSED) {
|
if (composed) {
|
||||||
xkb_compose_state_get_utf8(
|
xkb_compose_state_get_utf8(
|
||||||
seat->kbd.xkb_compose_state, (char *)utf8, count + 1);
|
seat->kbd.xkb_compose_state, (char *)utf8, count + 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1633,7 +1663,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 && released)
|
if (composed && 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,9 @@ 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_REPORT_EVENT,
|
KITTY_KBD_SUPPORTED = (KITTY_KBD_DISAMBIGUATE |
|
||||||
|
KITTY_KBD_REPORT_EVENT |
|
||||||
|
KITTY_KBD_REPORT_ALL),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grid {
|
struct grid {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue