Skip to content

Commit

Permalink
use windowService.reload() generally; fix double prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
colin-grant-work committed Nov 4, 2021
1 parent a32c320 commit 03c07ba
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 21 deletions.
10 changes: 7 additions & 3 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { QuickInputService, QuickPick, QuickPickItem } from './quick-input';
import { AsyncLocalizationProvider } from '../common/i18n/localization';
import { nls } from '../common/nls';
import { confirmExit } from './dialogs';
import { WindowService } from './window/window-service';

export namespace CommonMenus {

Expand Down Expand Up @@ -349,6 +350,9 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
@inject(AuthenticationService)
protected readonly authenticationService: AuthenticationService;

@inject(WindowService)
protected readonly windowService: WindowService;

async configure(app: FrontendApplication): Promise<void> {
const configDirUri = await this.environments.getConfigDirUri();
// Global settings
Expand Down Expand Up @@ -1041,10 +1045,10 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
for (const additionalLanguage of ['en', ...availableLanguages]) {
items.push({
label: additionalLanguage,
execute: () => {
if (additionalLanguage !== nls.locale) {
execute: async () => {
if (additionalLanguage !== nls.locale && await this.windowService.safeToShutDown()) {
window.localStorage.setItem(nls.localeId, additionalLanguage);
window.location.reload();
this.windowService.reload();
}
}
});
Expand Down
34 changes: 23 additions & 11 deletions packages/core/src/browser/window/default-window-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { confirmExit } from '../dialogs';
export class DefaultWindowService implements WindowService, FrontendApplicationContribution {

protected frontendApplication: FrontendApplication;
protected allowVetoes = true;

protected onUnloadEmitter = new Emitter<void>();
get onUnload(): Event<void> {
Expand Down Expand Up @@ -54,21 +55,31 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
this.openNewWindow(DEFAULT_WINDOW_HASH);
}

/**
* Returns a list of actions that {@link FrontendApplicationContribution}s would like to take before shutdown
* It is expected that this will succeed - i.e. return an empty array - at most once per session. If no vetoes are received
* during any cycle, no further checks will be made. In that case, shutdown should proceed unconditionally.
*/
protected collectContributionUnloadVetoes(): OnWillStopAction[] {
const vetoes = [];
const shouldConfirmExit = this.corePreferences['application.confirmExit'];
for (const contribution of this.contributions.getContributions()) {
const veto = contribution.onWillStop?.(this.frontendApplication);
if (veto && shouldConfirmExit !== 'never') { // Ignore vetoes if we should not prompt for exit.
if (OnWillStopAction.is(veto)) {
vetoes.push(veto);
} else {
vetoes.push({ reason: 'No reason given', action: () => false });
if (this.allowVetoes) {
const shouldConfirmExit = this.corePreferences['application.confirmExit'];
for (const contribution of this.contributions.getContributions()) {
const veto = contribution.onWillStop?.(this.frontendApplication);
if (veto && shouldConfirmExit !== 'never') { // Ignore vetoes if we should not prompt for exit or if we have already run vetoes.
if (OnWillStopAction.is(veto)) {
vetoes.push(veto);
} else {
vetoes.push({ reason: 'No reason given', action: () => false });
}
}
}
}
if (vetoes.length === 0 && shouldConfirmExit === 'always') {
vetoes.push({ reason: 'application.confirmExit preference', action: () => confirmExit() });
if (vetoes.length === 0 && shouldConfirmExit === 'always') {
vetoes.push({ reason: 'application.confirmExit preference', action: () => confirmExit() });
}
if (vetoes.length === 0) {
this.allowVetoes = false;
}
}
return vetoes;
}
Expand All @@ -94,6 +105,7 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
const resolvedVetoes = await Promise.allSettled(vetoes.map(({ action }) => action()));
if (resolvedVetoes.every(resolution => resolution.status === 'rejected' || resolution.value === true)) {
console.debug('OnWillStop actions resolved; allowing shutdown');
this.allowVetoes = false;
return true;
} else {
return false;
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/browser/window/window-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export interface WindowService {
/**
* Checks `FrontendApplicationContribution#willStop` for impediments to shutdown and runs any actions returned.
* Can be used safely in browser and Electron when triggering reload or shutdown programmatically.
* Should _only_ be called before a shutdown - if this returns `true`, `FrontendApplicationContribution#willStop`
* will not be called again in the current session. I.e. if this return `true`, the shutdown should proceed without
* further condition.
*/
safeToShutDown(): Promise<boolean>;

Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/electron-common/messaging/electron-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@ export const CLOSE_REQUESTED_SIGNAL = 'close-requested';
export const RELOAD_REQUESTED_SIGNAL = 'reload-requested';

export enum StopReason {
/**
* Closing the window with no prospect of restart.
*/
Close,
/**
* Reload without closing the window.
*/
Reload,
/**
* Reload that includes closing the window.
*/
Restart, // eslint-disable-line @typescript-eslint/no-shadow
}

export interface CloseRequestArguments {
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/electron-main/electron-main-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,15 @@ export class ElectronMainApplication {
}

event.preventDefault();
const doExit = () => {
this.closeIsConfirmed.add(electronWindow.id);
electronWindow.close();
};
this.handleStopRequest(electronWindow, doExit, StopReason.Close);
this.handleStopRequest(electronWindow, () => this.doCloseWindow(electronWindow), StopReason.Close);
});
}

protected doCloseWindow(electronWindow: BrowserWindow): void {
this.closeIsConfirmed.add(electronWindow.id);
electronWindow.close();
}

protected async handleStopRequest(electronWindow: BrowserWindow, onSafeCallback: () => unknown, reason: StopReason): Promise<void> {
const safeToClose = await this.checkSafeToStop(electronWindow, reason);
if (safeToClose) {
Expand Down Expand Up @@ -607,7 +608,7 @@ export class ElectronMainApplication {
});
this.restarting = false;
});
window.close();
this.handleStopRequest(window, () => this.doCloseWindow(window), StopReason.Restart);
}

protected async handleReload(event: Electron.IpcMainEvent): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import {
} from '@theia/plugin-ext/lib/main/browser/callhierarchy/callhierarchy-type-converters';
import { CustomEditorOpener } from '@theia/plugin-ext/lib/main/browser/custom-editors/custom-editor-opener';
import { nls } from '@theia/core/lib/common/nls';
import { WindowService } from '@theia/core/lib/browser/window/window-service';

export namespace VscodeCommands {
export const OPEN: Command = {
Expand Down Expand Up @@ -137,6 +138,8 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
protected readonly callHierarchyProvider: CallHierarchyServiceProvider;
@inject(MonacoTextModelService)
protected readonly textModelService: MonacoTextModelService;
@inject(WindowService)
protected readonly windowService: WindowService;

private async openWith(commandId: string, resource: URI, columnOrOptions?: ViewColumn | TextDocumentShowOptions, openerId?: string): Promise<boolean> {
if (!resource) {
Expand Down Expand Up @@ -477,7 +480,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {

commands.registerCommand({ id: 'workbench.action.reloadWindow' }, {
execute: () => {
window.location.reload();
this.windowService.reload();
}
});

Expand Down

0 comments on commit 03c07ba

Please sign in to comment.