feat(tui): handle kitty key events in libtermkey (#31727)

Enable key event reporting in the kitty keyboard protocol. This causes
supporting terminals to send key events for presses, repeats, and key
releases. For now we ignore release events, but eventually we will
support users mapping those.
This commit is contained in:
Gregory Anders 2024-12-31 08:29:14 -06:00 committed by GitHub
parent e00cd1ab40
commit 4fb3b57a19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 5 deletions

View File

@ -431,6 +431,15 @@ static void tk_getkeys(TermInput *input, bool force)
TermKeyResult result;
while ((result = tk_getkey(input->tk, &key, force)) == TERMKEY_RES_KEY) {
// Only press and repeat events are handled for now
switch (key.event) {
case TERMKEY_EVENT_PRESS:
case TERMKEY_EVENT_REPEAT:
break;
default:
continue;
}
if (key.type == TERMKEY_TYPE_UNICODE && !key.modifiers) {
forward_simple_utf8(input, &key);
} else if (key.type == TERMKEY_TYPE_UNICODE

View File

@ -177,9 +177,21 @@ static TermKeyResult handle_csi_u(TermKey *tk, TermKeyKey *key, int cmd, TermKey
return TERMKEY_RES_ERROR;
}
if (nsubparams > 0 && subparam != 1) {
// Not a press event. Ignore for now
return TERMKEY_RES_NONE;
if (nsubparams > 0) {
switch (subparam) {
case 1:
key->event = TERMKEY_EVENT_PRESS;
break;
case 2:
key->event = TERMKEY_EVENT_REPEAT;
break;
case 3:
key->event = TERMKEY_EVENT_RELEASE;
break;
default:
// Invalid event
return TERMKEY_RES_NONE;
}
}
key->modifiers = args[1] - 1;

View File

@ -834,6 +834,9 @@ static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nb
return TERMKEY_RES_ERROR;
}
// Press is the default event type.
key->event = TERMKEY_EVENT_PRESS;
#ifdef DEBUG
fprintf(stderr, "getkey(force=%d): buffer ", force);
print_buffer(tk);

View File

@ -123,6 +123,12 @@ typedef enum {
TERMKEY_MOUSE_RELEASE,
} TermKeyMouseEvent;
typedef enum {
TERMKEY_EVENT_PRESS,
TERMKEY_EVENT_REPEAT,
TERMKEY_EVENT_RELEASE,
} TermKeyEvent;
enum {
TERMKEY_KEYMOD_SHIFT = 1 << 0,
TERMKEY_KEYMOD_ALT = 1 << 1,
@ -163,6 +169,8 @@ typedef struct {
int modifiers;
TermKeyEvent event;
// Any Unicode character can be UTF-8 encoded in no more than 6 bytes, plus
// terminating NUL
char utf8[7];

View File

@ -296,7 +296,10 @@ void tui_set_key_encoding(TUIData *tui)
{
switch (tui->input.key_encoding) {
case kKeyEncodingKitty:
out(tui, S_LEN("\x1b[>1u"));
// Progressive enhancement flags:
// 0b01 (1) Disambiguate escape codes
// 0b10 (2) Report event types
out(tui, S_LEN("\x1b[>3u"));
break;
case kKeyEncodingXterm:
out(tui, S_LEN("\x1b[>4;2m"));
@ -311,7 +314,7 @@ static void tui_reset_key_encoding(TUIData *tui)
{
switch (tui->input.key_encoding) {
case kKeyEncodingKitty:
out(tui, S_LEN("\x1b[<1u"));
out(tui, S_LEN("\x1b[<u"));
break;
case kKeyEncodingXterm:
out(tui, S_LEN("\x1b[>4;0m"));