From 50e90ddf8a54b0a4f6577705b5a9e235d84ae6a4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 12 May 2026 13:19:15 +0800 Subject: [PATCH] Fix keys getting swallowed when enabling only "Report event types" Per kovidgoyal/kitty#9999, enabling "Report event types" without "Disambiguate escape codes" doesn't really make sense, and terminals may choose whatever behavior they think makes sense. However, keys shouldn't get swallowed (which, after #5791, happens when the !useCsiU branch cannot handle the event), so instead make "Report event types" imply "Disambiguate escape codes". --- src/common/input/KittyKeyboard.test.ts | 23 ++++++++++++++++++++++- src/common/input/KittyKeyboard.ts | 5 ++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/common/input/KittyKeyboard.test.ts b/src/common/input/KittyKeyboard.test.ts index 7646c052b..2a832d75f 100644 --- a/src/common/input/KittyKeyboard.test.ts +++ b/src/common/input/KittyKeyboard.test.ts @@ -478,7 +478,7 @@ describe('KittyKeyboard', () => { assert.strictEqual(result.key, '\x7f'); }); - it('press event explicit :1 when modifiers present', () => { + it('press event when modifiers present', () => { const result = kitty.evaluate(createEvent({ key: 'a', ctrlKey: true }), flags, KittyKeyboardEventType.PRESS); assert.strictEqual(result.key, '\x1b[97;5u'); }); @@ -554,6 +554,27 @@ describe('KittyKeyboard', () => { }); }); + // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense and + // isn't specified in the spec, but press and repeat events shouldn't get swallowed. + describe('REPORT_EVENT_TYPES flag without DISAMBIGUATE_ESCAPE_CODES', () => { + const flags = KittyKeyboardFlags.REPORT_EVENT_TYPES; + + it('press event is not swallowed when modifiers present', () => { + const result = kitty.evaluate(createEvent({ key: 'a', ctrlKey: true }), flags, KittyKeyboardEventType.PRESS); + assert.strictEqual(result.key, '\x1b[97;5u'); + }); + + it('repeat event is not swallowed when modifiers present', () => { + const result = kitty.evaluate(createEvent({ key: 'a', ctrlKey: true }), flags, KittyKeyboardEventType.REPEAT); + assert.strictEqual(result.key, '\x1b[97;5:2u'); + }); + + it('release event is reported as CSI u sequence', () => { + const result = kitty.evaluate(createEvent({ key: 'a', ctrlKey: true }), flags, KittyKeyboardEventType.RELEASE); + assert.strictEqual(result.key, '\x1b[97;5:3u'); + }); + }); + describe('modifier-only reporting', () => { const flags = KittyKeyboardFlags.REPORT_EVENT_TYPES; diff --git a/src/common/input/KittyKeyboard.ts b/src/common/input/KittyKeyboard.ts index f35cfebd5..ff57b4f89 100644 --- a/src/common/input/KittyKeyboard.ts +++ b/src/common/input/KittyKeyboard.ts @@ -485,7 +485,10 @@ export class KittyKeyboard { const useCsiU = !!( flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES || (reportEventTypes && eventType === KittyKeyboardEventType.RELEASE) || - (flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES && + // Enabling REPORT_EVENT_TYPES without DISAMBIGUATE_ESCAPE_CODES doesn't really make sense, so + // just make REPORT_EVENT_TYPES imply DISAMBIGUATE_ESCAPE_CODES here for simplicity. + // See: https://github.com/kovidgoyal/kitty/issues/9999 + ((flags & KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES || reportEventTypes) && ( // Per spec, Enter/Tab/Backspace "still generate the same bytes as in legacy mode" and // consider space to be a text-generating key, so these skip the isFunc fast-path and only