Commit 54b212d
Umputun
·
2026-09-25 15:52:53 -0400 EDT
parent 878a8b0
fix: kitty keyboard status reply should not take leadership (#266) isUserInput accepted any CSI ending in u, so the terminal's CSI ? flags u reply to a keyboard status query promoted a follower. Skip that sequence and keep scanning the payload.
2 files changed,
+20,
-1
+4,
-0
| ... | ... | @@ -8,6 +8,10 @@ Use spec: https://common-changelog.org/ | |
| 8 | 8 | ||
| 9 | 9 | - Completions for [`yash`](https://magicant.github.io/yash/) | |
| 10 | 10 | ||
| 11 | + | ### Fixed | |
| 12 | + | ||
| 13 | + | - Stop classifying complete kitty keyboard status replies (`CSI ? flags u`) as user input for leader selection | |
| 14 | + | ||
| 11 | 15 | ## v0.8.1 - 2026-09-05 | |
| 12 | 16 | ||
| 13 | 17 | ### Fixed |
+16,
-1
| ... | ... | @@ -706,7 +706,10 @@ pub fn isUserInput(payload: []const u8) bool { | |
| 706 | 706 | // kitty keyboard: CSI ... u or CSI ... ~ | |
| 707 | 707 | // legacy modified keys: CSI 27 ; ... ~ | |
| 708 | 708 | // arrow/function keys with modifiers: CSI 1 ; <mod> A-D | |
| 709 | - | if (csi.final == 'u' or csi.final == '~') return true; | |
| 709 | + | // CSI ? flags u is the terminal's reply to a kitty keyboard status | |
| 710 | + | // query, not a key press; skip it and keep scanning the payload | |
| 711 | + | const status_reply = csi.final == 'u' and csi.intermediates.len > 0 and csi.intermediates[0] == '?'; | |
| 712 | + | if (!status_reply and (csi.final == 'u' or csi.final == '~')) return true; | |
| 710 | 713 | // modified arrow keys (e.g., Ctrl+F sends CSI 1;5C in legacy mode) | |
| 711 | 714 | if (csi.final >= 'A' and csi.final <= 'D' and csi.params.len > 1) return true; | |
| 712 | 715 | // mouse events: CSI M (basic) or CSI < (SGR extended) - EXCLUDE these |
| ... | ... | @@ -2191,3 +2194,15 @@ test "stripAnsi: only escape sequences" { | |
| 2191 | 2194 | defer alloc.free(result); | |
| 2192 | 2195 | try testing.expectEqualStrings("", result); | |
| 2193 | 2196 | } | |
| 2197 | + | ||
| 2198 | + | test "isUserInput: kitty keyboard status reply is a terminal response" { | |
| 2199 | + | // CSI ? flags u answers the program's CSI ? u query; no key was pressed | |
| 2200 | + | try testing.expect(!isUserInput("\x1b[?1u")); | |
| 2201 | + | try testing.expect(!isUserInput("\x1b[?0u")); | |
| 2202 | + | try testing.expect(!isUserInput("\x1b[?31u")); | |
| 2203 | + | // a real key coalesced with the reply still counts | |
| 2204 | + | try testing.expect(isUserInput("\x1b[?1ua")); | |
| 2205 | + | try testing.expect(isUserInput("\x1b[?1u\r")); | |
| 2206 | + | try testing.expect(isUserInput("\x1b[?1u\x1b[97;1u")); | |
| 2207 | + | try testing.expect(!isUserInput("\x1b[?1u\x1b[97;1:3u")); | |
| 2208 | + | } |