Skip to content

Commit e78e63f

Browse files
committed
Window crash: "Reopen" does not work on macOS (fix microsoft#135572)
1 parent b3d1442 commit e78e63f

File tree

2 files changed

+54
-25
lines changed

2 files changed

+54
-25
lines changed

src/vs/platform/native/electron-main/nativeHostMainService.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,13 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
653653
//#region macOS Touchbar
654654

655655
async newWindowTab(): Promise<void> {
656-
this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentMainService.args, forceNewTabbedWindow: true, forceEmpty: true, remoteAuthority: this.environmentMainService.args.remote || undefined });
656+
this.windowsMainService.open({
657+
context: OpenContext.API,
658+
cli: this.environmentMainService.args,
659+
forceNewTabbedWindow: true,
660+
forceEmpty: true,
661+
remoteAuthority: this.environmentMainService.args.remote || undefined
662+
});
657663
}
658664

659665
async showPreviousWindowTab(): Promise<void> {

src/vs/platform/windows/electron-main/window.ts

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ import { IStorageMainService } from 'vs/platform/storage/electron-main/storageMa
3232
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
3333
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
3434
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
35-
import { getMenuBarVisibility, getTitleBarStyle, INativeWindowConfiguration, IWindowSettings, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
36-
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, LoadReason, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
35+
import { getMenuBarVisibility, getTitleBarStyle, IFolderToOpen, INativeWindowConfiguration, IWindowSettings, IWorkspaceToOpen, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
36+
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowsMainService, IWindowState, LoadReason, OpenContext, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
3737
import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
3838
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
3939

@@ -158,7 +158,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
158158
@IDialogMainService private readonly dialogMainService: IDialogMainService,
159159
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
160160
@IProductService private readonly productService: IProductService,
161-
@IProtocolMainService private readonly protocolMainService: IProtocolMainService
161+
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
162+
@IWindowsMainService private readonly windowsMainService: IWindowsMainService
162163
) {
163164
super();
164165

@@ -617,15 +618,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
617618
cancelId: 1
618619
}, this._win);
619620

620-
if (!this._win) {
621-
return; // Return early if the window has been going down already
622-
}
623-
624-
if (result.response === 0) {
625-
this._win.webContents.forcefullyCrashRenderer(); // Calling reload() immediately after calling this method will force the reload to occur in a new process
626-
this.reload();
627-
} else if (result.response === 2) {
628-
this.destroyWindow();
621+
// Handle choice
622+
if (result.response !== 1 /* keep waiting */) {
623+
const reopen = result.response === 0;
624+
this.destroyWindow(reopen);
629625
}
630626
}
631627

@@ -638,6 +634,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
638634
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}', code: '{1}')", details.reason, details.exitCode ?? '<unknown>');
639635
}
640636

637+
// Show Dialog
641638
const result = await this.dialogMainService.showMessageBox({
642639
title: this.productService.nameLong,
643640
type: 'warning',
@@ -651,23 +648,49 @@ export class CodeWindow extends Disposable implements ICodeWindow {
651648
defaultId: 0
652649
}, this._win);
653650

654-
if (!this._win) {
655-
return; // Return early if the window has been going down already
656-
}
657-
658-
if (result.response === 0) {
659-
this.reload();
660-
} else if (result.response === 1) {
661-
this.destroyWindow();
662-
}
651+
// Handle choice
652+
const reopen = result.response === 0;
653+
this.destroyWindow(reopen);
663654
}
664655
break;
665656
}
666657
}
667658

668-
private destroyWindow(): void {
669-
this._onDidDestroy.fire(); // 'close' event will not be fired on destroy(), so signal crash via explicit event
670-
this._win.destroy(); // make sure to destroy the window as it has crashed
659+
private destroyWindow(reopen: boolean): void {
660+
661+
// 'close' event will not be fired on destroy(), so signal crash via explicit event
662+
this._onDidDestroy.fire();
663+
664+
// make sure to destroy the window as it has crashed
665+
this._win?.destroy();
666+
667+
// ask the windows service to open a new fresh window if specified
668+
if (reopen && this.config) {
669+
670+
// We have to reconstruct a openable from the current workspace
671+
let workspace: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
672+
let forceEmpty = undefined;
673+
if (isSingleFolderWorkspaceIdentifier(this.openedWorkspace)) {
674+
workspace = { folderUri: this.openedWorkspace.uri };
675+
} else if (isWorkspaceIdentifier(this.openedWorkspace)) {
676+
workspace = { workspaceUri: this.openedWorkspace.configPath };
677+
} else {
678+
forceEmpty = true;
679+
}
680+
681+
// Delegate to windows service
682+
const [window] = this.windowsMainService.open({
683+
context: OpenContext.API,
684+
userEnv: this.config.userEnv,
685+
cli: {
686+
...this.environmentMainService.args,
687+
_: [] // we pass in the workspace to open explicitly via `urisToOpen`
688+
},
689+
urisToOpen: workspace ? [workspace] : undefined,
690+
forceEmpty
691+
});
692+
window.focus();
693+
}
671694
}
672695

673696
private onDidDeleteUntitledWorkspace(workspace: IWorkspaceIdentifier): void {

0 commit comments

Comments
 (0)