mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-04 15:25:47 +01:00
debt - introduce and use dialog main service
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor, IpcMainEvent } from 'electron';
|
||||
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor, IpcMainEvent, BrowserWindow } from 'electron';
|
||||
import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform';
|
||||
import { WindowsManager } from 'vs/code/electron-main/windows';
|
||||
import { OpenContext, IWindowOpenable } from 'vs/platform/windows/common/windows';
|
||||
@@ -78,6 +78,8 @@ import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
|
||||
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
export class CodeApplication extends Disposable {
|
||||
|
||||
@@ -85,6 +87,7 @@ export class CodeApplication extends Disposable {
|
||||
private static readonly TRUE_MACHINE_ID_KEY = 'telemetry.trueMachineId';
|
||||
|
||||
private windowsMainService: IWindowsMainService | undefined;
|
||||
private dialogMainService: IDialogMainService | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly mainIpcServer: Server,
|
||||
@@ -449,6 +452,7 @@ export class CodeApplication extends Disposable {
|
||||
}
|
||||
|
||||
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));
|
||||
services.set(IDialogMainService, new SyncDescriptor(DialogMainService));
|
||||
services.set(ISharedProcessMainService, new SyncDescriptor(SharedProcessMainService, [sharedProcess]));
|
||||
services.set(ILaunchMainService, new SyncDescriptor(LaunchMainService));
|
||||
|
||||
@@ -503,13 +507,13 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
contentTracing.stopRecording(join(homedir(), `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`), path => {
|
||||
if (!timeout) {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.showMessageBox({
|
||||
if (this.dialogMainService) {
|
||||
this.dialogMainService.showMessageBox({
|
||||
type: 'info',
|
||||
message: localize('trace.message', "Successfully created trace."),
|
||||
detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
|
||||
buttons: [localize('trace.ok', "Ok")]
|
||||
}, this.windowsMainService.getLastActiveWindow());
|
||||
}, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
}
|
||||
} else {
|
||||
this.logService.info(`Tracing: data recorded (after 30s timeout) to ${path}`);
|
||||
@@ -580,6 +584,7 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
// Propagate to clients
|
||||
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
||||
this.dialogMainService = accessor.get(IDialogMainService);
|
||||
|
||||
// Create a URL handler to open file URIs in the active window
|
||||
const environmentService = accessor.get(IEnvironmentService);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { basename, normalize, join, dirname } from 'vs/base/common/path';
|
||||
import { basename, normalize, join } from 'vs/base/common/path';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { assign, mixin } from 'vs/base/common/objects';
|
||||
@@ -13,7 +13,7 @@ import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter, shell, MessageBoxReturnValue, MessageBoxOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, Display } from 'electron';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, systemPreferences, MessageBoxOptions, Display } from 'electron';
|
||||
import { parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -27,20 +27,20 @@ import { ITelemetryService, ITelemetryData } from 'vs/platform/telemetry/common/
|
||||
import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent, ICodeWindow, IWindowState as ISingleWindowState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
|
||||
import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
import { IWorkspaceIdentifier, WORKSPACE_FILTER, isSingleFolderWorkspaceIdentifier, hasWorkspaceFileExtension, IEnterWorkspaceResult, IRecent } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, hasWorkspaceFileExtension, IEnterWorkspaceResult, IRecent } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { normalizeNFC } from 'vs/base/common/normalization';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Queue } from 'vs/base/common/async';
|
||||
import { exists, dirExists } from 'vs/base/node/pfs';
|
||||
import { dirExists } from 'vs/base/node/pfs';
|
||||
import { getComparisonKey, isEqual, normalizePath, basename as resourcesBasename, originalFSPath, hasTrailingPathSeparator, removeTrailingPathSeparator } from 'vs/base/common/resources';
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { restoreWindowsState, WindowsStateStorageData, getWindowsStateStoreData } from 'vs/code/electron-main/windowsStateStorage';
|
||||
import { getWorkspaceIdentifier, IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
const enum WindowError {
|
||||
UNRESPONSIVE = 1,
|
||||
@@ -167,7 +167,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
private readonly windowsState: IWindowsState;
|
||||
private lastClosedWindowState?: IWindowState;
|
||||
|
||||
private readonly dialogs: Dialogs;
|
||||
private readonly workspacesManager: WorkspacesManager;
|
||||
|
||||
private readonly _onWindowReady = this._register(new Emitter<ICodeWindow>());
|
||||
@@ -194,7 +193,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkspacesHistoryMainService private readonly workspacesHistoryMainService: IWorkspacesHistoryMainService,
|
||||
@IWorkspacesMainService private readonly workspacesMainService: IWorkspacesMainService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IDialogMainService private readonly dialogMainService: IDialogMainService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -203,8 +203,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
this.windowsState.openedWindows = [];
|
||||
}
|
||||
|
||||
this.dialogs = new Dialogs(stateService, this);
|
||||
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, this);
|
||||
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, this, dialogMainService);
|
||||
|
||||
this.lifecycleMainService.when(LifecycleMainPhase.Ready).then(() => this.registerListeners());
|
||||
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => this.installWindowsMutex());
|
||||
@@ -380,12 +379,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
};
|
||||
}
|
||||
|
||||
async openExternal(url: string): Promise<boolean> {
|
||||
shell.openExternal(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
open(openConfig: IOpenConfiguration): ICodeWindow[] {
|
||||
this.logService.trace('windowsManager#open');
|
||||
openConfig = this.validateOpenConfig(openConfig);
|
||||
@@ -883,7 +876,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
noLink: true
|
||||
};
|
||||
|
||||
this.dialogs.showMessageBox(options, this.getFocusedWindow());
|
||||
this.dialogMainService.showMessageBox(options, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
}
|
||||
}
|
||||
return pathsToOpen;
|
||||
@@ -1013,10 +1006,12 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
this.logService.error(`Invalid URI input string, scheme missing: ${arg}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return uri;
|
||||
} catch (e) {
|
||||
this.logService.error(`Invalid URI input string: ${arg}, ${e.message}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1052,6 +1047,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
remoteAuthority
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
fileUri: uri,
|
||||
remoteAuthority
|
||||
@@ -1714,14 +1710,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// Show Dialog
|
||||
this.dialogs.showMessageBox({
|
||||
this.dialogMainService.showMessageBox({
|
||||
title: product.nameLong,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'wait', comment: ['&& denotes a mnemonic'] }, "&&Keep Waiting")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message: localize('appStalled', "The window is no longer responding"),
|
||||
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
|
||||
noLink: true
|
||||
}, window).then(result => {
|
||||
}, window.win).then(result => {
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
@@ -1737,14 +1733,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
// Crashed
|
||||
else {
|
||||
this.dialogs.showMessageBox({
|
||||
this.dialogMainService.showMessageBox({
|
||||
title: product.nameLong,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message: localize('appCrashed', "The window has crashed"),
|
||||
detail: localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
|
||||
noLink: true
|
||||
}, window).then(result => {
|
||||
}, window.win).then(result => {
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
@@ -1774,8 +1770,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
async pickFileFolderAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('open', "Open");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFolders: true, pickFiles: true, title });
|
||||
const paths = await this.dialogMainService.pickFileFolder(options);
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFileFolder', options.telemetryExtraData);
|
||||
const urisToOpen = await Promise.all(paths.map(async path => {
|
||||
@@ -1794,8 +1789,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
async pickFolderAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openFolder', "Open Folder");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFolders: true, title });
|
||||
const paths = await this.dialogMainService.pickFolder(options);
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFolder', options.telemetryExtraData);
|
||||
this.open({
|
||||
@@ -1809,8 +1803,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
async pickFileAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openFile', "Open File");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFiles: true, title });
|
||||
const paths = await this.dialogMainService.pickFile(options);
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFile', options.telemetryExtraData);
|
||||
this.open({
|
||||
@@ -1824,10 +1817,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
async pickWorkspaceAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openWorkspaceTitle', "Open Workspace");
|
||||
const buttonLabel = mnemonicButtonLabel(localize({ key: 'openWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open"));
|
||||
const filters = WORKSPACE_FILTER;
|
||||
const paths = await this.dialogs.pick({ ...options, pickFiles: true, title, filters, buttonLabel });
|
||||
const paths = await this.dialogMainService.pickWorkspace(options);
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openWorkspace', options.telemetryExtraData);
|
||||
this.open({
|
||||
@@ -1842,7 +1832,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
private sendPickerTelemetry(paths: string[], telemetryEventName: string, telemetryExtraData?: ITelemetryData) {
|
||||
|
||||
const numberOfPaths = paths ? paths.length : 0;
|
||||
|
||||
// Telemetry
|
||||
@@ -1854,18 +1843,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
});
|
||||
}
|
||||
|
||||
showMessageBox(options: MessageBoxOptions, win?: ICodeWindow): Promise<MessageBoxReturnValue> {
|
||||
return this.dialogs.showMessageBox(options, win);
|
||||
}
|
||||
|
||||
showSaveDialog(options: SaveDialogOptions, win?: ICodeWindow): Promise<SaveDialogReturnValue> {
|
||||
return this.dialogs.showSaveDialog(options, win);
|
||||
}
|
||||
|
||||
showOpenDialog(options: OpenDialogOptions, win?: ICodeWindow): Promise<OpenDialogReturnValue> {
|
||||
return this.dialogs.showOpenDialog(options, win);
|
||||
}
|
||||
|
||||
quit(): void {
|
||||
|
||||
// If the user selected to exit from an extension development host window, do not quit, but just
|
||||
@@ -1884,165 +1861,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
interface IInternalNativeOpenDialogOptions extends INativeOpenDialogOptions {
|
||||
|
||||
pickFolders?: boolean;
|
||||
pickFiles?: boolean;
|
||||
|
||||
title: string;
|
||||
buttonLabel?: string;
|
||||
filters?: FileFilter[];
|
||||
}
|
||||
|
||||
class Dialogs {
|
||||
|
||||
private static readonly workingDirPickerStorageKey = 'pickerWorkingDir';
|
||||
|
||||
private readonly mapWindowToDialogQueue: Map<number, Queue<void>>;
|
||||
private readonly noWindowDialogQueue: Queue<void>;
|
||||
|
||||
constructor(
|
||||
private readonly stateService: IStateService,
|
||||
private readonly windowsMainService: IWindowsMainService
|
||||
) {
|
||||
this.mapWindowToDialogQueue = new Map<number, Queue<void>>();
|
||||
this.noWindowDialogQueue = new Queue<void>();
|
||||
}
|
||||
|
||||
async pick(options: IInternalNativeOpenDialogOptions, win?: ICodeWindow): Promise<string[] | undefined> {
|
||||
|
||||
// Ensure dialog options
|
||||
const dialogOptions: OpenDialogOptions = {
|
||||
title: options.title,
|
||||
buttonLabel: options.buttonLabel,
|
||||
filters: options.filters
|
||||
};
|
||||
|
||||
// Ensure defaultPath
|
||||
dialogOptions.defaultPath = options.defaultPath || this.stateService.getItem<string>(Dialogs.workingDirPickerStorageKey);
|
||||
|
||||
|
||||
// Ensure properties
|
||||
if (typeof options.pickFiles === 'boolean' || typeof options.pickFolders === 'boolean') {
|
||||
dialogOptions.properties = undefined; // let it override based on the booleans
|
||||
|
||||
if (options.pickFiles && options.pickFolders) {
|
||||
dialogOptions.properties = ['multiSelections', 'openDirectory', 'openFile', 'createDirectory'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!dialogOptions.properties) {
|
||||
dialogOptions.properties = ['multiSelections', options.pickFolders ? 'openDirectory' : 'openFile', 'createDirectory'];
|
||||
}
|
||||
|
||||
if (isMacintosh) {
|
||||
dialogOptions.properties.push('treatPackageAsDirectory'); // always drill into .app files
|
||||
}
|
||||
|
||||
// Show Dialog
|
||||
const windowToUse = win || this.windowsMainService.getFocusedWindow();
|
||||
|
||||
const result = await this.showOpenDialog(dialogOptions, windowToUse);
|
||||
if (result && result.filePaths && result.filePaths.length > 0) {
|
||||
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(result.filePaths[0]));
|
||||
|
||||
return result.filePaths;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private getDialogQueue(window?: ICodeWindow): Queue<any> {
|
||||
if (!window) {
|
||||
return this.noWindowDialogQueue;
|
||||
}
|
||||
|
||||
let windowDialogQueue = this.mapWindowToDialogQueue.get(window.id);
|
||||
if (!windowDialogQueue) {
|
||||
windowDialogQueue = new Queue<any>();
|
||||
this.mapWindowToDialogQueue.set(window.id, windowDialogQueue);
|
||||
}
|
||||
|
||||
return windowDialogQueue;
|
||||
}
|
||||
|
||||
showMessageBox(options: MessageBoxOptions, window?: ICodeWindow): Promise<MessageBoxReturnValue> {
|
||||
return this.getDialogQueue(window).queue(async () => {
|
||||
if (window) {
|
||||
return dialog.showMessageBox(window.win, options);
|
||||
}
|
||||
|
||||
return dialog.showMessageBox(options);
|
||||
});
|
||||
}
|
||||
|
||||
showSaveDialog(options: SaveDialogOptions, window?: ICodeWindow): Promise<SaveDialogReturnValue> {
|
||||
|
||||
function normalizePath(path: string | undefined): string | undefined {
|
||||
if (path && isMacintosh) {
|
||||
path = normalizeNFC(path); // normalize paths returned from the OS
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
return this.getDialogQueue(window).queue(async () => {
|
||||
let result: SaveDialogReturnValue;
|
||||
if (window) {
|
||||
result = await dialog.showSaveDialog(window.win, options);
|
||||
} else {
|
||||
result = await dialog.showSaveDialog(options);
|
||||
}
|
||||
|
||||
result.filePath = normalizePath(result.filePath);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
showOpenDialog(options: OpenDialogOptions, window?: ICodeWindow): Promise<OpenDialogReturnValue> {
|
||||
|
||||
function normalizePaths(paths: string[] | undefined): string[] | undefined {
|
||||
if (paths && paths.length > 0 && isMacintosh) {
|
||||
paths = paths.map(path => normalizeNFC(path)); // normalize paths returned from the OS
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
return this.getDialogQueue(window).queue(async () => {
|
||||
|
||||
// Ensure the path exists (if provided)
|
||||
if (options.defaultPath) {
|
||||
const pathExists = await exists(options.defaultPath);
|
||||
if (!pathExists) {
|
||||
options.defaultPath = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Show dialog
|
||||
let result: OpenDialogReturnValue;
|
||||
if (window) {
|
||||
result = await dialog.showOpenDialog(window.win, options);
|
||||
} else {
|
||||
result = await dialog.showOpenDialog(options);
|
||||
}
|
||||
|
||||
result.filePaths = normalizePaths(result.filePaths);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class WorkspacesManager {
|
||||
|
||||
constructor(
|
||||
private readonly workspacesMainService: IWorkspacesMainService,
|
||||
private readonly backupMainService: IBackupMainService,
|
||||
private readonly windowsMainService: IWindowsMainService,
|
||||
private readonly dialogMainService: IDialogMainService
|
||||
) { }
|
||||
|
||||
async enterWorkspace(window: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | null> {
|
||||
@@ -2078,7 +1903,7 @@ class WorkspacesManager {
|
||||
noLink: true
|
||||
};
|
||||
|
||||
await this.windowsMainService.showMessageBox(options, this.windowsMainService.getFocusedWindow());
|
||||
await this.dialogMainService.showMessageBox(options, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user