Skip to content

Commit 1482909

Browse files
fix: Cannot quit app when there is a dirty editor (#13164)
Contributed by STMicroelectronics Signed-off-by: Emil HAMMARSTEDT <[email protected]>
1 parent 469bd74 commit 1482909

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

packages/core/src/browser/common-frontend-contribution.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import { QuickInputService, QuickPickItem, QuickPickItemOrSeparator, QuickPickSe
5757
import { AsyncLocalizationProvider } from '../common/i18n/localization';
5858
import { nls } from '../common/nls';
5959
import { CurrentWidgetCommandAdapter } from './shell/current-widget-command-adapter';
60-
import { ConfirmDialog, confirmExitWithOrWithoutSaving, Dialog } from './dialogs';
60+
import { ConfirmDialog, confirmExitWithOrWithoutSaving, confirmExitWithOrWithoutSavingResult, Dialog } from './dialogs';
6161
import { WindowService } from './window/window-service';
6262
import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
6363
import { DecorationStyle } from './decoration-style';
@@ -1200,17 +1200,16 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
12001200
action: async () => {
12011201
const captionsToSave = this.unsavedTabsCaptions();
12021202
const untitledCaptionsToSave = this.unsavedUntitledTabsCaptions();
1203-
const result = await confirmExitWithOrWithoutSaving(captionsToSave, async () => {
1203+
const shouldExit = await confirmExitWithOrWithoutSaving(captionsToSave, async () => {
12041204
await this.saveDirty(untitledCaptionsToSave);
12051205
await this.shell.saveAll();
12061206
});
1207-
if (this.shell.canSaveAll()) {
1208-
this.shouldPreventClose = true;
1209-
return false;
1210-
} else {
1211-
this.shouldPreventClose = false;
1212-
return result;
1213-
}
1207+
const allSavedOrDoNotSave = (
1208+
confirmExitWithOrWithoutSavingResult.save === shouldExit && untitledCaptionsToSave.length === 0
1209+
) || confirmExitWithOrWithoutSavingResult.doNotSave === shouldExit;
1210+
1211+
this.shouldPreventClose = !allSavedOrDoNotSave;
1212+
return allSavedOrDoNotSave;
12141213

12151214
}
12161215
};
@@ -1236,11 +1235,19 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
12361235
this.windowService.reload();
12371236
}
12381237
}
1238+
/**
1239+
* saves any dirty widget in toSave
1240+
* side effect - will pop all widgets from toSave that was saved
1241+
* @param toSave
1242+
*/
12391243
protected async saveDirty(toSave: Widget[]): Promise<void> {
12401244
for (const widget of toSave) {
12411245
const saveable = Saveable.get(widget);
12421246
if (saveable?.dirty) {
12431247
await this.saveResourceService.save(widget);
1248+
if (!this.saveResourceService.canSave(widget)) {
1249+
toSave.pop();
1250+
}
12441251
}
12451252
}
12461253
}

packages/core/src/browser/dialogs.ts

+16-5
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,18 @@ export class ConfirmSaveDialog extends AbstractDialog<boolean | undefined> {
458458

459459
}
460460

461+
export enum confirmExitWithOrWithoutSavingResult {
462+
save = 'save',
463+
doNotSave = 'doNotSave',
464+
cancel = 'cancel',
465+
}
466+
461467
// Asks the user to confirm whether they want to exit with or without saving the changes
462-
export async function confirmExitWithOrWithoutSaving(captionsToSave: string[], performSave: () => Promise<void>): Promise<boolean> {
468+
export async function confirmExitWithOrWithoutSaving(captionsToSave: string[], performSave?: () => Promise<void>): Promise<confirmExitWithOrWithoutSavingResult> {
463469
const div: HTMLElement = document.createElement('div');
464470
div.innerText = nls.localizeByDefault("Your changes will be lost if you don't save them.");
465471

472+
let result;
466473
if (captionsToSave.length > 0) {
467474
const span = document.createElement('span');
468475
span.appendChild(document.createElement('br'));
@@ -474,22 +481,26 @@ export async function confirmExitWithOrWithoutSaving(captionsToSave: string[], p
474481
});
475482
span.appendChild(document.createElement('br'));
476483
div.appendChild(span);
477-
const result = await new ConfirmSaveDialog({
484+
result = await new ConfirmSaveDialog({
478485
title: nls.localizeByDefault('Do you want to save the changes to the following {0} files?', captionsToSave.length),
479486
msg: div,
480487
dontSave: nls.localizeByDefault("Don't Save"),
481488
save: nls.localizeByDefault('Save All'),
482489
cancel: Dialog.CANCEL
483490
}).open();
484491

485-
if (result) {
492+
if (result && performSave) {
486493
await performSave();
487494
}
488-
return result !== undefined;
489495
} else {
490496
// fallback if not passed with an empty caption-list.
491-
return confirmExit();
497+
result = confirmExit();
492498
}
499+
if (result !== undefined) {
500+
return result === true ? confirmExitWithOrWithoutSavingResult.save : confirmExitWithOrWithoutSavingResult.doNotSave;
501+
} else {
502+
return confirmExitWithOrWithoutSavingResult.cancel;
503+
};
493504

494505
}
495506
@injectable()

0 commit comments

Comments
 (0)