diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 017633b4..1e5eb569 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -1099,14 +1099,17 @@ export class Terminal extends CoreTerminal implements ITerminal { return false; } - if (!this._compositionHelper!.keydown(event)) { + // Ignore composing with Alt key on Mac when macOptionIsMeta is enabled + const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey; + + if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) { if (this.buffer.ybase !== this.buffer.ydisp) { this._bufferService.scrollToBottom(); } return false; } - if (event.key === 'Dead' || event.key === 'AltGraph') { + if (!shouldIgnoreComposition && (event.key === 'Dead' || event.key === 'AltGraph')) { this._unprocessedDeadKey = true; } diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index c48b23ea..1ff8f6df 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -50,6 +50,7 @@ export interface IKeyboardEvent { keyCode: number; key: string; type: string; + code: string; } export interface IScrollEvent { diff --git a/src/common/input/Keyboard.test.ts b/src/common/input/Keyboard.test.ts index 64886e38..68fbaac1 100644 --- a/src/common/input/Keyboard.test.ts +++ b/src/common/input/Keyboard.test.ts @@ -13,6 +13,7 @@ function testEvaluateKeyboardEvent(partialEvent: { shiftKey?: boolean; metaKey?: boolean; keyCode?: number; + code?: string; key?: string; type?: string; }, partialOptions: { @@ -26,6 +27,7 @@ function testEvaluateKeyboardEvent(partialEvent: { shiftKey: partialEvent.shiftKey || false, metaKey: partialEvent.metaKey || false, keyCode: partialEvent.keyCode !== undefined ? partialEvent.keyCode : 0, + code: partialEvent.code || '', key: partialEvent.key || '', type: partialEvent.type || '' }; diff --git a/src/common/input/Keyboard.ts b/src/common/input/Keyboard.ts index 850a5c71..0481ad99 100644 --- a/src/common/input/Keyboard.ts +++ b/src/common/input/Keyboard.ts @@ -358,7 +358,23 @@ export function evaluateKeyboardEvent( result.key = C0.ESC + key; } else if (ev.keyCode >= 65 && ev.keyCode <= 90) { const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32; - result.key = C0.ESC + String.fromCharCode(keyCode); + let keyString = String.fromCharCode(keyCode); + if (ev.shiftKey) { + keyString = keyString.toUpperCase(); + } + result.key = C0.ESC + keyString; + } else if (ev.key === 'Dead' && ev.code.startsWith('Key')) { + // Reference: https://github.com/xtermjs/xterm.js/issues/3725 + // Alt will produce a "dead key" (initate composition) with some + // of the letters in US layout (e.g. N/E/U). + // It's safe to match against Key* since no other `code` values begin with "Key". + // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values#code_values_on_mac + let keyString = ev.code.slice(3, 4); + if (!ev.shiftKey) { + keyString = keyString.toLowerCase(); + } + result.key = C0.ESC + keyString; + result.cancel = true; } } else if (isMac && !ev.altKey && !ev.ctrlKey && !ev.shiftKey && ev.metaKey) { if (ev.keyCode === 65) { // cmd + a