Skip to content

Commit 5bb2cb8

Browse files
committed
Enable all window restore on quit
Part of microsoft#13305
1 parent 8ed9c07 commit 5bb2cb8

7 files changed

Lines changed: 31 additions & 14 deletions

File tree

src/vs/code/electron-main/lifecycle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class LifecycleService implements ILifecycleService {
185185
c(true); // veto
186186
});
187187

188-
vscodeWindow.send('vscode:beforeUnload', { okChannel: oneTimeOkEvent, cancelChannel: oneTimeCancelEvent });
188+
vscodeWindow.send('vscode:beforeUnload', { okChannelReply: oneTimeOkEvent, cancelChannelReply: oneTimeCancelEvent, quitRequested: this.quitRequested });
189189
});
190190
}
191191

src/vs/platform/lifecycle/common/lifecycle.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const ILifecycleService = createDecorator<ILifecycleService>('lifecycleSe
2222
export interface ShutdownEvent {
2323

2424
veto(value: boolean | TPromise<boolean>): void;
25+
quitRequested: boolean;
2526
}
2627

2728
/**
@@ -38,6 +39,12 @@ export interface ILifecycleService {
3839
*/
3940
willShutdown: boolean;
4041

42+
/**
43+
* A flag indications if the application is in the process of quitting all windows. This will be
44+
* set before the onWillShutdown event is fired and reverted to false afterwards.
45+
*/
46+
quitRequested: boolean;
47+
4148
/**
4249
* Fired before shutdown happens. Allows listeners to veto against the
4350
* shutdown.

src/vs/workbench/services/backup/common/backup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface IBackupService {
2222
_serviceBrand: any;
2323

2424
isHotExitEnabled: boolean;
25-
backupBeforeShutdown(dirtyToBackup: Uri[], textFileEditorModelManager: ITextFileEditorModelManager, confirmCallback: () => boolean | TPromise<boolean>): boolean | TPromise<boolean>;
25+
backupBeforeShutdown(dirtyToBackup: Uri[], textFileEditorModelManager: ITextFileEditorModelManager, quitRequested: boolean, confirmCallback: () => boolean | TPromise<boolean>): boolean | TPromise<boolean>;
2626
cleanupBackupsBeforeShutdown(): boolean | TPromise<boolean>;
2727

2828
doBackup(resource: Uri, content: string, immediate?: boolean): TPromise<void>;

src/vs/workbench/services/backup/node/backupService.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,16 @@ export class BackupService implements IBackupService {
129129
return this.configuredHotExit && this.contextService.getWorkspace() && !platform.isMacintosh;
130130
}
131131

132-
public backupBeforeShutdown(dirtyToBackup: Uri[], textFileEditorModelManager: ITextFileEditorModelManager, confirmCallback: () => boolean | TPromise<boolean>): boolean | TPromise<boolean> {
132+
public backupBeforeShutdown(dirtyToBackup: Uri[], textFileEditorModelManager: ITextFileEditorModelManager, quitRequested: boolean, confirmCallback: () => boolean | TPromise<boolean>): boolean | TPromise<boolean> {
133133
// If there are no dirty files, clean up and exit
134134
if (dirtyToBackup.length === 0) {
135135
return this.cleanupBackupsBeforeShutdown();
136136
}
137137

138138
return this.backupFileService.getWorkspaceBackupPaths().then(workspaceBackupPaths => {
139-
// Only remove the workspace from the backup service if it's not the last one or it's not dirty
140-
if (workspaceBackupPaths.length > 1) {
139+
// Only remove the workspace's backups if it's not the last one or it's not dirty. The one exception to this
140+
// is if quit (all windows) was requested then all windows should be backed up and restored on next launch..
141+
if (!quitRequested && workspaceBackupPaths.length > 1) {
141142
return confirmCallback(); // confirm save
142143
}
143144

src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export class LifecycleService implements ILifecycleService {
2121
private _onShutdown = new Emitter<void>();
2222

2323
private _willShutdown: boolean;
24+
private _quitRequested: boolean;
2425

2526
constructor(
2627
@IMessageService private messageService: IMessageService,
@@ -33,6 +34,10 @@ export class LifecycleService implements ILifecycleService {
3334
return this._willShutdown;
3435
}
3536

37+
public get quitRequested(): boolean {
38+
return this._quitRequested;
39+
}
40+
3641
public get onWillShutdown(): Event<ShutdownEvent> {
3742
return this._onWillShutdown.event;
3843
}
@@ -45,29 +50,32 @@ export class LifecycleService implements ILifecycleService {
4550
const windowId = this.windowService.getWindowId();
4651

4752
// Main side indicates that window is about to unload, check for vetos
48-
ipc.on('vscode:beforeUnload', (event, reply: { okChannel: string, cancelChannel: string }) => {
53+
ipc.on('vscode:beforeUnload', (event, args: { okChannelReply: string, cancelChannelReply: string, quitRequested: boolean }) => {
4954
this._willShutdown = true;
55+
this._quitRequested = args.quitRequested;
5056

5157
// trigger onWillShutdown events and veto collecting
52-
this.onBeforeUnload().done(veto => {
58+
this.onBeforeUnload(args.quitRequested).done(veto => {
59+
this._quitRequested = false;
5360
if (veto) {
5461
this._willShutdown = false; // reset this flag since the shutdown has been vetoed!
55-
ipc.send(reply.cancelChannel, windowId);
62+
ipc.send(args.cancelChannelReply, windowId);
5663
} else {
5764
this._onShutdown.fire();
58-
ipc.send(reply.okChannel, windowId);
65+
ipc.send(args.okChannelReply, windowId);
5966
}
6067
});
6168
});
6269
}
6370

64-
private onBeforeUnload(): TPromise<boolean> {
71+
private onBeforeUnload(quitRequested: boolean): TPromise<boolean> {
6572
const vetos: (boolean | TPromise<boolean>)[] = [];
6673

6774
this._onWillShutdown.fire({
6875
veto(value) {
6976
vetos.push(value);
70-
}
77+
},
78+
quitRequested
7179
});
7280

7381
if (vetos.length === 0) {

src/vs/workbench/services/textfile/browser/textFileService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export abstract class TextFileService implements ITextFileService {
101101
private registerListeners(): void {
102102

103103
// Lifecycle
104-
this.lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown()));
104+
this.lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown(event.quitRequested)));
105105
this.lifecycleService.onShutdown(this.dispose, this);
106106

107107
// Configuration changes
@@ -113,9 +113,9 @@ export abstract class TextFileService implements ITextFileService {
113113
this.toUnbind.push(this.editorGroupService.onEditorsChanged(() => this.onEditorFocusChanged()));
114114
}
115115

116-
private beforeShutdown(): boolean | TPromise<boolean> {
116+
private beforeShutdown(quitRequested: boolean): boolean | TPromise<boolean> {
117117
if (this.backupService.isHotExitEnabled) {
118-
return this.backupService.backupBeforeShutdown(this.getDirty(), this.models, this.confirmBeforeShutdown.bind(this));
118+
return this.backupService.backupBeforeShutdown(this.getDirty(), this.models, quitRequested, this.confirmBeforeShutdown.bind(this));
119119
}
120120

121121
// Dirty files need treatment on shutdown

src/vs/workbench/services/textfile/test/textFileService.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ServiceAccessor {
2828
class ShutdownEventImpl implements ShutdownEvent {
2929

3030
public value: boolean | TPromise<boolean>;
31+
public quitRequested: boolean = false;
3132

3233
veto(value: boolean | TPromise<boolean>): void {
3334
this.value = value;

0 commit comments

Comments
 (0)