diff options
Diffstat (limited to 'src/vs/code/electron-main/app.ts')
-rw-r--r-- | src/vs/code/electron-main/app.ts | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 5d6b367dca0..169ba778fe1 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { app, BrowserWindow, contentTracing, dialog, ipcMain, protocol, session, Session, systemPreferences, WebFrameMain } from 'electron'; +import { app, BrowserWindow, contentTracing, dialog, protocol, session, Session, systemPreferences, WebFrameMain } from 'electron'; +import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain'; import { statSync } from 'fs'; import { hostname, release } from 'os'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -16,7 +17,7 @@ import { getPathLabel, mnemonicButtonLabel } from 'vs/base/common/labels'; import { Disposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { isAbsolute, join, posix } from 'vs/base/common/path'; -import { IProcessEnvironment, isLinux, isLinuxSnap, isMacintosh, isWindows } from 'vs/base/common/platform'; +import { IProcessEnvironment, isLinux, isLinuxSnap, isMacintosh, isWindows, OS } from 'vs/base/common/platform'; import { assertType, withNullAsUndefined } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; @@ -36,7 +37,6 @@ import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/el import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnostics'; import { DiagnosticsMainService, IDiagnosticsMainService } from 'vs/platform/diagnostics/electron-main/diagnosticsMainService'; import { DialogMainService, IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; -import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { IEncryptionMainService } from 'vs/platform/encryption/common/encryptionService'; import { EncryptionMainService } from 'vs/platform/encryption/node/encryptionMainService'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; @@ -380,7 +380,7 @@ export class CodeApplication extends Disposable { //#region Bootstrap IPC Handlers - ipcMain.handle('vscode:fetchShellEnv', event => { + validatedIpcMain.handle('vscode:fetchShellEnv', event => { // Prefer to use the args and env from the target window // when resolving the shell env. It is possible that @@ -405,7 +405,7 @@ export class CodeApplication extends Disposable { return this.resolveShellEnvironment(args, env, false); }); - ipcMain.handle('vscode:writeNlsFile', (event, path: unknown, data: unknown) => { + validatedIpcMain.handle('vscode:writeNlsFile', (event, path: unknown, data: unknown) => { const uri = this.validateNlsPath([path]); if (!uri || typeof data !== 'string') { throw new Error('Invalid operation (vscode:writeNlsFile)'); @@ -414,7 +414,7 @@ export class CodeApplication extends Disposable { return this.fileService.writeFile(uri, VSBuffer.fromString(data)); }); - ipcMain.handle('vscode:readNlsFile', async (event, ...paths: unknown[]) => { + validatedIpcMain.handle('vscode:readNlsFile', async (event, ...paths: unknown[]) => { const uri = this.validateNlsPath(paths); if (!uri) { throw new Error('Invalid operation (vscode:readNlsFile)'); @@ -423,10 +423,10 @@ export class CodeApplication extends Disposable { return (await this.fileService.readFile(uri)).value.toString(); }); - ipcMain.on('vscode:toggleDevTools', event => event.sender.toggleDevTools()); - ipcMain.on('vscode:openDevTools', event => event.sender.openDevTools()); + validatedIpcMain.on('vscode:toggleDevTools', event => event.sender.toggleDevTools()); + validatedIpcMain.on('vscode:openDevTools', event => event.sender.openDevTools()); - ipcMain.on('vscode:reloadWindow', event => event.sender.reload()); + validatedIpcMain.on('vscode:reloadWindow', event => event.sender.reload()); //#endregion } @@ -522,14 +522,6 @@ export class CodeApplication extends Disposable { // Services const appInstantiationService = await this.initServices(machineId, sharedProcess, sharedProcessReady); - // Create driver - if (this.environmentMainService.driverHandle) { - const server = await serveDriver(mainProcessElectronServer, this.environmentMainService.driverHandle, appInstantiationService); - - this.logService.info('Driver started at:', this.environmentMainService.driverHandle); - this._register(server); - } - // Setup Auth Handler this._register(appInstantiationService.createInstance(ProxyAuthHandler)); @@ -859,6 +851,19 @@ export class CodeApplication extends Disposable { return true; } + let shouldOpenInNewWindow = false; + + // We should handle the URI in a new window if the URL contains `windowId=_blank` + const params = new URLSearchParams(uri.query); + if (params.get('windowId') === '_blank') { + params.delete('windowId'); + uri = uri.with({ query: params.toString() }); + shouldOpenInNewWindow = true; + } + + // or if no window is open (macOS only) + shouldOpenInNewWindow ||= isMacintosh && windowsMainService.getWindowCount() === 0; + // Check for URIs to open in window const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri); logService.trace('app#handleURL: windowOpenableFromProtocolLink = ', windowOpenableFromProtocolLink); @@ -867,6 +872,7 @@ export class CodeApplication extends Disposable { context: OpenContext.API, cli: { ...environmentService.args }, urisToOpen: [windowOpenableFromProtocolLink], + forceNewWindow: shouldOpenInNewWindow, gotoLineMode: true // remoteAuthority: will be determined based on windowOpenableFromProtocolLink }); @@ -876,12 +882,11 @@ export class CodeApplication extends Disposable { return true; } - // If we have not yet handled the URI and we have no window opened (macOS only) - // we first open a window and then try to open that URI within that window - if (isMacintosh && windowsMainService.getWindowCount() === 0) { + if (shouldOpenInNewWindow) { const [window] = windowsMainService.open({ context: OpenContext.API, cli: { ...environmentService.args }, + forceNewWindow: true, forceEmpty: true, gotoLineMode: true, remoteAuthority: getRemoteAuthority(uri) @@ -987,7 +992,7 @@ export class CodeApplication extends Disposable { ], defaultId: 0, cancelId: 1, - message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri.fsPath, this.environmentMainService), this.productService.nameShort), + message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri, { os: OS, tildify: this.environmentMainService }), this.productService.nameShort), detail: localize('confirmOpenDetail', "If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"), noLink: true }); @@ -1088,11 +1093,14 @@ export class CodeApplication extends Disposable { // Telemetry type SharedProcessErrorClassification = { - type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; owner: 'bpasero'; comment: 'The type of shared process crash to understand the nature of the crash better.' }; - reason: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; owner: 'bpasero'; comment: 'The type of shared process crash to understand the nature of the crash better.' }; - code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; owner: 'bpasero'; comment: 'The type of shared process crash to understand the nature of the crash better.' }; - visible: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; owner: 'bpasero'; comment: 'Whether shared process window was visible or not.' }; - shuttingdown: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; owner: 'bpasero'; comment: 'Whether the application is shutting down when the crash happens.' }; + type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of shared process crash to understand the nature of the crash better.' }; + reason: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of shared process crash to understand the nature of the crash better.' }; + code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of shared process crash to understand the nature of the crash better.' }; + visible: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether shared process window was visible or not.' }; + shuttingdown: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether the application is shutting down when the crash happens.' }; + owner: 'bpaser'; + comment: 'Event which fires whenever an error occurs in the shared process'; + }; type SharedProcessErrorEvent = { type: WindowError; @@ -1133,7 +1141,7 @@ export class CodeApplication extends Disposable { // Initialize update service const updateService = accessor.get(IUpdateService); if (updateService instanceof Win32UpdateService || updateService instanceof LinuxUpdateService || updateService instanceof DarwinUpdateService) { - updateService.initialize(); + await updateService.initialize(); } // Start to fetch shell environment (if needed) after window has opened |