From 9d5ab91b6af513efaeb08e9bf747897641f2a809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 7 Dec 2021 19:55:52 +0100 Subject: [PATCH 1/5] =?UTF-8?q?kitty:=20initial=20support=20for=20?= =?UTF-8?q?=E2=80=9Creport=20alternate=20key=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this mode, the “shifted” and “base layout” keys are added to the CSIs, as sub-parameters to the “key” parameter. Note that this PR only implements the “shifted” key, not the “base layout key”. This is done by converting the original XKB symbol to it’s corresponding UTF-32 codepoint. If this codepoint is different from the one we use as “key” in the CSI, we add it as a sub-parameter. Related to #319 --- CHANGELOG.md | 3 +++ input.c | 10 +++++++++- terminal.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 828f51aa..6a16da7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,9 @@ * Kitty keyboard protocol: - [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events) (mode `0b10`) + - [Report alternate keys](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-alternates) + (mode `0b100`, but not that only the _shifted_ key is reported, + not the _base layout key_) - [Report all keys as escape codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-all-keys) (mode `0b1000`) - [Report associated text](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-text) diff --git a/input.c b/input.c index 869e1c67..dbbcc82b 100644 --- a/input.c +++ b/input.c @@ -1161,6 +1161,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, const bool disambiguate = flags & KITTY_KBD_DISAMBIGUATE; const bool report_events = flags & KITTY_KBD_REPORT_EVENT; + const bool report_alternate = flags & KITTY_KBD_REPORT_ALTERNATE; const bool report_all_as_escapes = flags & KITTY_KBD_REPORT_ALL; if (!report_events && released) @@ -1252,7 +1253,7 @@ emit_escapes: encoded_mods |= mods & (1 << seat->kbd.mod_num) ? (1 << 7) : 0; encoded_mods++; - int key = -1; + int key = -1, alternate = -1; char final; switch (sym) { @@ -1435,6 +1436,8 @@ emit_escapes: key = xkb_keysym_to_utf32(sym_to_use); if (key == 0) key = sym_to_use; + else + alternate = xkb_keysym_to_utf32(sym); } final = 'u'; @@ -1465,6 +1468,11 @@ emit_escapes: bytes = snprintf(p, left, "\x1b[%u", key); p += bytes; left -= bytes; + if (report_alternate && alternate > 0 && alternate != key) { + bytes = snprintf(p, left, ":%u", alternate); + p += bytes; left -= bytes; + } + if (encoded_mods > 1 || event[0] != '\0' || report_associated_text) { bytes = snprintf(p, left, ";%u%s", encoded_mods, event); p += bytes; left -= bytes; diff --git a/terminal.h b/terminal.h index 394871f6..09b04614 100644 --- a/terminal.h +++ b/terminal.h @@ -135,6 +135,7 @@ enum kitty_kbd_flags { KITTY_KBD_REPORT_ASSOCIATED = 0x10, KITTY_KBD_SUPPORTED = (KITTY_KBD_DISAMBIGUATE | KITTY_KBD_REPORT_EVENT | + KITTY_KBD_REPORT_ALTERNATE | KITTY_KBD_REPORT_ALL | KITTY_KBD_REPORT_ASSOCIATED), }; From 9b57ef07f14a66727223d4ab5457ebff57448b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 7 Dec 2021 20:25:14 +0100 Subject: [PATCH 2/5] =?UTF-8?q?kitty:=20implement=20=E2=80=9Cbase=20layout?= =?UTF-8?q?=20key=E2=80=9D=20in=20=E2=80=9Creport=20alternate=20key?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/input.c b/input.c index dbbcc82b..b5876baa 100644 --- a/input.c +++ b/input.c @@ -1253,7 +1253,7 @@ emit_escapes: encoded_mods |= mods & (1 << seat->kbd.mod_num) ? (1 << 7) : 0; encoded_mods++; - int key = -1, alternate = -1; + int key = -1, alternate = -1, base = -1; char final; switch (sym) { @@ -1436,8 +1436,23 @@ emit_escapes: key = xkb_keysym_to_utf32(sym_to_use); if (key == 0) key = sym_to_use; - else + + if (report_alternate) { + /* The *shifted* key. May be the same as the unshifted + * key - if so, this is filtered out below, when + * emitting the CSI */ alternate = xkb_keysym_to_utf32(sym); + + /* Base layout key. I.e the symbol the pressed key + * produces in the base/default layout (layout idx + * 0) */ + const xkb_keysym_t *base_syms; + int base_sym_count = xkb_keymap_key_get_syms_by_level( + seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms); + + if (base_sym_count > 0) + base = xkb_keysym_to_utf32(base_syms[0]); + } } final = 'u'; @@ -1468,9 +1483,20 @@ emit_escapes: bytes = snprintf(p, left, "\x1b[%u", key); p += bytes; left -= bytes; - if (report_alternate && alternate > 0 && alternate != key) { - bytes = snprintf(p, left, ":%u", alternate); - p += bytes; left -= bytes; + if (report_alternate) { + bool emit_alternate = alternate > 0 && alternate != key; + bool emit_base = base > 0 && base != key && base != alternate; + + if (emit_alternate) { + bytes = snprintf(p, left, ":%u", alternate); + p += bytes; left -= bytes; + } + + if (emit_base) { + bytes = snprintf( + p, left, "%s:%u", !emit_alternate ? ":" : "", base); + p += bytes; left -= bytes; + } } if (encoded_mods > 1 || event[0] != '\0' || report_associated_text) { From c0cfec89e0093c10253416e26efdcb8e38f7fd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 7 Dec 2021 21:48:42 +0100 Subject: [PATCH 3/5] kitty: report-alternate: apply base-layout key to composed characters --- input.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/input.c b/input.c index b5876baa..7587f729 100644 --- a/input.c +++ b/input.c @@ -1437,22 +1437,24 @@ emit_escapes: if (key == 0) key = sym_to_use; - if (report_alternate) { - /* The *shifted* key. May be the same as the unshifted - * key - if so, this is filtered out below, when - * emitting the CSI */ + if (report_alternate) alternate = xkb_keysym_to_utf32(sym); + } - /* Base layout key. I.e the symbol the pressed key - * produces in the base/default layout (layout idx - * 0) */ - const xkb_keysym_t *base_syms; - int base_sym_count = xkb_keymap_key_get_syms_by_level( - seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms); + if (report_alternate) { + /* The *shifted* key. May be the same as the unshifted + * key - if so, this is filtered out below, when + * emitting the CSI */ - if (base_sym_count > 0) - base = xkb_keysym_to_utf32(base_syms[0]); - } + /* Base layout key. I.e the symbol the pressed key + * produces in the base/default layout (layout idx + * 0) */ + const xkb_keysym_t *base_syms; + int base_sym_count = xkb_keymap_key_get_syms_by_level( + seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms); + + if (base_sym_count > 0) + base = xkb_keysym_to_utf32(base_syms[0]); } final = 'u'; From 52eee4482bf823455acd61617eba3a74702763d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 7 Dec 2021 21:52:43 +0100 Subject: [PATCH 4/5] =?UTF-8?q?kitty:=20when=20emitting=20associated=20tex?= =?UTF-8?q?t,=20don=E2=80=99t=20report=20mods/events=20unless=20necessary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/input.c b/input.c index 7587f729..e0587b17 100644 --- a/input.c +++ b/input.c @@ -1465,7 +1465,7 @@ emit_escapes: xassert(encoded_mods >= 1); char event[4]; - if (report_events) { + if (report_events /*&& !pressed*/) { /* Note: this deviates slightly from Kitty, which omits the * “:1” subparameter for key press events */ event[0] = ':'; @@ -1501,14 +1501,16 @@ emit_escapes: } } - if (encoded_mods > 1 || event[0] != '\0' || report_associated_text) { + bool emit_mods = encoded_mods > 1 || event[0] != '\0'; + + if (emit_mods) { bytes = snprintf(p, left, ";%u%s", encoded_mods, event); p += bytes; left -= bytes; + } - if (report_associated_text) { - bytes = snprintf(p, left, ";%u", utf32); - p += bytes; left -= bytes; - } + if (report_associated_text) { + bytes = snprintf(p, left, "%s;%u", !emit_mods ? ";" : "", utf32); + p += bytes; left -= bytes; } bytes = snprintf(p, left, "%c", final); From 34ce9f97bbe1502bdd24650a36b0e3da06cef77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 7 Dec 2021 22:22:55 +0100 Subject: [PATCH 5/5] kitty: simplify: always calculate alternate/base keys But only _emit_ them if report alternate has been enabled. --- input.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/input.c b/input.c index e0587b17..41349d9a 100644 --- a/input.c +++ b/input.c @@ -1437,26 +1437,21 @@ emit_escapes: if (key == 0) key = sym_to_use; - if (report_alternate) - alternate = xkb_keysym_to_utf32(sym); - } - - if (report_alternate) { /* The *shifted* key. May be the same as the unshifted * key - if so, this is filtered out below, when * emitting the CSI */ - - /* Base layout key. I.e the symbol the pressed key - * produces in the base/default layout (layout idx - * 0) */ - const xkb_keysym_t *base_syms; - int base_sym_count = xkb_keymap_key_get_syms_by_level( - seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms); - - if (base_sym_count > 0) - base = xkb_keysym_to_utf32(base_syms[0]); + alternate = xkb_keysym_to_utf32(sym); } + /* Base layout key. I.e the symbol the pressed key produces in + * the base/default layout (layout idx 0) */ + const xkb_keysym_t *base_syms; + int base_sym_count = xkb_keymap_key_get_syms_by_level( + seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms); + + if (base_sym_count > 0) + base = xkb_keysym_to_utf32(base_syms[0]); + final = 'u'; break; }