Skip to content

Commit 7b417f4

Browse files
committed
win32 input mode: Avoid scrolling to bottom on modifier only
Fixes #5612
1 parent 87e0b9a commit 7b417f4

2 files changed

Lines changed: 46 additions & 3 deletions

File tree

src/browser/CoreBrowserTerminal.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,9 +1156,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
11561156
this.textarea!.value = '';
11571157
}
11581158

1159+
const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(event);
11591160
this._onKey.fire({ key: result.key, domEvent: event });
11601161
this._showCursor();
1161-
this.coreService.triggerDataEvent(result.key, true);
1162+
this.coreService.triggerDataEvent(result.key, !wasModifierOnly);
11621163

11631164
// Cancel events when not in screen reader mode so events don't get bubbled up and handled by
11641165
// 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 {
11991200
// Handle key release for Kitty keyboard protocol
12001201
const result = this._keyboardService.evaluateKeyUp(ev);
12011202
if (result?.key) {
1202-
this.coreService.triggerDataEvent(result.key, true);
1203+
const wasModifierOnly = this._keyboardService.useWin32InputMode && wasModifierKeyOnlyEvent(ev);
1204+
this.coreService.triggerDataEvent(result.key, !wasModifierOnly);
12031205
}
12041206

12051207
this.updateCursorStyle(ev);
@@ -1410,5 +1412,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
14101412
function wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {
14111413
return ev.keyCode === 16 || // Shift
14121414
ev.keyCode === 17 || // Ctrl
1413-
ev.keyCode === 18; // Alt
1415+
ev.keyCode === 18 || // Alt
1416+
ev.keyCode === 91 || // Meta (Left)
1417+
ev.keyCode === 92 || // Meta (Right)
1418+
ev.keyCode === 93 || // Meta (Menu)
1419+
ev.keyCode === 224 || // Meta (Firefox)
1420+
ev.key === 'Meta';
14141421
}

src/browser/Terminal.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,42 @@ describe('Terminal', () => {
401401
});
402402
});
403403

404+
describe('keyDown', () => {
405+
it('should not scroll down on modifier-only input in win32 input mode', async () => {
406+
term.options.vtExtensions = { win32InputMode: true };
407+
term.coreService.decPrivateModes.win32InputMode = true;
408+
(term as any).textarea = { value: '' };
409+
410+
await term.writeP('test\r\n'.repeat(term.rows * 3));
411+
const startYDisp = term.buffer.ydisp;
412+
term.scrollLines(-1);
413+
const scrolledYDisp = term.buffer.ydisp;
414+
assert.equal(scrolledYDisp, startYDisp - 1);
415+
416+
const evKeyDown = {
417+
type: 'keydown',
418+
key: 'Control',
419+
keyCode: 17,
420+
ctrlKey: true,
421+
preventDefault: () => { },
422+
stopPropagation: () => { }
423+
} as KeyboardEvent;
424+
425+
const evKeyUp = {
426+
type: 'keyup',
427+
key: 'Control',
428+
keyCode: 17,
429+
preventDefault: () => { },
430+
stopPropagation: () => { }
431+
} as KeyboardEvent;
432+
433+
term.keyDown(evKeyDown);
434+
assert.equal(term.buffer.ydisp, scrolledYDisp);
435+
(term as any)._keyUp(evKeyUp);
436+
assert.equal(term.buffer.ydisp, scrolledYDisp);
437+
});
438+
});
439+
404440
describe('scroll() function', () => {
405441
describe('when scrollback > 0', () => {
406442
it('should create a new line and scroll', () => {

0 commit comments

Comments
 (0)