diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index e0761b1f1db..faddd4e7b06 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -544,6 +544,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Visibility this._register(this.groupsView.onDidVisibilityChange(e => this.onDidVisibilityChange(e))); + + // Focus + this._register(this.onDidFocus(() => this.onDidGainFocus())); } private onDidGroupModelChange(e: IGroupModelChangeEvent): void { @@ -578,6 +581,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { case GroupModelChangeKind.EDITOR_DIRTY: this.onDidChangeEditorDirty(e.editor); break; + case GroupModelChangeKind.EDITOR_TRANSIENT: + this.onDidChangeEditorTransient(e.editor); + break; case GroupModelChangeKind.EDITOR_LABEL: this.onDidChangeEditorLabel(e.editor); break; @@ -762,6 +768,17 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.titleControl.updateEditorDirty(editor); } + private onDidChangeEditorTransient(editor: EditorInput): void { + const transient = this.model.isTransient(editor); + + // Transient state overrides the `enablePreview` setting, + // so when an editor leaves the transient state, we have + // to ensure its preview state is also cleared. + if (!transient && !this.groupsView.partOptions.enablePreview) { + this.pinEditor(editor); + } + } + private onDidChangeEditorLabel(editor: EditorInput): void { // Forward to title control @@ -774,6 +791,18 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.editorPane.setVisible(visible); } + private onDidGainFocus(): void { + if (this.activeEditor) { + + // We aggressively clear the transient state of editors + // as soon as the group gains focus. This is to ensure + // that the transient state is not staying around when + // the user interacts with the editor. + + this.setTransient(this.activeEditor, false); + } + } + //#endregion //#region IEditorGroupView diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index e42c6116bc7..f1e25f4a355 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -1881,6 +1881,9 @@ suite('EditorGroupsService', () => { await group.openEditor(input2, { transient: true }); assert.strictEqual(group.isPinned(input2), false); + + group.setTransient(input2, false); + assert.strictEqual(group.isPinned(input2), true); }); ensureNoDisposablesAreLeakedInTestSuite(); diff --git a/src/vs/workbench/services/history/browser/historyService.ts b/src/vs/workbench/services/history/browser/historyService.ts index 3cef7fa9416..efaf3103c6c 100644 --- a/src/vs/workbench/services/history/browser/historyService.ts +++ b/src/vs/workbench/services/history/browser/historyService.ts @@ -35,6 +35,21 @@ import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecyc import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { mainWindow } from 'vs/base/browser/window'; +interface ISerializedEditorHistoryEntry { + readonly editor: Omit & { resource: string }; +} + +interface IRecentlyClosedEditor { + readonly editorId: string | undefined; + readonly editor: IUntypedEditorInput; + + readonly resource: URI | undefined; + readonly associatedResources: URI[]; + + readonly index: number; + readonly sticky: boolean; +} + export class HistoryService extends Disposable implements IHistoryService { declare readonly _serviceBrand: undefined; @@ -47,8 +62,6 @@ export class HistoryService extends Disposable implements IHistoryService { private readonly editorHelper = this.instantiationService.createInstance(EditorHelper); - - constructor( @IEditorService private readonly editorService: EditorServiceImpl, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @@ -59,7 +72,8 @@ export class HistoryService extends Disposable implements IHistoryService { @IWorkspacesService private readonly workspacesService: IWorkspacesService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @IContextKeyService private readonly contextKeyService: IContextKeyService + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @ILogService private readonly logService: ILogService ) { super(); @@ -176,6 +190,8 @@ export class HistoryService extends Disposable implements IHistoryService { // Handle editor change unless the editor is transient if (!activeEditorPane?.group.isTransient(activeEditorPane.input)) { this.handleActiveEditorChange(activeEditorGroup, activeEditorPane); + } else { + this.logService.trace(`[History]: ignoring transient editor change (editor: ${activeEditorPane.input?.resource?.toString()}})`); } // Listen to selection changes unless the editor is transient @@ -183,6 +199,8 @@ export class HistoryService extends Disposable implements IHistoryService { this.activeEditorListeners.add(activeEditorPane.onDidChangeSelection(e => { if (!activeEditorPane.group.isTransient(activeEditorPane.input)) { this.handleActiveEditorSelectionChangeEvent(activeEditorGroup, activeEditorPane, e); + } else { + this.logService.trace(`[History]: ignoring transient editor selection change (editor: ${activeEditorPane.input?.resource?.toString()}})`); } })); } @@ -2077,18 +2095,3 @@ class EditorHelper { } } } - -interface ISerializedEditorHistoryEntry { - editor: Omit & { resource: string }; -} - -interface IRecentlyClosedEditor { - editorId: string | undefined; - editor: IUntypedEditorInput; - - resource: URI | undefined; - associatedResources: URI[]; - - index: number; - sticky: boolean; -}