Merge from vscode 817eb6b0c720a4ecbc13c020afbbebfed667aa09 (#7356)

This commit is contained in:
Anthony Dresser
2019-09-24 21:36:17 -07:00
committed by GitHub
parent a29ae4d3b9
commit 6a6048d40f
541 changed files with 7045 additions and 7287 deletions

View File

@@ -209,4 +209,10 @@ if (options.workspaceUri) {
options.workspaceUri = URI.revive(options.workspaceUri);
}
if (Array.isArray(options.staticExtensions)) {
options.staticExtensions.forEach(extension => {
extension.extensionLocation = URI.revive(extension.extensionLocation);
});
}
create(document.body, options);

View File

@@ -303,7 +303,7 @@ export class IssueReporter extends Disposable {
const loggerClient = new LoggerChannelClient(mainProcessService.getChannel('logger'));
this.logService = new FollowerLogService(loggerClient, logService);
const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
const sharedProcess = mainProcessService.getChannel('sharedProcess').call('whenSharedProcessReady')
.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${configuration.windowId}`));
const instantiationService = new InstantiationService(serviceCollection, true);

View File

@@ -51,7 +51,7 @@ import { IFileService } from 'vs/platform/files/common/files';
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
import { Schemas } from 'vs/base/common/network';
import { IProductService } from 'vs/platform/product/common/productService';
import { IUserDataSyncService, IUserDataSyncStoreService, ISettingsMergeService } from 'vs/platform/userDataSync/common/userDataSync';
import { IUserDataSyncService, IUserDataSyncStoreService, ISettingsMergeService, registerConfiguration } from 'vs/platform/userDataSync/common/userDataSync';
import { UserDataSyncService, UserDataAutoSync } from 'vs/platform/userDataSync/common/userDataSyncService';
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
@@ -122,11 +122,6 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
const windowsService = new WindowsService(mainProcessService);
services.set(IWindowsService, windowsService);
const activeWindowManager = new ActiveWindowManager(windowsService);
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
const settingsMergeChannel = server.getChannel('settingsMerge', activeWindowRouter);
services.set(ISettingsMergeService, new SettingsMergeChannelClient(settingsMergeChannel));
// Files
const fileService = new FileService(logService);
services.set(IFileService, fileService);
@@ -173,8 +168,15 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService));
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
// User Data Sync Contributions
const activeWindowManager = new ActiveWindowManager(windowsService);
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
const settingsMergeChannel = server.getChannel('settingsMerge', activeWindowRouter);
services.set(ISettingsMergeService, new SettingsMergeChannelClient(settingsMergeChannel));
services.set(IUserDataSyncStoreService, new SyncDescriptor(UserDataSyncStoreService));
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
registerConfiguration();
const instantiationService2 = instantiationService.createChild(services);

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor } from 'electron';
import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, protocol, powerMonitor, IpcMainEvent } from 'electron';
import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform';
import { WindowsManager } from 'vs/code/electron-main/windows';
import { IWindowsService, OpenContext, ActiveWindowManager, IURIToOpen } from 'vs/platform/windows/common/windows';
import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc';
import { WindowsService } from 'vs/platform/windows/electron-main/windowsService';
import { LegacyWindowsMainService } from 'vs/platform/windows/electron-main/legacyWindowsMainService';
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { getShellEnvironment } from 'vs/code/node/shellEnv';
import { IUpdateService } from 'vs/platform/update/common/update';
@@ -17,7 +17,7 @@ import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
import { Server, connect } from 'vs/base/parts/ipc/node/ipc.net';
import { SharedProcess } from 'vs/code/electron-main/sharedProcess';
import { LaunchMainService, LaunchChannel, ILaunchMainService } from 'vs/platform/launch/electron-main/launchService';
import { LaunchMainService, LaunchChannel, ILaunchMainService } from 'vs/platform/launch/electron-main/launchMainService';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
@@ -53,7 +53,6 @@ import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlLi
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
import { MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
import { RunOnceScheduler } from 'vs/base/common/async';
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
import { homedir } from 'os';
@@ -78,6 +77,7 @@ import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemPro
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
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';
export class CodeApplication extends Disposable {
@@ -125,7 +125,7 @@ export class CodeApplication extends Disposable {
// Mac only event: open new window when we get activated
if (!hasVisibleWindows && this.windowsMainService) {
this.windowsMainService.openNewWindow(OpenContext.DOCK);
this.windowsMainService.openEmptyWindow(OpenContext.DOCK);
}
});
@@ -165,8 +165,8 @@ export class CodeApplication extends Disposable {
event.preventDefault();
});
app.on('web-contents-created', (_event: Electron.Event, contents) => {
contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => {
app.on('web-contents-created', (_event: Event, contents) => {
contents.on('will-attach-webview', (event: Event, webPreferences, params) => {
const isValidWebviewSource = (source: string): boolean => {
if (!source) {
@@ -247,7 +247,7 @@ export class CodeApplication extends Disposable {
app.on('new-window-for-tab', () => {
if (this.windowsMainService) {
this.windowsMainService.openNewWindow(OpenContext.DESKTOP); //macOS native tab "+" button
this.windowsMainService.openEmptyWindow(OpenContext.DESKTOP); //macOS native tab "+" button
}
});
@@ -258,7 +258,7 @@ export class CodeApplication extends Disposable {
this.lifecycleMainService.kill(code);
});
ipc.on('vscode:fetchShellEnv', async (event: Electron.IpcMainEvent) => {
ipc.on('vscode:fetchShellEnv', async (event: IpcMainEvent) => {
const webContents = event.sender;
try {
@@ -275,10 +275,10 @@ export class CodeApplication extends Disposable {
}
});
ipc.on('vscode:toggleDevTools', (event: Electron.IpcMainEvent) => event.sender.toggleDevTools());
ipc.on('vscode:openDevTools', (event: Electron.IpcMainEvent) => event.sender.openDevTools());
ipc.on('vscode:toggleDevTools', (event: IpcMainEvent) => event.sender.toggleDevTools());
ipc.on('vscode:openDevTools', (event: IpcMainEvent) => event.sender.openDevTools());
ipc.on('vscode:reloadWindow', (event: Electron.IpcMainEvent) => event.sender.reload());
ipc.on('vscode:reloadWindow', (event: IpcMainEvent) => event.sender.reload());
// Some listeners after window opened
(async () => {
@@ -449,7 +449,8 @@ export class CodeApplication extends Disposable {
}
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));
services.set(IWindowsService, new SyncDescriptor(WindowsService, [sharedProcess]));
services.set(ISharedProcessMainService, new SyncDescriptor(SharedProcessMainService, [sharedProcess]));
services.set(IWindowsService, new SyncDescriptor(LegacyWindowsMainService));
services.set(ILaunchMainService, new SyncDescriptor(LaunchMainService));
const diagnosticsChannel = getDelayedChannel(sharedProcessClient.then(client => client.getChannel('diagnostics')));
@@ -546,8 +547,12 @@ export class CodeApplication extends Disposable {
const electronChannel = new SimpleServiceProxyChannel(electronService);
electronIpcServer.registerChannel('electron', electronChannel);
const sharedProcessMainService = accessor.get(ISharedProcessMainService);
const sharedProcessChannel = new SimpleServiceProxyChannel(sharedProcessMainService);
electronIpcServer.registerChannel('sharedProcess', sharedProcessChannel);
const workspacesMainService = accessor.get(IWorkspacesMainService);
const workspacesChannel = new WorkspacesChannel(workspacesMainService);
const workspacesChannel = new WorkspacesChannel(workspacesMainService, accessor.get(IWindowsMainService));
electronIpcServer.registerChannel('workspaces', workspacesChannel);
const windowsService = accessor.get(IWindowsService);
@@ -556,7 +561,7 @@ export class CodeApplication extends Disposable {
sharedProcessClient.then(client => client.registerChannel('windows', windowsChannel));
const menubarService = accessor.get(IMenubarService);
const menubarChannel = new MenubarChannel(menubarService);
const menubarChannel = new SimpleServiceProxyChannel(menubarService);
electronIpcServer.registerChannel('menubar', menubarChannel);
const urlService = accessor.get(IURLService);

View File

@@ -7,13 +7,13 @@ import { localize } from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { Event } from 'vs/base/common/event';
import { BrowserWindow, app } from 'electron';
import { BrowserWindow, app, AuthInfo, WebContents, Event as ElectronEvent } from 'electron';
type LoginEvent = {
event: Electron.Event;
webContents: Electron.WebContents;
req: Electron.Request;
authInfo: Electron.AuthInfo;
event: ElectronEvent;
webContents: WebContents;
req: Request;
authInfo: AuthInfo;
cb: (username: string, password: string) => void;
};
@@ -93,4 +93,4 @@ export class ProxyAuthHandler {
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
}

View File

@@ -14,7 +14,7 @@ import { mkdirp } from 'vs/base/node/pfs';
import { validatePaths } from 'vs/code/node/paths';
import { LifecycleMainService, ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net';
import { LaunchChannelClient } from 'vs/platform/launch/electron-main/launchService';
import { LaunchChannelClient } from 'vs/platform/launch/electron-main/launchMainService';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';

View File

@@ -18,7 +18,7 @@ export class SharedProcess implements ISharedProcess {
private barrier = new Barrier();
private window: Electron.BrowserWindow | null = null;
private window: BrowserWindow | null = null;
constructor(
private readonly machineId: string,

View File

@@ -7,7 +7,7 @@ import * as path from 'vs/base/common/path';
import * as objects from 'vs/base/common/objects';
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display } from 'electron';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment } from 'electron';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -44,7 +44,7 @@ export const defaultWindowState = function (mode = WindowMode.Normal): IWindowSt
};
};
interface ITouchBarSegment extends Electron.SegmentedControlSegment {
interface ITouchBarSegment extends SegmentedControlSegment {
id: string;
}
@@ -58,7 +58,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private hiddenTitleBarStyle: boolean;
private showTimeoutHandle: NodeJS.Timeout;
private _id: number;
private _win: Electron.BrowserWindow;
private _win: BrowserWindow;
private _lastFocusTime: number;
private _readyState: ReadyState;
private windowState: IWindowState;
@@ -72,7 +72,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private marketplaceHeadersPromise: Promise<object>;
private readonly touchBarGroups: Electron.TouchBarSegmentedControl[];
private readonly touchBarGroups: TouchBarSegmentedControl[];
constructor(
config: IWindowCreationOptions,
@@ -116,7 +116,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// in case we are maximized or fullscreen, only show later after the call to maximize/fullscreen (see below)
const isFullscreenOrMaximized = (this.windowState.mode === WindowMode.Maximized || this.windowState.mode === WindowMode.Fullscreen);
const options: Electron.BrowserWindowConstructorOptions = {
const options: BrowserWindowConstructorOptions = {
width: this.windowState.width,
height: this.windowState.height,
x: this.windowState.x,
@@ -231,7 +231,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
return this._id;
}
get win(): Electron.BrowserWindow {
get win(): BrowserWindow {
return this._win;
}
@@ -421,7 +421,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
});
// Window Failed to load
this._win.webContents.on('did-fail-load', (event: Electron.Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean) => {
this._win.webContents.on('did-fail-load', (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean) => {
this.logService.warn('[electron event]: fail to load, ', errorDescription);
});
@@ -653,7 +653,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// only consider non-minimized window states
if (mode === WindowMode.Normal || mode === WindowMode.Maximized) {
let bounds: Electron.Rectangle;
let bounds: Rectangle;
if (mode === WindowMode.Normal) {
bounds = this.getBounds();
} else {
@@ -778,7 +778,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
return undefined;
}
getBounds(): Electron.Rectangle {
getBounds(): Rectangle {
const pos = this._win.getPosition();
const dimension = this._win.getSize();
@@ -908,7 +908,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
}
}
onWindowTitleDoubleClick(): void {
handleTitleDoubleClick(): void {
// Respect system settings on mac with regards to title click on windows title
if (isMacintosh) {
@@ -988,7 +988,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this._win.setTouchBar(new TouchBar({ items: this.touchBarGroups }));
}
private createTouchBarGroup(items: ISerializableCommandAction[] = []): Electron.TouchBarSegmentedControl {
private createTouchBarGroup(items: ISerializableCommandAction[] = []): TouchBarSegmentedControl {
// Group Segments
const segments = this.createTouchBarGroupSegments(items);
@@ -1008,7 +1008,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private createTouchBarGroupSegments(items: ISerializableCommandAction[] = []): ITouchBarSegment[] {
const segments: ITouchBarSegment[] = items.map(item => {
let icon: Electron.NativeImage | undefined;
let icon: NativeImage | undefined;
if (item.iconLocation && item.iconLocation.dark.scheme === 'file') {
icon = nativeImage.createFromPath(URI.revive(item.iconLocation.dark).fsPath);
if (icon.isEmpty()) {

View File

@@ -13,12 +13,12 @@ import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { IStateService } from 'vs/platform/state/common/state';
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter, shell, MessageBoxReturnValue, MessageBoxOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, 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';
import { ILogService } from 'vs/platform/log/common/log';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, IEnterWorkspaceResult, IMessageBoxResult, INewWindowOptions, IURIToOpen, isFileToOpen, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, IEnterWorkspaceResult, IURIToOpen, isFileToOpen, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri } from 'vs/code/node/windowsFinder';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import product from 'vs/platform/product/common/product';
@@ -197,9 +197,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
const windowsStateStoreData = this.stateService.getItem<WindowsStateStorageData>(WindowsManager.windowsStateStorageKey);
this.windowsState = restoreWindowsState(windowsStateStoreData);
this.windowsState = restoreWindowsState(this.stateService.getItem<WindowsStateStorageData>(WindowsManager.windowsStateStorageKey));
if (!Array.isArray(this.windowsState.openedWindows)) {
this.windowsState.openedWindows = [];
}
@@ -227,7 +226,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
private registerListeners(): void {
// React to workbench ready events from windows
ipc.on('vscode:workbenchReady', (event: Electron.Event, windowId: number) => {
ipc.on('vscode:workbenchReady', (event: Event, windowId: number) => {
this.logService.trace('IPC#vscode-workbenchReady');
const win = this.getWindowById(windowId);
@@ -381,6 +380,12 @@ 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);
@@ -867,7 +872,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
message = localize('uriInvalidTitle', "URI can not be opened");
detail = localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString());
}
const options: Electron.MessageBoxOptions = {
const options: MessageBoxOptions = {
title: product.nameLong,
type: 'info',
buttons: [localize('ok', "OK")],
@@ -1468,7 +1473,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
//
// We want the new window to open on the same display that the last active one is in
let displayToUse: Electron.Display | undefined;
let displayToUse: Display | undefined;
const displays = screen.getAllDisplays();
// Single Display
@@ -1605,13 +1610,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return getLastActiveWindow(WindowsManager.WINDOWS.filter(window => window.remoteAuthority === remoteAuthority));
}
openNewWindow(context: OpenContext, options?: INewWindowOptions): ICodeWindow[] {
openEmptyWindow(context: OpenContext, options?: { reuse?: boolean, remoteAuthority?: string }): ICodeWindow[] {
let cli = this.environmentService.args;
const remote = options && options.remoteAuthority || undefined;
const remote = options && options.remoteAuthority;
if (cli && (cli.remote !== remote)) {
cli = { ...cli, remote };
}
const forceReuseWindow = options && options.reuseWindow;
const forceReuseWindow = options && options.reuse;
const forceNewWindow = !forceReuseWindow;
return this.open({ context, cli, forceEmpty: true, forceNewWindow, forceReuseWindow });
}
@@ -1665,11 +1670,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
getWindowById(windowId: number): ICodeWindow | undefined {
const res = WindowsManager.WINDOWS.filter(window => window.id === windowId);
if (res && res.length === 1) {
return res[0];
}
return undefined;
return arrays.firstOrDefault(res);
}
getWindows(): ICodeWindow[] {
@@ -1714,9 +1715,9 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return; // Return early if the window has been going down already
}
if (result.button === 0) {
if (result.response === 0) {
window.reload();
} else if (result.button === 2) {
} else if (result.response === 2) {
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
window.win.destroy(); // make sure to destroy the window as it is unresponsive
}
@@ -1737,9 +1738,9 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return; // Return early if the window has been going down already
}
if (result.button === 0) {
if (result.response === 0) {
window.reload();
} else if (result.button === 1) {
} else if (result.response === 1) {
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
window.win.destroy(); // make sure to destroy the window as it has crashed
}
@@ -1761,7 +1762,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
this._onWindowClose.fire(win.id);
}
async pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
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 });
if (paths) {
@@ -1773,7 +1774,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}));
this.open({
context: OpenContext.DIALOG,
contextWindowId: options.windowId,
contextWindowId: win ? win.id : undefined,
cli: this.environmentService.args,
urisToOpen,
forceNewWindow: options.forceNewWindow
@@ -1781,14 +1782,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}
}
async pickFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
async pickFolderAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
const title = localize('openFolder', "Open Folder");
const paths = await this.dialogs.pick({ ...options, pickFolders: true, title });
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFolder', options.telemetryExtraData);
this.open({
context: OpenContext.DIALOG,
contextWindowId: options.windowId,
contextWindowId: win ? win.id : undefined,
cli: this.environmentService.args,
urisToOpen: paths.map(path => ({ folderUri: URI.file(path) })),
forceNewWindow: options.forceNewWindow
@@ -1796,14 +1797,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}
}
async pickFileAndOpen(options: INativeOpenDialogOptions): Promise<void> {
async pickFileAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
const title = localize('openFile', "Open File");
const paths = await this.dialogs.pick({ ...options, pickFiles: true, title });
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFile', options.telemetryExtraData);
this.open({
context: OpenContext.DIALOG,
contextWindowId: options.windowId,
contextWindowId: win ? win.id : undefined,
cli: this.environmentService.args,
urisToOpen: paths.map(path => ({ fileUri: URI.file(path) })),
forceNewWindow: options.forceNewWindow
@@ -1811,7 +1812,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}
}
async pickWorkspaceAndOpen(options: INativeOpenDialogOptions): Promise<void> {
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;
@@ -1820,7 +1821,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openWorkspace', options.telemetryExtraData);
this.open({
context: OpenContext.DIALOG,
contextWindowId: options.windowId,
contextWindowId: win ? win.id : undefined,
cli: this.environmentService.args,
urisToOpen: paths.map(path => ({ workspaceUri: URI.file(path) })),
forceNewWindow: options.forceNewWindow
@@ -1842,15 +1843,15 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
});
}
showMessageBox(options: Electron.MessageBoxOptions, win?: ICodeWindow): Promise<IMessageBoxResult> {
showMessageBox(options: MessageBoxOptions, win?: ICodeWindow): Promise<MessageBoxReturnValue> {
return this.dialogs.showMessageBox(options, win);
}
showSaveDialog(options: Electron.SaveDialogOptions, win?: ICodeWindow): Promise<string> {
showSaveDialog(options: SaveDialogOptions, win?: ICodeWindow): Promise<SaveDialogReturnValue> {
return this.dialogs.showSaveDialog(options, win);
}
showOpenDialog(options: Electron.OpenDialogOptions, win?: ICodeWindow): Promise<string[]> {
showOpenDialog(options: OpenDialogOptions, win?: ICodeWindow): Promise<OpenDialogReturnValue> {
return this.dialogs.showOpenDialog(options, win);
}
@@ -1897,10 +1898,10 @@ class Dialogs {
this.noWindowDialogQueue = new Queue<void>();
}
async pick(options: IInternalNativeOpenDialogOptions): Promise<string[] | undefined> {
async pick(options: IInternalNativeOpenDialogOptions, win?: ICodeWindow): Promise<string[] | undefined> {
// Ensure dialog options
const dialogOptions: Electron.OpenDialogOptions = {
const dialogOptions: OpenDialogOptions = {
title: options.title,
buttonLabel: options.buttonLabel,
filters: options.filters
@@ -1928,15 +1929,15 @@ class Dialogs {
}
// Show Dialog
const focusedWindow = (typeof options.windowId === 'number' ? this.windowsMainService.getWindowById(options.windowId) : undefined) || this.windowsMainService.getFocusedWindow();
const windowToUse = win || this.windowsMainService.getFocusedWindow();
const paths = await this.showOpenDialog(dialogOptions, focusedWindow);
if (paths && paths.length > 0) {
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(paths[0]));
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(result.filePaths[0]));
return paths;
return result.filePaths;
}
return undefined; // {{SQL CARBON EDIT}} @anthonydresser strict-null-check
@@ -1956,20 +1957,17 @@ class Dialogs {
return windowDialogQueue;
}
showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): Promise<IMessageBoxResult> {
showMessageBox(options: MessageBoxOptions, window?: ICodeWindow): Promise<MessageBoxReturnValue> {
return this.getDialogQueue(window).queue(async () => {
let result: Electron.MessageBoxReturnValue;
if (window) {
result = await dialog.showMessageBox(window.win, options);
} else {
result = await dialog.showMessageBox(options);
return dialog.showMessageBox(window.win, options);
}
return { button: result.response, checkboxChecked: result.checkboxChecked };
return dialog.showMessageBox(options);
});
}
showSaveDialog(options: Electron.SaveDialogOptions, window?: ICodeWindow): Promise<string> {
showSaveDialog(options: SaveDialogOptions, window?: ICodeWindow): Promise<SaveDialogReturnValue> {
function normalizePath(path: string | undefined): string | undefined {
if (path && isMacintosh) {
@@ -1980,18 +1978,20 @@ class Dialogs {
}
return this.getDialogQueue(window).queue(async () => {
let result: Electron.SaveDialogReturnValue;
let result: SaveDialogReturnValue;
if (window) {
result = await dialog.showSaveDialog(window.win, options);
} else {
result = await dialog.showSaveDialog(options);
}
return normalizePath(result.filePath);
result.filePath = normalizePath(result.filePath);
return result;
});
}
showOpenDialog(options: Electron.OpenDialogOptions, window?: ICodeWindow): Promise<string[]> {
showOpenDialog(options: OpenDialogOptions, window?: ICodeWindow): Promise<OpenDialogReturnValue> {
function normalizePaths(paths: string[] | undefined): string[] | undefined {
if (paths && paths.length > 0 && isMacintosh) {
@@ -2012,14 +2012,16 @@ class Dialogs {
}
// Show dialog
let result: Electron.OpenDialogReturnValue;
let result: OpenDialogReturnValue;
if (window) {
result = await dialog.showOpenDialog(window.win, options);
} else {
result = await dialog.showOpenDialog(options);
}
return normalizePaths(result.filePaths);
result.filePaths = normalizePaths(result.filePaths);
return result;
});
}
}
@@ -2056,7 +2058,7 @@ class WorkspacesManager {
// Prevent overwriting a workspace that is currently opened in another window
if (findWindowOnWorkspace(this.windowsMainService.getWindows(), getWorkspaceIdentifier(path))) {
const options: Electron.MessageBoxOptions = {
const options: MessageBoxOptions = {
title: product.nameLong,
type: 'info',
buttons: [localize('ok', "OK")],