Window crash: "Reopen" does not work on macOS (fix #135572)

This commit is contained in:
Benjamin Pasero 2021-10-23 13:41:50 +02:00
parent b3d1442477
commit e78e63fc3a
No known key found for this signature in database
GPG key ID: E6380CC4C8219E65
2 changed files with 54 additions and 25 deletions

View file

@ -653,7 +653,13 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
//#region macOS Touchbar
async newWindowTab(): Promise<void> {
this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentMainService.args, forceNewTabbedWindow: true, forceEmpty: true, remoteAuthority: this.environmentMainService.args.remote || undefined });
this.windowsMainService.open({
context: OpenContext.API,
cli: this.environmentMainService.args,
forceNewTabbedWindow: true,
forceEmpty: true,
remoteAuthority: this.environmentMainService.args.remote || undefined
});
}
async showPreviousWindowTab(): Promise<void> {

View file

@ -32,8 +32,8 @@ import { IStorageMainService } from 'vs/platform/storage/electron-main/storageMa
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
import { getMenuBarVisibility, getTitleBarStyle, INativeWindowConfiguration, IWindowSettings, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, LoadReason, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { getMenuBarVisibility, getTitleBarStyle, IFolderToOpen, INativeWindowConfiguration, IWindowSettings, IWorkspaceToOpen, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowsMainService, IWindowState, LoadReason, OpenContext, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
@ -158,7 +158,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
@IDialogMainService private readonly dialogMainService: IDialogMainService,
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
@IProductService private readonly productService: IProductService,
@IProtocolMainService private readonly protocolMainService: IProtocolMainService
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
@IWindowsMainService private readonly windowsMainService: IWindowsMainService
) {
super();
@ -617,15 +618,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
cancelId: 1
}, this._win);
if (!this._win) {
return; // Return early if the window has been going down already
}
if (result.response === 0) {
this._win.webContents.forcefullyCrashRenderer(); // Calling reload() immediately after calling this method will force the reload to occur in a new process
this.reload();
} else if (result.response === 2) {
this.destroyWindow();
// Handle choice
if (result.response !== 1 /* keep waiting */) {
const reopen = result.response === 0;
this.destroyWindow(reopen);
}
}
@ -638,6 +634,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}', code: '{1}')", details.reason, details.exitCode ?? '<unknown>');
}
// Show Dialog
const result = await this.dialogMainService.showMessageBox({
title: this.productService.nameLong,
type: 'warning',
@ -651,23 +648,49 @@ export class CodeWindow extends Disposable implements ICodeWindow {
defaultId: 0
}, this._win);
if (!this._win) {
return; // Return early if the window has been going down already
}
if (result.response === 0) {
this.reload();
} else if (result.response === 1) {
this.destroyWindow();
}
// Handle choice
const reopen = result.response === 0;
this.destroyWindow(reopen);
}
break;
}
}
private destroyWindow(): void {
this._onDidDestroy.fire(); // 'close' event will not be fired on destroy(), so signal crash via explicit event
this._win.destroy(); // make sure to destroy the window as it has crashed
private destroyWindow(reopen: boolean): void {
// 'close' event will not be fired on destroy(), so signal crash via explicit event
this._onDidDestroy.fire();
// make sure to destroy the window as it has crashed
this._win?.destroy();
// ask the windows service to open a new fresh window if specified
if (reopen && this.config) {
// We have to reconstruct a openable from the current workspace
let workspace: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
let forceEmpty = undefined;
if (isSingleFolderWorkspaceIdentifier(this.openedWorkspace)) {
workspace = { folderUri: this.openedWorkspace.uri };
} else if (isWorkspaceIdentifier(this.openedWorkspace)) {
workspace = { workspaceUri: this.openedWorkspace.configPath };
} else {
forceEmpty = true;
}
// Delegate to windows service
const [window] = this.windowsMainService.open({
context: OpenContext.API,
userEnv: this.config.userEnv,
cli: {
...this.environmentMainService.args,
_: [] // we pass in the workspace to open explicitly via `urisToOpen`
},
urisToOpen: workspace ? [workspace] : undefined,
forceEmpty
});
window.focus();
}
}
private onDidDeleteUntitledWorkspace(workspace: IWorkspaceIdentifier): void {