mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
debt - provide common method to load renderer with config param
This commit is contained in:
parent
19f6f31036
commit
e5b2742fff
|
@ -80,11 +80,8 @@ class CodeMain {
|
|||
// default electron error dialog popping up
|
||||
setUnexpectedErrorHandler(err => console.error(err));
|
||||
|
||||
// Resolve command line arguments
|
||||
const args = this.resolveArgs();
|
||||
|
||||
// Create services
|
||||
const [instantiationService, instanceEnvironment, environmentService, configurationService, stateService, bufferLogService, productService] = this.createServices(args);
|
||||
const [instantiationService, instanceEnvironment, environmentService, configurationService, stateService, bufferLogService, productService] = this.createServices();
|
||||
|
||||
try {
|
||||
|
||||
|
@ -108,7 +105,7 @@ class CodeMain {
|
|||
// Create the main IPC server by trying to be the server
|
||||
// If this throws an error it means we are not the first
|
||||
// instance of VS Code running and so we would quit.
|
||||
const mainProcessNodeIpcServer = await this.doStartup(args, logService, environmentService, lifecycleMainService, instantiationService, productService, true);
|
||||
const mainProcessNodeIpcServer = await this.doStartup(logService, environmentService, lifecycleMainService, instantiationService, productService, true);
|
||||
|
||||
// Delay creation of spdlog for perf reasons (https://github.com/microsoft/vscode/issues/72906)
|
||||
bufferLogService.logger = new SpdLogLogger('main', join(environmentService.logsPath, 'main.log'), true, bufferLogService.getLevel());
|
||||
|
@ -126,7 +123,7 @@ class CodeMain {
|
|||
}
|
||||
}
|
||||
|
||||
private createServices(args: NativeParsedArgs): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogService, IProductService] {
|
||||
private createServices(): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogService, IProductService] {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
// Product
|
||||
|
@ -134,7 +131,7 @@ class CodeMain {
|
|||
services.set(IProductService, productService);
|
||||
|
||||
// Environment
|
||||
const environmentMainService = new EnvironmentMainService(args, productService);
|
||||
const environmentMainService = new EnvironmentMainService(this.resolveArgs(), productService);
|
||||
const instanceEnvironment = this.patchEnvironment(environmentMainService); // Patch `process.env` with the instance's environment
|
||||
services.set(IEnvironmentMainService, environmentMainService);
|
||||
|
||||
|
@ -219,7 +216,7 @@ class CodeMain {
|
|||
return Promise.all([environmentServiceInitialization, configurationServiceInitialization, stateServiceInitialization]);
|
||||
}
|
||||
|
||||
private async doStartup(args: NativeParsedArgs, logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise<NodeIPCServer> {
|
||||
private async doStartup(logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise<NodeIPCServer> {
|
||||
|
||||
// Try to setup a server for running. If that succeeds it means
|
||||
// we are the first instance to startup. Otherwise it is likely
|
||||
|
@ -271,7 +268,7 @@ class CodeMain {
|
|||
throw error;
|
||||
}
|
||||
|
||||
return this.doStartup(args, logService, environmentMainService, lifecycleMainService, instantiationService, productService, false);
|
||||
return this.doStartup(logService, environmentMainService, lifecycleMainService, instantiationService, productService, false);
|
||||
}
|
||||
|
||||
// Tests from CLI require to be the only instance currently
|
||||
|
@ -287,7 +284,7 @@ class CodeMain {
|
|||
// Skip this if we are running with --wait where it is expected that we wait for a while.
|
||||
// Also skip when gathering diagnostics (--status) which can take a longer time.
|
||||
let startupWarningDialogHandle: NodeJS.Timeout | undefined = undefined;
|
||||
if (!args.wait && !args.status) {
|
||||
if (!environmentMainService.args.wait && !environmentMainService.args.status) {
|
||||
startupWarningDialogHandle = setTimeout(() => {
|
||||
this.showStartupWarningDialog(
|
||||
localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", productService.nameShort),
|
||||
|
@ -300,7 +297,7 @@ class CodeMain {
|
|||
const launchService = ProxyChannel.toService<ILaunchMainService>(client.getChannel('launch'), { disableMarshalling: true });
|
||||
|
||||
// Process Info
|
||||
if (args.status) {
|
||||
if (environmentMainService.args.status) {
|
||||
return instantiationService.invokeFunction(async () => {
|
||||
const diagnosticsService = new DiagnosticsService(NullTelemetryService, productService);
|
||||
const mainProcessInfo = await launchService.getMainProcessInfo();
|
||||
|
@ -319,7 +316,7 @@ class CodeMain {
|
|||
|
||||
// Send environment over...
|
||||
logService.trace('Sending env to running instance...');
|
||||
await launchService.start(args, process.env as IProcessEnvironment);
|
||||
await launchService.start(environmentMainService.args, process.env as IProcessEnvironment);
|
||||
|
||||
// Cleanup
|
||||
client.dispose();
|
||||
|
@ -333,7 +330,7 @@ class CodeMain {
|
|||
}
|
||||
|
||||
// Print --status usage info
|
||||
if (args.status) {
|
||||
if (environmentMainService.args.status) {
|
||||
logService.warn('Warning: The --status argument can only be used if Code is already running. Please run it again after Code has started.');
|
||||
|
||||
throw new ExpectedError('Terminating...');
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import * as os from 'os';
|
||||
import { arch, release, type } from 'os';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { ICommonIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue';
|
||||
import { BrowserWindow, ipcMain, screen, IpcMainEvent, Display } from 'electron';
|
||||
import { ILaunchMainService } from 'vs/platform/launch/electron-main/launchMainService';
|
||||
|
@ -14,7 +13,7 @@ import { IDiagnosticsService, PerformanceInfo, isRemoteDiagnosticError } from 'v
|
|||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { isMacintosh, IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWindowState, toWindowUrl } from 'vs/platform/windows/electron-main/windows';
|
||||
import { listProcesses } from 'vs/base/node/ps';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -280,7 +279,7 @@ export class IssueMainService implements ICommonIssueService {
|
|||
};
|
||||
|
||||
this._processExplorerWindow.loadURL(
|
||||
toWindowUrl('vs/code/electron-sandbox/processExplorer/processExplorer.html', windowConfiguration));
|
||||
toWindowUrl('vs/code/electron-sandbox/processExplorer/processExplorer.html', windowConfiguration, true));
|
||||
|
||||
this._processExplorerWindow.on('close', () => this._processExplorerWindow = null);
|
||||
|
||||
|
@ -406,9 +405,9 @@ export class IssueMainService implements ICommonIssueService {
|
|||
features,
|
||||
disableExtensions: this.environmentMainService.disableExtensions,
|
||||
os: {
|
||||
type: os.type(),
|
||||
arch: os.arch(),
|
||||
release: os.release(),
|
||||
type: type(),
|
||||
arch: arch(),
|
||||
release: release(),
|
||||
},
|
||||
product: {
|
||||
nameShort: this.productService.nameShort,
|
||||
|
@ -420,22 +419,6 @@ export class IssueMainService implements ICommonIssueService {
|
|||
}
|
||||
};
|
||||
|
||||
return toWindowUrl('vs/code/electron-sandbox/issue/issueReporter.html', windowConfiguration);
|
||||
return toWindowUrl('vs/code/electron-sandbox/issue/issueReporter.html', windowConfiguration, true);
|
||||
}
|
||||
}
|
||||
|
||||
function toWindowUrl<T>(modulePathToHtml: string, windowConfiguration: T): string {
|
||||
const environment = parseArgs(process.argv, OPTIONS);
|
||||
const config = Object.assign(environment, windowConfiguration);
|
||||
for (const keyValue of Object.keys(config)) {
|
||||
const key = keyValue as keyof typeof config;
|
||||
if (config[key] === undefined || config[key] === null || config[key] === '') {
|
||||
delete config[key]; // only send over properties that have a true value
|
||||
}
|
||||
}
|
||||
|
||||
return FileAccess
|
||||
.asBrowserUri(modulePathToHtml, require, true)
|
||||
.with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` })
|
||||
.toString(true);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ if (isWeb || typeof require === 'undefined' || typeof require.__$__nodeRequire !
|
|||
// Running out of sources
|
||||
if (Object.keys(product).length === 0) {
|
||||
Object.assign(product, {
|
||||
version: '1.55.0-dev',
|
||||
version: '1.56.0-dev',
|
||||
nameShort: isWeb ? 'Code Web - OSS Dev' : 'Code - OSS Dev',
|
||||
nameLong: isWeb ? 'Code Web - OSS Dev' : 'Code - OSS Dev',
|
||||
applicationName: 'code-oss',
|
||||
|
@ -33,6 +33,7 @@ if (isWeb || typeof require === 'undefined' || typeof require.__$__nodeRequire !
|
|||
'ms-vscode.vscode-js-profile-flame',
|
||||
'ms-vscode.vscode-js-profile-table',
|
||||
'ms-vscode.github-browser',
|
||||
'ms-vscode.github-richnav',
|
||||
'ms-vscode.remotehub',
|
||||
'ms-vscode.remotehub-insiders'
|
||||
],
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
|||
import { connect as connectMessagePort } from 'vs/base/parts/ipc/electron-main/ipc.mp';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { WindowError } from 'vs/platform/windows/electron-main/windows';
|
||||
import { toWindowUrl, WindowError } from 'vs/platform/windows/electron-main/windows';
|
||||
import { resolveShellEnv } from 'vs/platform/environment/node/shellEnv';
|
||||
|
||||
export class SharedProcess extends Disposable implements ISharedProcess {
|
||||
|
@ -189,11 +189,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
|||
};
|
||||
|
||||
// Load with config
|
||||
this.window.loadURL(FileAccess
|
||||
.asBrowserUri('vs/code/electron-browser/sharedProcess/sharedProcess.html', require)
|
||||
.with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` })
|
||||
.toString(true)
|
||||
);
|
||||
this.window.loadURL(toWindowUrl('vs/code/electron-browser/sharedProcess/sharedProcess.html', config));
|
||||
}
|
||||
|
||||
private registerWindowListeners(): void {
|
||||
|
|
|
@ -13,13 +13,12 @@ import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, R
|
|||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { WindowMinimumSize, IWindowSettings, MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility, zoomLevelToZoomFactor, INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { browserCodeLoadingCacheStrategy, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, toWindowUrl, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
|
||||
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
|
||||
|
@ -73,7 +72,9 @@ const enum ReadyState {
|
|||
|
||||
export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
private static readonly MAX_URL_LENGTH = 2 * ByteSize.MB; // https://cs.chromium.org/chromium/src/url/url_constants.cc?l=32
|
||||
private static readonly MAX_URL_LENGTH = 2 * ByteSize.MB; // https://source.chromium.org/chromium/chromium/src/+/master:url/url_constants.cc;l=37
|
||||
|
||||
//#region Events
|
||||
|
||||
private readonly _onWillLoad = this._register(new Emitter<ILoadEvent>());
|
||||
readonly onWillLoad = this._onWillLoad.event;
|
||||
|
@ -87,6 +88,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
private readonly _onDidDestroy = this._register(new Emitter<void>());
|
||||
readonly onDidDestroy = this._onDidDestroy.event;
|
||||
|
||||
//#endregion
|
||||
|
||||
private hiddenTitleBarStyle: boolean | undefined;
|
||||
private showTimeoutHandle: NodeJS.Timeout | undefined;
|
||||
private windowState: IWindowState;
|
||||
|
@ -104,6 +107,34 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
private currentHttpProxy: string | undefined = undefined;
|
||||
private currentNoProxy: string | undefined = undefined;
|
||||
|
||||
private _id: number;
|
||||
get id(): number { return this._id; }
|
||||
|
||||
private _win: BrowserWindow;
|
||||
get win(): BrowserWindow | null { return this._win; }
|
||||
|
||||
private _lastFocusTime = -1;
|
||||
get lastFocusTime(): number { return this._lastFocusTime; }
|
||||
|
||||
get backupPath(): string | undefined { return this.currentConfig?.backupPath; }
|
||||
|
||||
get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this.currentConfig?.workspace; }
|
||||
|
||||
get remoteAuthority(): string | undefined { return this.currentConfig?.remoteAuthority; }
|
||||
|
||||
private pendingLoadConfig: INativeWindowConfiguration | undefined;
|
||||
|
||||
private currentConfig: INativeWindowConfiguration | undefined;
|
||||
get config(): INativeWindowConfiguration | undefined { return this.currentConfig; }
|
||||
|
||||
get hasHiddenTitleBarStyle(): boolean { return !!this.hiddenTitleBarStyle; }
|
||||
|
||||
get isExtensionDevelopmentHost(): boolean { return !!(this.currentConfig?.extensionDevelopmentPath); }
|
||||
|
||||
get isExtensionTestHost(): boolean { return !!(this.currentConfig?.extensionTestsPath); }
|
||||
|
||||
get isExtensionDevelopmentTestFromCli(): boolean { return this.isExtensionDevelopmentHost && this.isExtensionTestHost && !this.currentConfig?.debugId; }
|
||||
|
||||
constructor(
|
||||
config: IWindowCreationOptions,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
|
@ -132,7 +163,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 windowConfig = this.configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
const windowSettings = this.configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
|
||||
const options: BrowserWindowConstructorOptions = {
|
||||
width: this.windowState.width,
|
||||
|
@ -152,7 +183,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
spellcheck: false,
|
||||
nativeWindowOpen: true,
|
||||
webviewTag: true,
|
||||
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel),
|
||||
zoomFactor: zoomLevelToZoomFactor(windowSettings?.zoomLevel),
|
||||
...this.environmentMainService.sandbox ?
|
||||
|
||||
// Sandbox
|
||||
|
@ -188,12 +219,12 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
if (isMacintosh) {
|
||||
options.acceptFirstMouse = true; // enabled by default
|
||||
|
||||
if (windowConfig?.clickThroughInactive === false) {
|
||||
if (windowSettings?.clickThroughInactive === false) {
|
||||
options.acceptFirstMouse = false;
|
||||
}
|
||||
}
|
||||
|
||||
const useNativeTabs = isMacintosh && windowConfig?.nativeTabs === true;
|
||||
const useNativeTabs = isMacintosh && windowSettings?.nativeTabs === true;
|
||||
if (useNativeTabs) {
|
||||
options.tabbingIdentifier = this.productService.nameShort; // this opts in to sierra tabs
|
||||
}
|
||||
|
@ -271,25 +302,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
this.registerListeners();
|
||||
}
|
||||
|
||||
private pendingLoadConfig: INativeWindowConfiguration | undefined;
|
||||
|
||||
private currentConfig: INativeWindowConfiguration | undefined;
|
||||
get config(): INativeWindowConfiguration | undefined { return this.currentConfig; }
|
||||
|
||||
private _id: number;
|
||||
get id(): number { return this._id; }
|
||||
|
||||
private _win: BrowserWindow;
|
||||
get win(): BrowserWindow | null { return this._win; }
|
||||
|
||||
get hasHiddenTitleBarStyle(): boolean { return !!this.hiddenTitleBarStyle; }
|
||||
|
||||
get isExtensionDevelopmentHost(): boolean { return !!(this.currentConfig?.extensionDevelopmentPath); }
|
||||
|
||||
get isExtensionTestHost(): boolean { return !!(this.currentConfig?.extensionTestsPath); }
|
||||
|
||||
get isExtensionDevelopmentTestFromCli(): boolean { return this.isExtensionDevelopmentHost && this.isExtensionTestHost && !this.currentConfig?.debugId; }
|
||||
|
||||
setRepresentedFilename(filename: string): void {
|
||||
if (isMacintosh) {
|
||||
this._win.setRepresentedFilename(filename);
|
||||
|
@ -345,15 +357,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
this._win.focus();
|
||||
}
|
||||
|
||||
private _lastFocusTime = -1;
|
||||
get lastFocusTime(): number { return this._lastFocusTime; }
|
||||
|
||||
get backupPath(): string | undefined { return this.currentConfig?.backupPath; }
|
||||
|
||||
get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this.currentConfig?.workspace; }
|
||||
|
||||
get remoteAuthority(): string | undefined { return this.currentConfig?.remoteAuthority; }
|
||||
|
||||
private readyState = ReadyState.NONE;
|
||||
|
||||
setReady(): void {
|
||||
|
@ -680,7 +683,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
}
|
||||
}
|
||||
|
||||
load(config: INativeWindowConfiguration, { isReload, disableExtensions }: { isReload?: boolean, disableExtensions?: boolean } = Object.create(null)): void {
|
||||
load(configuration: INativeWindowConfiguration, { isReload, disableExtensions }: { isReload?: boolean, disableExtensions?: boolean } = Object.create(null)): void {
|
||||
|
||||
// If this window was loaded before from the command line
|
||||
// (as indicated by VSCODE_CLI environment), make sure to
|
||||
|
@ -688,15 +691,15 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
// unless the new configuration context was also a CLI
|
||||
// (for https://github.com/microsoft/vscode/issues/108571)
|
||||
const currentUserEnv = (this.currentConfig ?? this.pendingLoadConfig)?.userEnv;
|
||||
if (currentUserEnv && isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(config.userEnv)) {
|
||||
config.userEnv = { ...currentUserEnv, ...config.userEnv }; // still allow to override certain environment as passed in
|
||||
if (currentUserEnv && isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(configuration.userEnv)) {
|
||||
configuration.userEnv = { ...currentUserEnv, ...configuration.userEnv }; // still allow to override certain environment as passed in
|
||||
}
|
||||
|
||||
// If named pipe was instantiated for the crashpad_handler process, reuse the same
|
||||
// pipe for new app instances connecting to the original app instance.
|
||||
// Ref: https://github.com/microsoft/vscode/issues/115874
|
||||
if (process.env['CHROME_CRASHPAD_PIPE_NAME']) {
|
||||
Object.assign(config.userEnv, {
|
||||
Object.assign(configuration.userEnv, {
|
||||
CHROME_CRASHPAD_PIPE_NAME: process.env['CHROME_CRASHPAD_PIPE_NAME']
|
||||
});
|
||||
}
|
||||
|
@ -704,7 +707,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
// If this is the first time the window is loaded, we associate the paths
|
||||
// directly with the window because we assume the loading will just work
|
||||
if (this.readyState === ReadyState.NONE) {
|
||||
this.currentConfig = config;
|
||||
this.currentConfig = configuration;
|
||||
}
|
||||
|
||||
// Otherwise, the window is currently showing a folder and if there is an
|
||||
|
@ -712,17 +715,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
// because the loading might be vetoed. Instead we associate it later when
|
||||
// the window load event has fired.
|
||||
else {
|
||||
this.pendingLoadConfig = config;
|
||||
this.pendingLoadConfig = configuration;
|
||||
this.readyState = ReadyState.NAVIGATING;
|
||||
}
|
||||
|
||||
// Add disable-extensions to the config, but do not preserve it on currentConfig or
|
||||
// pendingLoadConfig so that it is applied only on this load
|
||||
const configuration = { ...config };
|
||||
if (disableExtensions !== undefined) {
|
||||
configuration['disable-extensions'] = disableExtensions;
|
||||
}
|
||||
|
||||
// Clear Document Edited if needed
|
||||
if (this.isDocumentEdited()) {
|
||||
if (!isReload || !this.backupMainService.isHotExitEnabled()) {
|
||||
|
@ -741,7 +737,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
|
||||
// Load URL
|
||||
mark('code/willOpenNewWindow');
|
||||
this._win.loadURL(this.getUrl(configuration));
|
||||
this._win.loadURL(this.getUrl(configuration, disableExtensions));
|
||||
|
||||
// Make window visible if it did not open in N seconds because this indicates an error
|
||||
// Only do this when running out of sources and not when running tests
|
||||
|
@ -816,64 +812,63 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
return configuration.workspace;
|
||||
}
|
||||
|
||||
private getUrl(windowConfiguration: INativeWindowConfiguration): string {
|
||||
private getUrl(baseConfig: INativeWindowConfiguration, disableExtensions: boolean | undefined): string {
|
||||
|
||||
// Config is a combination of native CLI args and window configuration
|
||||
const configuration: { [key: string]: unknown } = { ...this.environmentMainService.args, ...baseConfig };
|
||||
|
||||
// Add disable-extensions to the config, but do not preserve it on currentConfig or
|
||||
// pendingLoadConfig so that it is applied only on this load
|
||||
if (disableExtensions !== undefined) {
|
||||
configuration['disable-extensions'] = disableExtensions;
|
||||
}
|
||||
|
||||
// Set window ID
|
||||
windowConfiguration.windowId = this._win.id;
|
||||
windowConfiguration.sessionId = `window:${this._win.id}`;
|
||||
windowConfiguration.logLevel = this.logService.getLevel();
|
||||
windowConfiguration.logsPath = this.environmentMainService.logsPath;
|
||||
configuration.windowId = this._win.id;
|
||||
configuration.sessionId = `window:${this._win.id}`;
|
||||
configuration.logLevel = this.logService.getLevel();
|
||||
configuration.logsPath = this.environmentMainService.logsPath;
|
||||
|
||||
// Set zoomlevel
|
||||
const windowConfig = this.configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
const zoomLevel = windowConfig?.zoomLevel;
|
||||
if (typeof zoomLevel === 'number') {
|
||||
windowConfiguration.zoomLevel = zoomLevel;
|
||||
configuration.zoomLevel = zoomLevel;
|
||||
}
|
||||
|
||||
// Set fullscreen state
|
||||
windowConfiguration.fullscreen = this.isFullScreen;
|
||||
configuration.fullscreen = this.isFullScreen;
|
||||
|
||||
// Set Accessibility Config
|
||||
windowConfiguration.colorScheme = {
|
||||
configuration.colorScheme = {
|
||||
dark: nativeTheme.shouldUseDarkColors,
|
||||
highContrast: nativeTheme.shouldUseInvertedColorScheme || nativeTheme.shouldUseHighContrastColors
|
||||
};
|
||||
windowConfiguration.autoDetectHighContrast = windowConfig?.autoDetectHighContrast ?? true;
|
||||
windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled;
|
||||
configuration.autoDetectHighContrast = windowConfig?.autoDetectHighContrast ?? true;
|
||||
configuration.accessibilitySupport = app.accessibilitySupportEnabled;
|
||||
|
||||
// Title style related
|
||||
windowConfiguration.maximized = this._win.isMaximized();
|
||||
configuration.maximized = this._win.isMaximized();
|
||||
|
||||
// Dump Perf Counters
|
||||
windowConfiguration.perfMarks = getMarks();
|
||||
configuration.perfMarks = getMarks();
|
||||
|
||||
// Parts splash
|
||||
windowConfiguration.partsSplashPath = join(this.environmentMainService.userDataPath, 'rapid_render.json');
|
||||
configuration.partsSplashPath = join(this.environmentMainService.userDataPath, 'rapid_render.json');
|
||||
|
||||
// OS Info
|
||||
windowConfiguration.os = {
|
||||
configuration.os = {
|
||||
release: release()
|
||||
};
|
||||
|
||||
// Config (combination of process.argv and window configuration)
|
||||
const environment = parseArgs(process.argv, OPTIONS);
|
||||
const config = Object.assign(environment, windowConfiguration) as unknown as { [key: string]: unknown };
|
||||
for (const key in config) {
|
||||
const configValue = config[key];
|
||||
if (configValue === undefined || configValue === null || configValue === '' || configValue === false) {
|
||||
delete config[key]; // only send over properties that have a true value
|
||||
}
|
||||
}
|
||||
|
||||
// In the unlikely event of the URL becoming larger than 2MB, remove parts of
|
||||
// it that are not under our control. Mainly, the user environment can be very
|
||||
// large depending on user configuration, so we can only remove it in that case.
|
||||
let configUrl = this.doGetUrl(config);
|
||||
let configUrl = this.doGetUrl(configuration);
|
||||
if (configUrl.length > CodeWindow.MAX_URL_LENGTH) {
|
||||
this.logService.warn('Application URL exceeds maximum of 2MB and was shortened.');
|
||||
|
||||
configUrl = this.doGetUrl({ ...config, userEnv: undefined });
|
||||
configUrl = this.doGetUrl({ ...configuration, userEnv: undefined });
|
||||
|
||||
if (configUrl.length > CodeWindow.MAX_URL_LENGTH) {
|
||||
this.logService.error('Application URL exceeds maximum of 2MB and cannot be loaded.');
|
||||
|
@ -891,10 +886,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
workbench = 'vs/code/electron-browser/workbench/workbench.html';
|
||||
}
|
||||
|
||||
return FileAccess
|
||||
.asBrowserUri(workbench, require)
|
||||
.with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` })
|
||||
.toString(true);
|
||||
return toWindowUrl(workbench, config);
|
||||
}
|
||||
|
||||
serializeWindowState(): IWindowState {
|
||||
|
|
|
@ -14,6 +14,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { Rectangle, BrowserWindow, WebContents } from 'electron';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { FileAccess } from 'vs/base/common/network';
|
||||
|
||||
export const enum OpenContext {
|
||||
|
||||
|
@ -206,3 +207,28 @@ export interface IOpenConfiguration extends IBaseOpenConfiguration {
|
|||
}
|
||||
|
||||
export interface IOpenEmptyConfiguration extends IBaseOpenConfiguration { }
|
||||
|
||||
/**
|
||||
* Utility to produce a window URL that includes the provided configuration
|
||||
* as query parameter.
|
||||
*
|
||||
* @param modulePathToHtml path to the HTML to load
|
||||
* @param config the configuration for the window
|
||||
* @returns the url to use for loading
|
||||
*/
|
||||
export function toWindowUrl(modulePathToHtml: string, config: object, forceCodeFileUri?: boolean): string {
|
||||
const configuration: { [key: string]: unknown } = { ...config };
|
||||
|
||||
// Remove values from config that are falsy to reduce the size of of the URL we create
|
||||
for (const key in configuration) {
|
||||
const value = configuration[key];
|
||||
if (value === undefined || value === null || value === '' || value === false) {
|
||||
delete configuration[key];
|
||||
}
|
||||
}
|
||||
|
||||
return FileAccess
|
||||
.asBrowserUri(modulePathToHtml, require, forceCodeFileUri)
|
||||
.with({ query: `config=${encodeURIComponent(JSON.stringify(configuration))}` })
|
||||
.toString(true);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue