win32 input mode: Avoid scrolling to bottom on modifier only

Fixes #5612
This commit is contained in:
Daniel Imms
2026-01-31 22:05:33 -08:00
parent 87e0b9ab10
commit 7b417f4585
2 changed files with 46 additions and 3 deletions
+10 -3
View File
@@ -1156,9 +1156,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
this.textarea!.value = '';
}
const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);
this._onKey.fire({ key: result.key, domEvent: event });
this._showCursor();
this.coreService.triggerDataEvent(result.key, true);
this.coreService.triggerDataEvent(result.key, !wasModifierOnly);
// Cancel events when not in screen reader mode so events don't get bubbled up and handled by
// other listeners. When screen reader mode is enabled, we don't cancel them (unless ctrl or alt
@@ -1199,7 +1200,8 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
// Handle key release for Kitty keyboard protocol
const result = this._keyboardService.evaluateKeyUp(ev);
if (result?.key) {
this.coreService.triggerDataEvent(result.key, true);
const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);
this.coreService.triggerDataEvent(result.key, !wasModifierOnly);
}
this.updateCursorStyle(ev);
@@ -1410,5 +1412,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
function wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {
return ev.keyCode === 16 || // Shift
ev.keyCode === 17 || // Ctrl
ev.keyCode === 18; // Alt
ev.keyCode === 18 || // Alt
ev.keyCode === 91 || // Meta (Left)
ev.keyCode === 92 || // Meta (Right)
ev.keyCode === 93 || // Meta (Menu)
ev.keyCode === 224 || // Meta (Firefox)
ev.key === 'Meta';
}
+36
View File
@@ -401,6 +401,42 @@ describe('Terminal', () => {
});
});
describe('keyDown', () => {
it('should not scroll down on modifier-only input in win32 input mode', async () => {
term.options.vtExtensions = { win32InputMode: true };
term.coreService.decPrivateModes.win32InputMode = true;
(term as any).textarea = { value: '' };
await term.writeP('test\r\n'.repeat(term.rows * 3));
const startYDisp = term.buffer.ydisp;
term.scrollLines(-1);
const scrolledYDisp = term.buffer.ydisp;
assert.equal(scrolledYDisp, startYDisp - 1);
const evKeyDown = {
type: 'keydown',
key: 'Control',
keyCode: 17,
ctrlKey: true,
preventDefault: () => { },
stopPropagation: () => { }
} as KeyboardEvent;
const evKeyUp = {
type: 'keyup',
key: 'Control',
keyCode: 17,
preventDefault: () => { },
stopPropagation: () => { }
} as KeyboardEvent;
term.keyDown(evKeyDown);
assert.equal(term.buffer.ydisp, scrolledYDisp);
(term as any)._keyUp(evKeyUp);
assert.equal(term.buffer.ydisp, scrolledYDisp);
});
});
describe('scroll() function', () => {
describe('when scrollback > 0', () => {
it('should create a new line and scroll', () => {