Skip to content

Commit a825aaa

Browse files
committed
support auto save on focus lost for all editors (#84672)
1 parent d9c4923 commit a825aaa

File tree

5 files changed

+31
-35
lines changed

5 files changed

+31
-35
lines changed

src/vs/workbench/browser/composite.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ import { find } from 'vs/base/common/arrays';
3131
*/
3232
export abstract class Composite extends Component implements IComposite {
3333

34-
private readonly _onTitleAreaUpdate: Emitter<void> = this._register(new Emitter<void>());
35-
readonly onTitleAreaUpdate: Event<void> = this._onTitleAreaUpdate.event;
34+
private readonly _onTitleAreaUpdate = this._register(new Emitter<void>());
35+
readonly onTitleAreaUpdate = this._onTitleAreaUpdate.event;
3636

37-
private readonly _onDidChangeVisibility: Emitter<boolean> = this._register(new Emitter<boolean>());
38-
readonly onDidChangeVisibility: Event<boolean> = this._onDidChangeVisibility.event;
37+
private readonly _onDidChangeVisibility = this._register(new Emitter<boolean>());
38+
readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
3939

4040
private _onDidFocus: Emitter<void> | undefined;
4141
get onDidFocus(): Event<void> {
@@ -250,11 +250,11 @@ export abstract class CompositeDescriptor<T extends Composite> {
250250

251251
export abstract class CompositeRegistry<T extends Composite> extends Disposable {
252252

253-
private readonly _onDidRegister: Emitter<CompositeDescriptor<T>> = this._register(new Emitter<CompositeDescriptor<T>>());
254-
get onDidRegister(): Event<CompositeDescriptor<T>> { return this._onDidRegister.event; }
253+
private readonly _onDidRegister = this._register(new Emitter<CompositeDescriptor<T>>());
254+
readonly onDidRegister = this._onDidRegister.event;
255255

256-
private readonly _onDidDeregister: Emitter<CompositeDescriptor<T>> = this._register(new Emitter<CompositeDescriptor<T>>());
257-
get onDidDeregister(): Event<CompositeDescriptor<T>> { return this._onDidDeregister.event; }
256+
private readonly _onDidDeregister = this._register(new Emitter<CompositeDescriptor<T>>());
257+
readonly onDidDeregister = this._onDidDeregister.event;
258258

259259
private composites: CompositeDescriptor<T>[] = [];
260260

src/vs/workbench/browser/parts/editor/editorAutoSave.ts

+6-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/
99
import { IHostService } from 'vs/workbench/services/host/browser/host';
1010
import { SaveReason, IEditorIdentifier, IEditorInput, GroupIdentifier } from 'vs/workbench/common/editor';
1111
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
12-
import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
1312
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
1413
import { withNullAsUndefined } from 'vs/base/common/types';
1514

@@ -57,19 +56,11 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
5756
this.lastActiveEditorControlDisposable.clear();
5857

5958
// Listen to focus changes on control for auto save
60-
if (activeGroup && activeEditor) {
61-
const activeTextEditorWidget = this.editorService.activeTextEditorWidget;
62-
const controlsToObserve: ICodeEditor[] = [];
63-
64-
if (isCodeEditor(activeTextEditorWidget)) {
65-
controlsToObserve.push(activeTextEditorWidget);
66-
} else if (isDiffEditor(activeTextEditorWidget)) {
67-
controlsToObserve.push(activeTextEditorWidget.getOriginalEditor(), activeTextEditorWidget.getModifiedEditor());
68-
}
69-
70-
controlsToObserve.forEach(control => this.lastActiveEditorControlDisposable.add(control.onDidBlurEditorWidget(() => {
59+
const activeEditorControl = this.editorService.activeControl;
60+
if (activeEditor && activeEditorControl) {
61+
this.lastActiveEditorControlDisposable.add(activeEditorControl.onDidBlur(() => {
7162
this.maybeTriggerAutoSave(SaveReason.FOCUS_CHANGE, { groupId: activeGroup.id, editor: activeEditor });
72-
})));
63+
}));
7364
}
7465
}
7566

@@ -78,10 +69,9 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
7869
return; // no auto save for readonly or untitled editors
7970
}
8071

72+
// Determine if we need to save all. In case of a window focus change we also save if 
73+
// auto save mode is configured to be ON_FOCUS_CHANGE (editor focus change)
8174
const mode = this.filesConfigurationService.getAutoSaveMode();
82-
83-
// Determine if we need to save all. In case of a window focus change we also save if auto save mode
84-
// is configured to be ON_FOCUS_CHANGE (editor focus change)
8575
if (
8676
(reason === SaveReason.WINDOW_CHANGE && (mode === AutoSaveMode.ON_FOCUS_CHANGE || mode === AutoSaveMode.ON_WINDOW_CHANGE)) ||
8777
(reason === SaveReason.FOCUS_CHANGE && mode === AutoSaveMode.ON_FOCUS_CHANGE)

src/vs/workbench/common/composite.ts

+11
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,20 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { IAction, IActionViewItem } from 'vs/base/common/actions';
7+
import { Event } from 'vs/base/common/event';
78

89
export interface IComposite {
910

11+
/**
12+
* An event when the composite gained focus.
13+
*/
14+
readonly onDidFocus: Event<void>;
15+
16+
/**
17+
* An event when the composite lost focus.
18+
*/
19+
readonly onDidBlur: Event<void>;
20+
1021
/**
1122
* Returns the unique identifier of this composite.
1223
*/

src/vs/workbench/common/editor.ts

+2-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { coalesce, firstOrDefault } from 'vs/base/common/arrays';
2323
import { ITextFileSaveOptions, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
2424
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
2525
import { isEqual } from 'vs/base/common/resources';
26+
import { IPanel } from 'vs/workbench/common/panel';
2627

2728
export const DirtyWorkingCopiesContext = new RawContextKey<boolean>('dirtyWorkingCopies', false);
2829
export const ActiveEditorContext = new RawContextKey<string | null>('activeEditor', null);
@@ -54,7 +55,7 @@ export const TEXT_DIFF_EDITOR_ID = 'workbench.editors.textDiffEditor';
5455
*/
5556
export const BINARY_DIFF_EDITOR_ID = 'workbench.editors.binaryResourceDiffEditor';
5657

57-
export interface IEditor {
58+
export interface IEditor extends IPanel {
5859

5960
/**
6061
* The assigned input of this editor.
@@ -96,21 +97,11 @@ export interface IEditor {
9697
*/
9798
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined>;
9899

99-
/**
100-
* Returns the unique identifier of this editor.
101-
*/
102-
getId(): string;
103-
104100
/**
105101
* Returns the underlying control of this editor.
106102
*/
107103
getControl(): IEditorControl | undefined;
108104

109-
/**
110-
* Asks the underlying control to focus.
111-
*/
112-
focus(): void;
113-
114105
/**
115106
* Finds out if this editor is visible or not.
116107
*/

src/vs/workbench/services/progress/test/progressIndicator.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
1111
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
1212
import { IViewlet } from 'vs/workbench/common/viewlet';
1313
import { TestViewletService, TestPanelService } from 'vs/workbench/test/workbenchTestServices';
14+
import { Event } from 'vs/base/common/event';
1415

1516
class TestViewlet implements IViewlet {
1617

1718
constructor(private id: string) { }
1819

20+
readonly onDidBlur = Event.None;
21+
readonly onDidFocus = Event.None;
22+
1923
getId(): string { return this.id; }
2024
getTitle(): string { return this.id; }
2125
getActions(): IAction[] { return []; }

0 commit comments

Comments
 (0)