Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/browser/CoreBrowserTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
const shouldIgnoreComposition = this.browser.isMac && this.options.macOptionIsMeta && event.altKey;

if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {
// Reset _keyDownSeen when composition handles the keydown (e.g. keyCode 229 on
// Android). The keydown did not produce any data, so the subsequent input event
// must be allowed through to _inputEvent() to forward the IME text.
this._keyDownSeen = false;
if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {
this.scrollToBottom(true);
}
Expand Down Expand Up @@ -1037,6 +1041,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
// The key was handled so clear the dead key state, otherwise certain keystrokes like arrow
// keys could be ignored
this._unprocessedDeadKey = false;
// Cancel any pending composition send when the input event handles the committed text.
// This prevents double-sending when _finalizeComposition's setTimeout fires.
this._compositionHelper?.cancelPendingComposition();

const text = ev.data;
this.coreService.triggerDataEvent(text, true);
Expand Down
3 changes: 3 additions & 0 deletions src/browser/TestUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ export class MockCompositionHelper implements ICompositionHelper {
public keydown(ev: KeyboardEvent): boolean {
return true;
}
public cancelPendingComposition(): void {
// no-op
}
}

export class MockCoreBrowserService implements ICoreBrowserService {
Expand Down
1 change: 1 addition & 0 deletions src/browser/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface ICompositionHelper {
compositionend(): void;
updateCompositionElements(dontRecurse?: boolean): void;
keydown(ev: KeyboardEvent): boolean;
cancelPendingComposition(): void;
}

export interface IBrowser {
Expand Down
9 changes: 9 additions & 0 deletions src/browser/input/CompositionHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ export class CompositionHelper {
}
}

/**
* Cancel any pending composition send. This is called from _inputEvent when the
* IME committed text is handled via the input event, preventing a double-send from
* the _finalizeComposition timeout.
*/
public cancelPendingComposition(): void {
this._isSendingComposition = false;
}

/**
* Apply any changes made to the textarea after the current event chain is allowed to complete.
* This should be called when not currently composing but a keydown event with the "composition
Expand Down