From 0193f5bd9bc8d0922758e11bc257fd786383a5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Nov 2021 16:36:14 +0100 Subject: [PATCH 1/7] =?UTF-8?q?input:=20don=E2=80=99t=20ignore=20key=20rel?= =?UTF-8?q?ease=20events?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this, key release events stopped the repeat timer, and then returned. Now, we run through the entire function. Most things are still only done on key press events. But, the goal here is to get to the keyboard protocol functions (and the kitty protocol in particular), and call them on release events too. This is in preparation for the kitty protocol mode 0b10, report event types. --- input.c | 107 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/input.c b/input.c index 36991567..5294401c 100644 --- a/input.c +++ b/input.c @@ -1031,6 +1031,9 @@ static bool legacy_kbd_protocol(struct seat *seat, struct terminal *term, const struct kbd_ctx *ctx) { + if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED) + return; + enum modifier keymap_mods = MOD_NONE; keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE; keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE; @@ -1423,15 +1426,20 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, return; } - if (state == XKB_KEY_UP) { - stop_repeater(seat, key); - return; - } + const bool pressed = state == WL_KEYBOARD_KEY_STATE_PRESSED; + //const bool repeated = pressed && seat->kbd.repeat.dont_re_repeat; + 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); - 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 */ sym != XKB_KEY_Shift_L && sym != XKB_KEY_Shift_R && sym != XKB_KEY_Control_L && sym != XKB_KEY_Control_R && @@ -1448,7 +1456,8 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, enum xkb_compose_status compose_status = XKB_COMPOSE_NOTHING; 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( seat->kbd.xkb_compose_state); } @@ -1469,18 +1478,26 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, size_t raw_count = xkb_keymap_key_get_syms_by_level( seat->kbd.xkb_keymap, key, layout_idx, 0, &raw_syms); - if (term->is_searching) { - if (should_repeat) - start_repeater(seat, key); - search_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 (pressed) { + if (term->is_searching) { + if (should_repeat) + start_repeater(seat, key); + + search_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 @@ -1504,36 +1521,38 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, /* * User configurable bindings */ - tll_foreach(seat->kbd.bindings.key, it) { - const struct key_binding *bind = &it->item; + if (pressed) { + tll_foreach(seat->kbd.bindings.key, it) { + const struct key_binding *bind = &it->item; - /* Match translated symbol */ - if (bind->sym == sym && - bind->mods == (bind_mods & ~bind_consumed) && - 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( + /* Match translated symbol */ + if (bind->sym == sym && + bind->mods == (bind_mods & ~bind_consumed) && + 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; + 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)) + { + 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 +1614,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, ? kitty_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 && pressed) xkb_compose_state_reset(seat->kbd.xkb_compose_state); if (utf8 != buf) From 1df94f1468d0cdffea4cfcc68783aee4239261f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Nov 2021 18:45:28 +0100 Subject: [PATCH 2/7] =?UTF-8?q?input:=20kitty:=20add=20support=20for=20the?= =?UTF-8?q?=20=E2=80=9Creport=20event=E2=80=9D=20mode=20(0b10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input.c | 51 ++++++++++++++++++++++++++++++++++++++------------- terminal.h | 2 +- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/input.c b/input.c index 5294401c..322e1836 100644 --- a/input.c +++ b/input.c @@ -1032,7 +1032,7 @@ legacy_kbd_protocol(struct seat *seat, struct terminal *term, const struct kbd_ctx *ctx) { if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED) - return; + return false; enum modifier keymap_mods = MOD_NONE; keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE; @@ -1148,6 +1148,21 @@ static bool kitty_kbd_protocol(struct seat *seat, struct terminal *term, 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 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 && !pressed) + 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 consumed = xkb_state_key_get_consumed_mods2( seat->kbd.xkb_state, ctx->key, XKB_CONSUMED_MODE_GTK) & seat->kbd.kitty_significant; @@ -1160,11 +1175,6 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, const uint8_t *const utf8 = ctx->utf8.buf; 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) { switch (sym) { case XKB_KEY_Return: term_to_slave(term, "\r", 1); return true; @@ -1173,6 +1183,11 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, } } + if (ctx->compose_status == XKB_COMPOSE_COMPOSED && !released) { + term_to_slave(term, utf8, count); + return true; + } + /* * Printables without any modifiers are printed as is. * @@ -1182,7 +1197,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, * 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) { + if (iswprint(utf32) && (effective & ~caps_num) == 0 && !released) { term_to_slave(term, utf8, count); return true; } @@ -1324,7 +1339,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, default: if (count > 0) { - if (effective == 0) { + if (effective == 0 && !released) { term_to_slave(term, utf8, count); return true; } @@ -1391,6 +1406,16 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, 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]; int bytes; @@ -1398,14 +1423,14 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, return false; if (final == 'u' || final == '~') { - if (encoded_mods > 1) - bytes = snprintf(buf, sizeof(buf), "\x1b[%u;%u%c", - key, encoded_mods, final); + if (encoded_mods > 1 || event[0] != '\0') + bytes = snprintf(buf, sizeof(buf), "\x1b[%u;%u%s%c", + key, encoded_mods, event, final); else bytes = snprintf(buf, sizeof(buf), "\x1b[%u%c", key, final); } else { - if (encoded_mods > 1) - bytes = snprintf(buf, sizeof(buf), "\x1b[1;%u%c", encoded_mods, final); + if (encoded_mods > 1 || event[0] != '\0') + bytes = snprintf(buf, sizeof(buf), "\x1b[1;%u%s%c", encoded_mods, event, final); else bytes = snprintf(buf, sizeof(buf), "\x1b[%c", final); } diff --git a/terminal.h b/terminal.h index 62ccfb2a..6b7b01f8 100644 --- a/terminal.h +++ b/terminal.h @@ -133,7 +133,7 @@ enum kitty_kbd_flags { KITTY_KBD_REPORT_ALTERNATE = 0x04, KITTY_KBD_REPORT_ALL = 0x08, KITTY_KBD_REPORT_ASSOCIATED = 0x10, - KITTY_KBD_SUPPORTED = KITTY_KBD_DISAMBIGUATE, + KITTY_KBD_SUPPORTED = KITTY_KBD_DISAMBIGUATE | KITTY_KBD_REPORT_EVENT, }; struct grid { From 4e5d1b5c797077ac015acde91654704c1ce4d4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Nov 2021 19:03:49 +0100 Subject: [PATCH 3/7] changelog: kitty: report events --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f10509..4f33227d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,8 @@ * New value, `max`, for `[tweak].grapheme-width-method`. * Initial support for the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/). 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`) + - [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events) (mode `0b10`) * “Window menu” (compositor provided) on right clicks on the CSD title bar. From 6b9b03b8ddd1b3b1d929e2843a0b021e2522999d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 28 Nov 2021 19:20:37 +0100 Subject: [PATCH 4/7] input: kitty: treat repeating == pressed when report-events is off --- input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input.c b/input.c index 322e1836..53db8614 100644 --- a/input.c +++ b/input.c @@ -1156,7 +1156,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; - if (!report_events && !pressed) + if (!report_events && released) return false; /* TODO: should we even bother with this, or just say it’s not supported? */ From 660626118acd9c3e4cc7c022fabce53604d0b4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 29 Nov 2021 20:12:49 +0100 Subject: [PATCH 5/7] input: reset compose state on key *releases*, not presses --- input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input.c b/input.c index 53db8614..330b59b9 100644 --- a/input.c +++ b/input.c @@ -1639,7 +1639,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial, ? kitty_kbd_protocol(seat, term, &ctx) : legacy_kbd_protocol(seat, term, &ctx); - if (seat->kbd.xkb_compose_state != NULL && pressed) + if (seat->kbd.xkb_compose_state != NULL && released) xkb_compose_state_reset(seat->kbd.xkb_compose_state); if (utf8 != buf) From 93a8f51b75d308cf752a74797e6c35922cd9fc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 29 Nov 2021 20:13:23 +0100 Subject: [PATCH 6/7] input: kitty: merge handling of plain-text and composed characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All plain-text and composed characters are now printed as-is, in a single place. Also fix handling of “generic” keys when emitted as escapes; don’t use the raw XKB symbol as key in the escape, convert it to a unicode code point first. For many symbols, these are the same. But not all. For now, we fallback to using the symbol as is if XKB fails to convert it to a codepoint. Not sure if we should simply drop the key press instead. Composed characters also need special treatment; we can’t use the symbol as is, since it typically refers to the last key pressed (i.e. not the composed character). And, that key is also (usually) a special “dead” key, which cannot be converted to a unicode codepoint. So, what we do is convert the generated utf8 string, and (try to) convert it to a wchar. If it succeeds, use that. If not, fallback to using the XKB symbol (as above). --- input.c | 185 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 92 insertions(+), 93 deletions(-) diff --git a/input.c b/input.c index 330b59b9..3e3557c9 100644 --- a/input.c +++ b/input.c @@ -1151,6 +1151,7 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, 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; @@ -1159,6 +1160,9 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, 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); @@ -1183,21 +1187,10 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, } } - if (ctx->compose_status == XKB_COMPOSE_COMPOSED && !released) { - term_to_slave(term, utf8, count); - return true; - } - - /* - * Printables without any modifiers are printed as is. - * - * 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 && !released) { + /* Plain-text without modifiers, or commposed text, is emitted as-is */ + if (((iswprint(utf32) && (effective & ~caps_num) == 0) || composed) + && !released) + { term_to_slave(term, utf8, count); return true; } @@ -1319,90 +1312,96 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, case XKB_KEY_XF86AudioRaiseVolume: key = 57439; 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: key = 57358; final = 'u'; break; - case XKB_KEY_Num_Lock: key = 57360; final = 'u'; break; + case XKB_KEY_Caps_Lock: if (false) {key = 57358; final = 'u';} break; + case XKB_KEY_Num_Lock: if (false) {key = 57360; final = 'u';} break; - case XKB_KEY_Shift_L: key = 57441; final = 'u'; break; - case XKB_KEY_Control_L: key = 57442; final = 'u'; break; - case XKB_KEY_Alt_L: key = 57443; final = 'u'; break; - case XKB_KEY_Super_L: key = 57444; final = 'u'; break; - case XKB_KEY_Hyper_L: key = 57445; final = 'u'; break; - case XKB_KEY_Meta_L: key = 57446; final = 'u'; break; - case XKB_KEY_Shift_R: key = 57447; final = 'u'; break; - case XKB_KEY_Control_R: key = 57448; final = 'u'; break; - case XKB_KEY_Alt_R: key = 57449; final = 'u'; break; - case XKB_KEY_Super_R: key = 57450; final = 'u'; break; - case XKB_KEY_Hyper_R: key = 57451; final = 'u'; break; - case XKB_KEY_Meta_R: key = 57452; final = 'u'; break; -#endif + case XKB_KEY_Shift_L: if (false) {key = 57441; final = 'u';} break; + case XKB_KEY_Control_L: if (false) {key = 57442; final = 'u';} break; + case XKB_KEY_Alt_L: if (false) {key = 57443; final = 'u';} break; + case XKB_KEY_Super_L: if (false) {key = 57444; final = 'u';} break; + case XKB_KEY_Hyper_L: if (false) {key = 57445; final = 'u';} break; + case XKB_KEY_Meta_L: if (false) {key = 57446; final = 'u';} break; + case XKB_KEY_Shift_R: if (false) {key = 57447; final = 'u';} break; + case XKB_KEY_Control_R: if (false) {key = 57448; final = 'u';} break; + case XKB_KEY_Alt_R: if (false) {key = 57449; final = 'u';} break; + case XKB_KEY_Super_R: if (false) {key = 57450; final = 'u';} break; + case XKB_KEY_Hyper_R: if (false) {key = 57451; final = 'u';} break; + case XKB_KEY_Meta_R: if (false) {key = 57452; final = 'u';} break; - default: - if (count > 0) { - if (effective == 0 && !released) { - term_to_slave(term, utf8, count); - return true; + default: { + /* + * 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; } - - /* - * 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; } + } xassert(encoded_mods >= 1); From 20c887b996881495232b86b5cd7223551265c8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 2 Dec 2021 20:41:45 +0100 Subject: [PATCH 7/7] =?UTF-8?q?changelog:=20move=20entry=20to=20=E2=80=98u?= =?UTF-8?q?nreleased=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f33227d..a4e978b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,9 @@ * `[mouse-bindings].selection-override-modifiers` option, specifying which modifiers to hold to override mouse grabs by client applications and force selection instead. +* Kitty keyboard protocol: + - [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events) + (mode `0b10`) ### Changed @@ -59,7 +62,6 @@ * Initial support for the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/). Modes supported: - [Disambiguate escape codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) (mode `0b1`) - - [Report event types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events) (mode `0b10`) * “Window menu” (compositor provided) on right clicks on the CSD title bar.