diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index a2a26d6f7ad..4573e19ba9d 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -236,6 +236,12 @@ export interface IInternalEditorOpenOptions extends IInternalEditorTitleControlO * When set to `true`, pass DOM focus into the tab control. */ readonly focusTabControl?: boolean; + + /** + * When set to `true`, will not attempt to move the window to + * the top that the editor opens in. + */ + readonly preserveWindowOrder?: boolean; } export interface IInternalEditorCloseOptions extends IInternalEditorTitleControlOptions { diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index b34b28c1277..9a0b3c4eb67 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1073,7 +1073,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { let openEditorPromise: Promise; if (context.active) { openEditorPromise = (async () => { - const { pane, changed, cancelled, error } = await this.editorPane.openEditor(editor, options, { newInGroup: context.isNew }); + const { pane, changed, cancelled, error } = await this.editorPane.openEditor(editor, options, internalOptions, { newInGroup: context.isNew }); // Return early if the operation was cancelled by another operation if (cancelled) { @@ -1415,7 +1415,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView { ignoreError: internalOptions?.fromError }; - this.doOpenEditor(nextActiveEditor, options); + const internalEditorOpenOptions: IInternalEditorOpenOptions = { + // When closing an editor, we reveal the next one in the group. + // However, this can be a result of moving an editor to another + // window so we explicitly disable window reordering in this case. + preserveWindowOrder: true + }; + + this.doOpenEditor(nextActiveEditor, options, internalEditorOpenOptions); } // Otherwise we are empty, so clear from editor control and send event diff --git a/src/vs/workbench/browser/parts/editor/editorPanes.ts b/src/vs/workbench/browser/parts/editor/editorPanes.ts index 6bc385910a1..4f4c65d6d0b 100644 --- a/src/vs/workbench/browser/parts/editor/editorPanes.ts +++ b/src/vs/workbench/browser/parts/editor/editorPanes.ts @@ -17,7 +17,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IEditorProgressService, LongRunningOperation } from 'vs/platform/progress/common/progress'; -import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; +import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS, IInternalEditorOpenOptions } from 'vs/workbench/browser/parts/editor/editor'; import { assertIsDefined } from 'vs/base/common/types'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { ErrorPlaceholderEditor, IErrorEditorPlaceholderOptions, WorkspaceTrustRequiredPlaceholderEditor } from 'vs/workbench/browser/parts/editor/editorPlaceholder'; @@ -126,7 +126,7 @@ export class EditorPanes extends Disposable { } } - async openEditor(editor: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise { + async openEditor(editor: EditorInput, options: IEditorOptions | undefined, internalOptions: IInternalEditorOpenOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise { try { // Assert the `EditorInputCapabilities.AuxWindowUnsupported` condition @@ -138,12 +138,12 @@ export class EditorPanes extends Disposable { return this.groupView.closeEditor(editor); } }) - ], { forceMessage: true, forceSeverity: Severity.Warning }), editor, options, context); + ], { forceMessage: true, forceSeverity: Severity.Warning }), editor, options, internalOptions, context); } // Open editor normally else { - return await this.doOpenEditor(this.getEditorPaneDescriptor(editor), editor, options, context); + return await this.doOpenEditor(this.getEditorPaneDescriptor(editor), editor, options, internalOptions, context); } } catch (error) { @@ -159,11 +159,11 @@ export class EditorPanes extends Disposable { // For that reason we have place holder editors that can convey a // message with actions the user can click on. - return this.doShowError(error, editor, options, context); + return this.doShowError(error, editor, options, internalOptions, context); } } - private async doShowError(error: Error, editor: EditorInput, options?: IEditorOptions, context?: IEditorOpenContext): Promise { + private async doShowError(error: Error, editor: EditorInput, options: IEditorOptions | undefined, internalOptions: IInternalEditorOpenOptions | undefined, context?: IEditorOpenContext): Promise { // Always log the error to figure out what is going on this.logService.error(error); @@ -186,7 +186,7 @@ export class EditorPanes extends Disposable { } return { - ...(await this.doOpenEditor(ErrorPlaceholderEditor.DESCRIPTOR, editor, editorPlaceholderOptions, context)), + ...(await this.doOpenEditor(ErrorPlaceholderEditor.DESCRIPTOR, editor, editorPlaceholderOptions, internalOptions, context)), error }; } @@ -258,7 +258,7 @@ export class EditorPanes extends Disposable { return errorHandled; } - private async doOpenEditor(descriptor: IEditorPaneDescriptor, editor: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise { + private async doOpenEditor(descriptor: IEditorPaneDescriptor, editor: EditorInput, options: IEditorOptions | undefined, internalOptions: IInternalEditorOpenOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise { // Editor pane const pane = this.doShowEditorPane(descriptor); @@ -270,12 +270,13 @@ export class EditorPanes extends Disposable { const { changed, cancelled } = await this.doSetInput(pane, editor, options, context); // Make sure to pass focus to the pane or otherwise - // make sure that the pane window is visible. + // make sure that the pane window is visible unless + // this has been explicitly disabled. if (!cancelled) { const focus = !options || !options.preserveFocus; if (focus && this.shouldRestoreFocus(activeElement)) { pane.focus(); - } else { + } else if (!internalOptions?.preserveWindowOrder) { const paneWindow = getWindow(pane.getContainer()); if (paneWindow !== getActiveWindow()) { this.hostService.moveTop(paneWindow);