From 986933afab1dab8bcbbcd49d02f4e29fb396875f Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 13 Jan 2017 11:59:19 +0100 Subject: [PATCH] Fixes Microsoft/monaco-editor#254: The view should assume it is focused only if focusing the textarea succeeded --- .../browser/controller/keyboardHandler.ts | 2 +- src/vs/editor/browser/view/viewImpl.ts | 4 ++- .../common/controller/textAreaHandler.ts | 26 +++++++++---------- .../test/browser/controller/imeTester.ts | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/browser/controller/keyboardHandler.ts b/src/vs/editor/browser/controller/keyboardHandler.ts index 070e69cb887..89ceea1c90a 100644 --- a/src/vs/editor/browser/controller/keyboardHandler.ts +++ b/src/vs/editor/browser/controller/keyboardHandler.ts @@ -157,7 +157,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable { } public focusTextArea(): void { - this.textAreaHandler.writePlaceholderAndSelectTextAreaSync(); + this.textAreaHandler.focusTextArea(); } public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean { diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 2766ef2f051..cd57262869d 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -673,7 +673,9 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp this.keyboardHandler.focusTextArea(); // IE does not trigger the focus event immediately, so we must help it a little bit - this._setHasFocus(true); + if (document.activeElement === this.textArea) { + this._setHasFocus(true); + } } public isFocused(): boolean { diff --git a/src/vs/editor/common/controller/textAreaHandler.ts b/src/vs/editor/common/controller/textAreaHandler.ts index 1015da7d3fb..a385e1c96a8 100644 --- a/src/vs/editor/common/controller/textAreaHandler.ts +++ b/src/vs/editor/common/controller/textAreaHandler.ts @@ -118,7 +118,7 @@ export class TextAreaHandler extends Disposable { // In IE we cannot set .value when handling 'compositionstart' because the entire composition will get canceled. if (!this.Browser.isEdgeOrIE) { - this.setTextAreaState('compositionstart', this.textAreaState.toEmpty()); + this.setTextAreaState('compositionstart', this.textAreaState.toEmpty(), false); } this._onCompositionStart.fire({ @@ -200,13 +200,13 @@ export class TextAreaHandler extends Disposable { } else { if (this.textArea.getSelectionStart() !== this.textArea.getSelectionEnd()) { // Clean up the textarea, to get a clean paste - this.setTextAreaState('paste', this.textAreaState.toEmpty()); + this.setTextAreaState('paste', this.textAreaState.toEmpty(), false); } this._nextCommand = ReadFromTextArea.Paste; } })); - this._writePlaceholderAndSelectTextArea('ctor'); + this._writePlaceholderAndSelectTextArea('ctor', false); } public dispose(): void { @@ -227,24 +227,24 @@ export class TextAreaHandler extends Disposable { } this.hasFocus = isFocused; if (this.hasFocus) { - this._writePlaceholderAndSelectTextArea('focusgain'); + this._writePlaceholderAndSelectTextArea('focusgain', false); } } public setCursorSelections(primary: Range, secondary: Range[]): void { this.selection = primary; this.selections = [primary].concat(secondary); - this._writePlaceholderAndSelectTextArea('selection changed'); + this._writePlaceholderAndSelectTextArea('selection changed', false); } // --- end event handlers - private setTextAreaState(reason: string, textAreaState: TextAreaState): void { + private setTextAreaState(reason: string, textAreaState: TextAreaState, forceFocus: boolean): void { if (!this.hasFocus) { textAreaState = textAreaState.resetSelection(); } - textAreaState.applyToTextArea(reason, this.textArea, this.hasFocus); + textAreaState.applyToTextArea(reason, this.textArea, this.hasFocus || forceFocus); this.textAreaState = textAreaState; } @@ -281,18 +281,18 @@ export class TextAreaHandler extends Disposable { }); } - public writePlaceholderAndSelectTextAreaSync(): void { - this._writePlaceholderAndSelectTextArea('focusTextArea'); + public focusTextArea(): void { + this._writePlaceholderAndSelectTextArea('focusTextArea', true); } - private _writePlaceholderAndSelectTextArea(reason: string): void { + private _writePlaceholderAndSelectTextArea(reason: string, forceFocus: boolean): void { if (!this.textareaIsShownAtCursor) { // Do not write to the textarea if it is visible. if (this.Browser.isIPad) { // Do not place anything in the textarea for the iPad - this.setTextAreaState(reason, this.textAreaState.toEmpty()); + this.setTextAreaState(reason, this.textAreaState.toEmpty(), forceFocus); } else { - this.setTextAreaState(reason, this.textAreaState.fromEditorSelection(this.model, this.selection)); + this.setTextAreaState(reason, this.textAreaState.fromEditorSelection(this.model, this.selection), forceFocus); } } } @@ -304,7 +304,7 @@ export class TextAreaHandler extends Disposable { if (e.canUseTextData()) { e.setTextData(whatToCopy); } else { - this.setTextAreaState('copy or cut', this.textAreaState.fromText(whatToCopy)); + this.setTextAreaState('copy or cut', this.textAreaState.fromText(whatToCopy), false); } if (this.Browser.enableEmptySelectionClipboard) { diff --git a/src/vs/editor/test/browser/controller/imeTester.ts b/src/vs/editor/test/browser/controller/imeTester.ts index 906f40bf5d4..2abbab025a6 100644 --- a/src/vs/editor/test/browser/controller/imeTester.ts +++ b/src/vs/editor/test/browser/controller/imeTester.ts @@ -124,7 +124,7 @@ function doCreateTest(strategy: TextAreaStrategy, description: string, inputStr: cursorOffset = off; cursorLength = len; handler.setCursorSelections(new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength), []); - handler.writePlaceholderAndSelectTextAreaSync(); + handler.focusTextArea(); }; let updateModelAndPosition = (text: string, off: number, len: number) => {