fix(tui): filter key release events by default

Components must set wantsKeyRelease=true to receive release events.
Fixes double-processing of keys in editors when Kitty protocol flag 2 is enabled.
This commit is contained in:
Mario Zechner 2026-01-07 01:31:24 +01:00
parent 7508a51599
commit 41fe329cdd
2 changed files with 19 additions and 1 deletions

View file

@ -2,6 +2,14 @@
## [Unreleased]
### Added
- `Component.wantsKeyRelease` property to opt-in to key release events (default false)
### Fixed
- TUI now filters out key release events by default, preventing double-processing of keys in editors and other components
## [0.37.7] - 2026-01-07
### Fixed

View file

@ -5,7 +5,7 @@
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import { matchesKey } from "./keys.js";
import { isKeyRelease, matchesKey } from "./keys.js";
import type { Terminal } from "./terminal.js";
import { getCapabilities, setCellDimensions } from "./terminal-image.js";
import { visibleWidth } from "./utils.js";
@ -26,6 +26,12 @@ export interface Component {
*/
handleInput?(data: string): void;
/**
* If true, component receives key release events (Kitty protocol).
* Default is false - release events are filtered out.
*/
wantsKeyRelease?: boolean;
/**
* Invalidate any cached rendering state.
* Called when theme changes or when component needs to re-render from scratch.
@ -154,6 +160,10 @@ export class TUI extends Container {
// Pass input to focused component (including Ctrl+C)
// The focused component can decide how to handle Ctrl+C
if (this.focusedComponent?.handleInput) {
// Filter out key release events unless component opts in
if (isKeyRelease(data) && !this.focusedComponent.wantsKeyRelease) {
return;
}
this.focusedComponent.handleInput(data);
this.requestRender();
}