Skip to content

Commit

Permalink
[monaco] fix #7902: only focus the editor if it's revealed
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed May 27, 2020
1 parent f56cb7a commit 99a7aa3
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/editor/src/browser/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ export interface TextEditor extends Disposable, TextEditorSelection, Navigatable
selection: Range;
readonly onSelectionChanged: Event<Range>;

/**
* The text editor should be revealed,
* otherwise it won't receive the focus.
*/
focus(): void;
blur(): void;
isFocused(): boolean;
Expand Down
4 changes: 4 additions & 0 deletions packages/monaco/src/browser/monaco-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ export class MonacoEditorCommandHandlers implements CommandContribution {
}
const handler: CommandHandler = {
execute: (...args) => {
/*
* We check monaco focused code editor first since they can contain inline like the debug console and embedded editors like in the peek reference.
* If there is not such then we check last focused editor tracked by us.
*/
const editor = codeEditorService.getFocusedCodeEditor() || codeEditorService.getActiveCodeEditor();
if (editorActions.has(id)) {
const action = editor && editor.getAction(id);
Expand Down
15 changes: 14 additions & 1 deletion packages/monaco/src/browser/monaco-editor-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,31 @@ export class MonacoEditorProvider {
const control = editor.getControl();
const quickOpenController = control._contributions['editor.controller.quickOpenController'];
const originalRun = quickOpenController.run;
const toDispose = new DisposableCollection();
quickOpenController.dispose = () => toDispose.dispose();
quickOpenController.run = options => {
const toDisposeOnClose = toDispose.push(Disposable.create(() => this.quickOpenService.hide()));

const selection = control.getSelection();
this.quickOpenService.internalOpen({
...options,
onClose: canceled => {
toDisposeOnClose.dispose();

quickOpenController.clearDecorations();

// Restore selection if canceled
if (canceled && selection) {
control.setSelection(selection);
control.revealRangeInCenterIfOutsideViewport(selection);
}
editor.focus();

// Return focus to the editor if
// - focus is back on the <body> element because no other focusable element was clicked
// - a command was picked from the picker which indicates the editor should get focused
if (document.activeElement === document.body || !canceled) {
editor.focus();
}
}
});
};
Expand Down
12 changes: 11 additions & 1 deletion packages/monaco/src/browser/monaco-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,17 @@ export class MonacoEditor extends MonacoEditorServices implements TextEditor {
}

focus(): void {
this.editor.focus();
/**
* `this.editor.focus` forcefully changes the focus editor state,
* regardless whether the textarea actually received the focus.
* It could lead to issues like https://github.com/eclipse-theia/theia/issues/7902
* Instead we focus the underlying textarea.
*/
const node = this.editor.getDomNode();
if (node) {
const textarea = node.querySelector('textarea') as HTMLElement;
textarea.focus();
}
}

blur(): void {
Expand Down
4 changes: 2 additions & 2 deletions packages/monaco/src/typings/monaco/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1074,10 +1074,10 @@ declare module monaco.quickOpen {
// https://github.com/theia-ide/vscode/blob/standalone/0.19.x/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts#L25
export interface QuickOpenController extends IDisposable {
static readonly ID: string;
dispose(): void;
run(opts: IQuickOpenControllerOpts): void;

// https://github.com/theia-ide/vscode/blob/standalone/0.19.x/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts#L168-L169
decorateLine(range: Range, editor: monaco.editor.ICodeEditor): void;
// https://github.com/theia-ide/vscode/blob/standalone/0.19.x/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts#L169
clearDecorations(): void;
}
}
Expand Down

0 comments on commit 99a7aa3

Please sign in to comment.