mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 05:02:07 +00:00
fix(tui): ignore unsupported Kitty CSI-u modifiers closes #1807
This commit is contained in:
parent
8e157412a6
commit
49749407fa
5 changed files with 25 additions and 1 deletions
|
|
@ -5,6 +5,7 @@
|
|||
### Fixed
|
||||
|
||||
- Fixed TUI width calculation for regional indicator symbols (e.g. partial flag sequences like `🇨` during streaming) to prevent wrap drift and stale character artifacts in differential rendering.
|
||||
- Fixed Kitty CSI-u handling to ignore unsupported modifiers so modifier-only events do not insert stray printable characters ([#1807](https://github.com/badlogic/pi-mono/issues/1807))
|
||||
|
||||
## [0.55.4] - 2026-03-02
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ const KITTY_CSI_U_REGEX = /^\x1b\[(\d+)(?::(\d*))?(?::(\d+))?(?:;(\d+))?(?::(\d+
|
|||
const KITTY_MOD_SHIFT = 1;
|
||||
const KITTY_MOD_ALT = 2;
|
||||
const KITTY_MOD_CTRL = 4;
|
||||
const KITTY_LOCK_MASK = 64 + 128; // Caps Lock + Num Lock
|
||||
const KITTY_ALLOWED_MODIFIERS = KITTY_MOD_SHIFT | KITTY_LOCK_MASK;
|
||||
|
||||
// Decode a printable CSI-u sequence, preferring the shifted key when present.
|
||||
function decodeKittyPrintable(data: string): string | undefined {
|
||||
|
|
@ -111,7 +113,10 @@ function decodeKittyPrintable(data: string): string | undefined {
|
|||
// Modifiers are 1-indexed in CSI-u; normalize to our bitmask.
|
||||
const modifier = Number.isFinite(modValue) ? modValue - 1 : 0;
|
||||
|
||||
// Ignore CSI-u sequences used for Alt/Ctrl shortcuts.
|
||||
// Only accept printable CSI-u input for plain or Shift-modified text keys.
|
||||
// Reject unsupported modifier bits (e.g. Super/Meta) to avoid inserting
|
||||
// characters from modifier-only terminal events.
|
||||
if ((modifier & ~KITTY_ALLOWED_MODIFIERS) !== 0) return undefined;
|
||||
if (modifier & (KITTY_MOD_ALT | KITTY_MOD_CTRL)) return undefined;
|
||||
|
||||
// Prefer the shifted keycode when Shift is held.
|
||||
|
|
|
|||
|
|
@ -1048,6 +1048,8 @@ export function parseKey(data: string): string | undefined {
|
|||
const { codepoint, baseLayoutKey, modifier } = kitty;
|
||||
const mods: string[] = [];
|
||||
const effectiveMod = modifier & ~LOCK_MASK;
|
||||
const supportedModifierMask = MODIFIERS.shift | MODIFIERS.ctrl | MODIFIERS.alt;
|
||||
if ((effectiveMod & ~supportedModifierMask) !== 0) return undefined;
|
||||
if (effectiveMod & MODIFIERS.shift) mods.push("shift");
|
||||
if (effectiveMod & MODIFIERS.ctrl) mods.push("ctrl");
|
||||
if (effectiveMod & MODIFIERS.alt) mods.push("alt");
|
||||
|
|
|
|||
|
|
@ -361,6 +361,16 @@ describe("Editor component", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Kitty CSI-u handling", () => {
|
||||
it("ignores printable CSI-u sequences with unsupported modifiers", () => {
|
||||
const editor = new Editor(createTestTUI(), defaultEditorTheme);
|
||||
|
||||
editor.handleInput("\x1b[99;9u");
|
||||
|
||||
assert.strictEqual(editor.getText(), "");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unicode text editing behavior", () => {
|
||||
it("inserts mixed ASCII, umlauts, and emojis as literal text", () => {
|
||||
const editor = new Editor(createTestTUI(), defaultEditorTheme);
|
||||
|
|
|
|||
|
|
@ -294,6 +294,12 @@ describe("parseKey", () => {
|
|||
assert.strictEqual(parseKey(latinCtrlC), "ctrl+c");
|
||||
setKittyProtocolActive(false);
|
||||
});
|
||||
|
||||
it("should ignore Kitty CSI-u with unsupported modifiers", () => {
|
||||
setKittyProtocolActive(true);
|
||||
assert.strictEqual(parseKey("\x1b[99;9u"), undefined);
|
||||
setKittyProtocolActive(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Legacy key parsing", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue