Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998 (#7880)

* Merge from vscode c58aaab8a1cc22a7139b761166a0d4f37d41e998

* fix pipelines

* fix strict-null-checks

* add missing files
This commit is contained in:
Anthony Dresser
2019-10-21 22:12:22 -07:00
committed by GitHub
parent 7c9be74970
commit 1e22f47304
913 changed files with 18898 additions and 16536 deletions

View File

@@ -4,20 +4,29 @@
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { MessageBoxOptions, shell, OpenDevToolsOptions, SaveDialogOptions, OpenDialogOptions, CrashReporterStartOptions, crashReporter, Menu, BrowserWindow, app } from 'electron';
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
import { MessageBoxOptions, MessageBoxReturnValue, shell, OpenDevToolsOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, CrashReporterStartOptions, crashReporter, Menu, BrowserWindow, app } from 'electron';
import { INativeOpenWindowOptions } from 'vs/platform/windows/node/window';
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { IOpenedWindow, OpenContext, IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { INativeOpenDialogOptions, MessageBoxReturnValue, SaveDialogReturnValue, OpenDialogReturnValue } from 'vs/platform/dialogs/node/dialogs';
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/node/dialogs';
import { isMacintosh, IProcessEnvironment } from 'vs/base/common/platform';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { AddFirstParameterToFunctions } from 'vs/base/common/types';
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
import { dirExists } from 'vs/base/node/pfs';
import { URI } from 'vs/base/common/uri';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import { ITelemetryData, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export class ElectronMainService implements AddFirstParameterToFunctions<IElectronService, Promise<any> /* only methods, not events */, number /* window ID */> {
export interface IElectronMainService extends AddFirstParameterToFunctions<IElectronService, Promise<any> /* only methods, not events */, number | undefined /* window ID */> { }
export const IElectronMainService = createDecorator<IElectronService>('electronMainService');
export class ElectronMainService implements IElectronMainService {
_serviceBrand: undefined;
@@ -25,7 +34,8 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
@IDialogMainService private readonly dialogMainService: IDialogMainService,
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
@IEnvironmentService private readonly environmentService: IEnvironmentService
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@ITelemetryService private readonly telemetryService: ITelemetryService
) {
}
@@ -58,11 +68,11 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
}));
}
async getWindowCount(windowId: number): Promise<number> {
async getWindowCount(windowId: number | undefined): Promise<number> {
return this.windowsMainService.getWindowCount();
}
async getActiveWindowId(windowId: number): Promise<number | undefined> {
async getActiveWindowId(windowId: number | undefined): Promise<number | undefined> {
const activeWindow = BrowserWindow.getFocusedWindow() || this.windowsMainService.getLastActiveWindow();
if (activeWindow) {
return activeWindow.id;
@@ -71,9 +81,9 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
return undefined;
}
openWindow(windowId: number, options?: IOpenEmptyWindowOptions): Promise<void>;
openWindow(windowId: number, toOpen: IWindowOpenable[], options?: INativeOpenWindowOptions): Promise<void>;
openWindow(windowId: number, arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: INativeOpenWindowOptions): Promise<void> {
openWindow(windowId: number | undefined, options?: IOpenEmptyWindowOptions): Promise<void>;
openWindow(windowId: number | undefined, toOpen: IWindowOpenable[], options?: INativeOpenWindowOptions): Promise<void>;
openWindow(windowId: number | undefined, arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: INativeOpenWindowOptions): Promise<void> {
if (Array.isArray(arg1)) {
return this.doOpenWindow(windowId, arg1, arg2);
}
@@ -81,7 +91,7 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
return this.doOpenEmptyWindow(windowId, arg1);
}
private async doOpenWindow(windowId: number, toOpen: IWindowOpenable[], options: INativeOpenWindowOptions = Object.create(null)): Promise<void> {
private async doOpenWindow(windowId: number | undefined, toOpen: IWindowOpenable[], options: INativeOpenWindowOptions = Object.create(null)): Promise<void> {
if (toOpen.length > 0) {
this.windowsMainService.open({
context: OpenContext.API,
@@ -99,26 +109,26 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
}
}
private async doOpenEmptyWindow(windowId: number, options?: IOpenEmptyWindowOptions): Promise<void> {
private async doOpenEmptyWindow(windowId: number | undefined, options?: IOpenEmptyWindowOptions): Promise<void> {
this.windowsMainService.openEmptyWindow(OpenContext.API, options);
}
async toggleFullScreen(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async toggleFullScreen(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.toggleFullScreen();
}
}
async handleTitleDoubleClick(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async handleTitleDoubleClick(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.handleTitleDoubleClick();
}
}
async isMaximized(windowId: number): Promise<boolean> {
const window = this.windowsMainService.getWindowById(windowId);
async isMaximized(windowId: number | undefined): Promise<boolean> {
const window = this.windowById(windowId);
if (window) {
return window.win.isMaximized();
}
@@ -126,29 +136,29 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
return false;
}
async maximizeWindow(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async maximizeWindow(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.win.maximize();
}
}
async unmaximizeWindow(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async unmaximizeWindow(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.win.unmaximize();
}
}
async minimizeWindow(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async minimizeWindow(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.win.minimize();
}
}
async isWindowFocused(windowId: number): Promise<boolean> {
const window = this.windowsMainService.getWindowById(windowId);
async isWindowFocused(windowId: number | undefined): Promise<boolean> {
const window = this.windowById(windowId);
if (window) {
return window.win.isFocused();
}
@@ -156,12 +166,12 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
return false;
}
async focusWindow(windowId: number, options?: { windowId?: number; }): Promise<void> {
async focusWindow(windowId: number | undefined, options?: { windowId?: number; }): Promise<void> {
if (options && typeof options.windowId === 'number') {
windowId = options.windowId;
}
const window = this.windowsMainService.getWindowById(windowId);
const window = this.windowById(windowId);
if (window) {
if (isMacintosh) {
window.win.show();
@@ -175,20 +185,20 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
//#region Dialog
async showMessageBox(windowId: number, options: MessageBoxOptions): Promise<MessageBoxReturnValue> {
async showMessageBox(windowId: number | undefined, options: MessageBoxOptions): Promise<MessageBoxReturnValue> {
return this.dialogMainService.showMessageBox(options, this.toBrowserWindow(windowId));
}
async showSaveDialog(windowId: number, options: SaveDialogOptions): Promise<SaveDialogReturnValue> {
async showSaveDialog(windowId: number | undefined, options: SaveDialogOptions): Promise<SaveDialogReturnValue> {
return this.dialogMainService.showSaveDialog(options, this.toBrowserWindow(windowId));
}
async showOpenDialog(windowId: number, options: OpenDialogOptions): Promise<OpenDialogReturnValue> {
async showOpenDialog(windowId: number | undefined, options: OpenDialogOptions): Promise<OpenDialogReturnValue> {
return this.dialogMainService.showOpenDialog(options, this.toBrowserWindow(windowId));
}
private toBrowserWindow(windowId: number): BrowserWindow | undefined {
const window = this.windowsMainService.getWindowById(windowId);
private toBrowserWindow(windowId: number | undefined): BrowserWindow | undefined {
const window = this.windowById(windowId);
if (window) {
return window.win;
}
@@ -196,52 +206,90 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
return undefined;
}
async pickFileFolderAndOpen(windowId: number, options: INativeOpenDialogOptions): Promise<void> {
return this.windowsMainService.pickFileFolderAndOpen(options, this.windowsMainService.getWindowById(windowId));
async pickFileFolderAndOpen(windowId: number | undefined, options: INativeOpenDialogOptions): Promise<void> {
const paths = await this.dialogMainService.pickFileFolder(options);
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFileFolder', options.telemetryExtraData);
this.doOpenPicked(await Promise.all(paths.map(async path => (await dirExists(path)) ? { folderUri: URI.file(path) } : { fileUri: URI.file(path) })), options, windowId);
}
}
async pickFileAndOpen(windowId: number, options: INativeOpenDialogOptions): Promise<void> {
return this.windowsMainService.pickFileAndOpen(options, this.windowsMainService.getWindowById(windowId));
async pickFolderAndOpen(windowId: number | undefined, options: INativeOpenDialogOptions): Promise<void> {
const paths = await this.dialogMainService.pickFolder(options);
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFolder', options.telemetryExtraData);
this.doOpenPicked(paths.map(path => ({ folderUri: URI.file(path) })), options, windowId);
}
}
async pickFolderAndOpen(windowId: number, options: INativeOpenDialogOptions): Promise<void> {
return this.windowsMainService.pickFolderAndOpen(options, this.windowsMainService.getWindowById(windowId));
async pickFileAndOpen(windowId: number | undefined, options: INativeOpenDialogOptions): Promise<void> {
const paths = await this.dialogMainService.pickFile(options);
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFile', options.telemetryExtraData);
this.doOpenPicked(paths.map(path => ({ fileUri: URI.file(path) })), options, windowId);
}
}
async pickWorkspaceAndOpen(windowId: number, options: INativeOpenDialogOptions): Promise<void> {
return this.windowsMainService.pickWorkspaceAndOpen(options, this.windowsMainService.getWindowById(windowId));
async pickWorkspaceAndOpen(windowId: number | undefined, options: INativeOpenDialogOptions): Promise<void> {
const paths = await this.dialogMainService.pickWorkspace(options);
if (paths) {
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openWorkspace', options.telemetryExtraData);
this.doOpenPicked(paths.map(path => ({ workspaceUri: URI.file(path) })), options, windowId);
}
}
private doOpenPicked(openable: IWindowOpenable[], options: INativeOpenDialogOptions, windowId: number | undefined): void {
this.windowsMainService.open({
context: OpenContext.DIALOG,
contextWindowId: windowId,
cli: this.environmentService.args,
urisToOpen: openable,
forceNewWindow: options.forceNewWindow
});
}
private sendPickerTelemetry(paths: string[], telemetryEventName: string, telemetryExtraData?: ITelemetryData) {
const numberOfPaths = paths ? paths.length : 0;
// Telemetry
// __GDPR__TODO__ Dynamic event names and dynamic properties. Can not be registered statically.
this.telemetryService.publicLog(telemetryEventName, {
...telemetryExtraData,
outcome: numberOfPaths ? 'success' : 'canceled',
numberOfPaths
});
}
//#endregion
//#region OS
async showItemInFolder(windowId: number, path: string): Promise<void> {
async showItemInFolder(windowId: number | undefined, path: string): Promise<void> {
shell.showItemInFolder(path);
}
async setRepresentedFilename(windowId: number, path: string): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async setRepresentedFilename(windowId: number | undefined, path: string): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.setRepresentedFilename(path);
}
}
async setDocumentEdited(windowId: number, edited: boolean): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async setDocumentEdited(windowId: number | undefined, edited: boolean): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.win.setDocumentEdited(edited);
}
}
async openExternal(windowId: number, url: string): Promise<boolean> {
async openExternal(windowId: number | undefined, url: string): Promise<boolean> {
shell.openExternal(url);
return true;
}
async updateTouchBar(windowId: number, items: ISerializableCommandAction[][]): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async updateTouchBar(windowId: number | undefined, items: ISerializableCommandAction[][]): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.updateTouchBar(items);
}
@@ -279,44 +327,51 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
//#region Lifecycle
async relaunch(windowId: number, options?: { addArgs?: string[], removeArgs?: string[] }): Promise<void> {
async relaunch(windowId: number | undefined, options?: { addArgs?: string[], removeArgs?: string[] }): Promise<void> {
return this.lifecycleMainService.relaunch(options);
}
async reload(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async reload(windowId: number | undefined, options?: { disableExtensions?: boolean }): Promise<void> {
const window = this.windowById(windowId);
if (window) {
return this.windowsMainService.reload(window);
return this.lifecycleMainService.reload(window, options?.disableExtensions ? { _: [], 'disable-extensions': true } : undefined);
}
}
async closeWorkspace(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
if (window) {
return this.windowsMainService.closeWorkspace(window);
}
}
async closeWindow(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async closeWindow(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
return window.win.close();
}
}
async quit(windowId: number): Promise<void> {
return this.windowsMainService.quit();
async quit(windowId: number | undefined): Promise<void> {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const window = this.windowsMainService.getLastActiveWindow();
if (window?.isExtensionDevelopmentHost && this.windowsMainService.getWindowCount() > 1) {
window.win.close();
}
// Otherwise: normal quit
else {
setTimeout(() => {
this.lifecycleMainService.quit();
}, 10 /* delay to unwind callback stack (IPC) */);
}
}
//#endregion
//#region Connectivity
async resolveProxy(windowId: number, url: string): Promise<string | undefined> {
async resolveProxy(windowId: number | undefined, url: string): Promise<string | undefined> {
return new Promise(resolve => {
const window = this.windowsMainService.getWindowById(windowId);
if (window && window.win && window.win.webContents && window.win.webContents.session) {
window.win.webContents.session.resolveProxy(url, proxy => resolve(proxy));
const window = this.windowById(windowId);
const session = window?.win?.webContents?.session;
if (session) {
session.resolveProxy(url, proxy => resolve(proxy));
} else {
resolve();
}
@@ -327,18 +382,18 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
//#region Development
async openDevTools(windowId: number, options?: OpenDevToolsOptions): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async openDevTools(windowId: number | undefined, options?: OpenDevToolsOptions): Promise<void> {
const window = this.windowById(windowId);
if (window) {
window.win.webContents.openDevTools(options);
}
}
async toggleDevTools(windowId: number): Promise<void> {
const window = this.windowsMainService.getWindowById(windowId);
async toggleDevTools(windowId: number | undefined): Promise<void> {
const window = this.windowById(windowId);
if (window) {
const contents = window.win.webContents;
if (isMacintosh && window.hasHiddenTitleBarStyle() && !window.isFullScreen() && !contents.isDevToolsOpened()) {
if (isMacintosh && window.hasHiddenTitleBarStyle && !window.isFullScreen && !contents.isDevToolsOpened()) {
contents.openDevTools({ mode: 'undocked' }); // due to https://github.com/electron/electron/issues/3647
} else {
contents.toggleDevTools();
@@ -346,7 +401,7 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
}
}
async startCrashReporter(windowId: number, options: CrashReporterStartOptions): Promise<void> {
async startCrashReporter(windowId: number | undefined, options: CrashReporterStartOptions): Promise<void> {
crashReporter.start(options);
}
@@ -356,16 +411,25 @@ export class ElectronMainService implements AddFirstParameterToFunctions<IElectr
// TODO@Isidor move into debug IPC channel (https://github.com/microsoft/vscode/issues/81060)
async openExtensionDevelopmentHostWindow(windowId: number, args: ParsedArgs, env: IProcessEnvironment): Promise<void> {
const extDevPaths = args.extensionDevelopmentPath;
async openExtensionDevelopmentHostWindow(windowId: number, args: string[], env: IProcessEnvironment): Promise<void> {
const pargs = parseArgs(args, OPTIONS);
const extDevPaths = pargs.extensionDevelopmentPath;
if (extDevPaths) {
this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
context: OpenContext.API,
cli: args,
cli: pargs,
userEnv: Object.keys(env).length > 0 ? env : undefined
});
}
}
//#endregion
private windowById(windowId: number | undefined): ICodeWindow | undefined {
if (typeof windowId !== 'number') {
return undefined;
}
return this.windowsMainService.getWindowById(windowId);
}
}