Skip to content

Commit 4316263

Browse files
authored
Merge pull request #5790 from xtermjs/anthonykim1/closeKittyKeyboardGap
Do not report lock key presses without REPORT_ALL_KEYS in Kitty keyboard
2 parents ad730f2 + 4a35a48 commit 4316263

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/common/input/KittyKeyboard.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,25 @@ describe('KittyKeyboard', () => {
506506
const result = kitty.evaluate(createEvent({ key: 'Shift', code: 'ShiftLeft', shiftKey: false }), flags, KittyKeyboardEventType.RELEASE);
507507
assert.strictEqual(result.key, undefined);
508508
});
509+
510+
it('does not report CapsLock press without REPORT_ALL_KEYS_AS_ESCAPE_CODES', () => {
511+
assert.strictEqual(kitty.evaluate(createEvent({ key: 'CapsLock', code: 'CapsLock' }), KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES).key, undefined);
512+
assert.strictEqual(kitty.evaluate(createEvent({ key: 'CapsLock', code: 'CapsLock' }), KittyKeyboardFlags.REPORT_EVENT_TYPES).key, undefined);
513+
assert.strictEqual(kitty.evaluate(createEvent({ key: 'CapsLock', code: 'CapsLock' }), KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES | KittyKeyboardFlags.REPORT_EVENT_TYPES).key, undefined);
514+
});
515+
516+
it('does not report NumLock press without REPORT_ALL_KEYS_AS_ESCAPE_CODES', () => {
517+
assert.strictEqual(kitty.evaluate(createEvent({ key: 'NumLock', code: 'NumLock' }), KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES).key, undefined);
518+
});
519+
520+
it('does not report ScrollLock press without REPORT_ALL_KEYS_AS_ESCAPE_CODES', () => {
521+
assert.strictEqual(kitty.evaluate(createEvent({ key: 'ScrollLock', code: 'ScrollLock' }), KittyKeyboardFlags.DISAMBIGUATE_ESCAPE_CODES).key, undefined);
522+
});
523+
524+
it('does not report CapsLock release without REPORT_ALL_KEYS_AS_ESCAPE_CODES', () => {
525+
const result = kitty.evaluate(createEvent({ key: 'CapsLock', code: 'CapsLock' }), flags, KittyKeyboardEventType.RELEASE);
526+
assert.strictEqual(result.key, undefined);
527+
});
509528
});
510529

511530
describe('REPORT_ALL_KEYS_AS_ESCAPE_CODES flag', () => {

src/common/input/KittyKeyboard.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,19 @@ export class KittyKeyboard {
265265
return ev.key === 'Shift' || ev.key === 'Control' || ev.key === 'Alt' || ev.key === 'Meta';
266266
}
267267

268+
/**
269+
* Check if a key is a lock key (CapsLock/NumLock/ScrollLock).
270+
*
271+
* Kitty's reference implementation classifies these as modifier keys for the
272+
* purpose of suppressing press events (kitty/keys.c `is_modifier_key()`
273+
* includes `GLFW_FKEY_CAPS_LOCK`, `GLFW_FKEY_SCROLL_LOCK`, `GLFW_FKEY_NUM_LOCK`),
274+
* and its test suite asserts that a CapsLock press with no protocol flags
275+
* produces empty output.
276+
*/
277+
private _isLockKey(ev: IKeyboardEvent): boolean {
278+
return ev.key === 'CapsLock' || ev.key === 'NumLock' || ev.key === 'ScrollLock';
279+
}
280+
268281
/**
269282
* Build CSI letter sequence for arrow keys, Home, End.
270283
* Format: CSI [1;mod] letter
@@ -422,6 +435,14 @@ export class KittyKeyboard {
422435
return result;
423436
}
424437

438+
// Spec § "Report all keys as escape codes": "Additionally, with this mode,
439+
// events for pressing modifier keys are reported." — i.e. *without* this
440+
// mode, modifier-key press events are suppressed. Kitty's is_modifier_key()
441+
// treats CapsLock/NumLock/ScrollLock as modifier keys for this rule.
442+
if (this._isLockKey(ev) && !(flags & KittyKeyboardFlags.REPORT_ALL_KEYS_AS_ESCAPE_CODES)) {
443+
return result;
444+
}
445+
425446
const csiLetter = this._csiLetterKeys[ev.key];
426447
if (csiLetter) {
427448
result.key = this._buildCsiLetterSequence(csiLetter, modifiers, eventType, reportEventTypes);

0 commit comments

Comments
 (0)