shell.ts 26.9 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import 'vs/css!./media/shell';

10
import * as nls from 'vs/nls';
J
Joao Moreno 已提交
11
import * as platform from 'vs/base/common/platform';
J
Johannes Rieken 已提交
12
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
E
Erich Gamma 已提交
13
import dom = require('vs/base/browser/dom');
14
import aria = require('vs/base/browser/ui/aria/aria');
J
Johannes Rieken 已提交
15
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
E
Erich Gamma 已提交
16
import errors = require('vs/base/common/errors');
J
Johannes Rieken 已提交
17
import { toErrorMessage } from 'vs/base/common/errorMessage';
18
import product from 'vs/platform/node/product';
19
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
20
import pkg from 'vs/platform/node/package';
J
Johannes Rieken 已提交
21
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
22
import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench';
23
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
24
import { NullTelemetryService, configurationTelemetry, lifecycleTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
25
import { IExperimentService, ExperimentService } from 'vs/platform/telemetry/common/experiments';
J
Johannes Rieken 已提交
26 27 28
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
import { IdleMonitor, UserStatus } from 'vs/platform/telemetry/browser/idleMonitor';
J
Joao Moreno 已提交
29
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
30
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
C
Christof Marti 已提交
31 32
import { resolveWorkbenchCommonProperties, getOrCreateMachineId } from 'vs/platform/telemetry/node/workbenchCommonProperties';
import { machineIdIpcChannel } from 'vs/platform/telemetry/node/commonProperties';
33
import { WorkspaceStats } from 'vs/workbench/services/telemetry/node/workspaceStats';
34
import { IWindowsService, IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows';
J
Joao Moreno 已提交
35
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
J
Johannes Rieken 已提交
36
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
J
Joao Moreno 已提交
37
import { IRequestService } from 'vs/platform/request/node/request';
38
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
J
Johannes Rieken 已提交
39 40 41 42 43 44 45
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { SearchService } from 'vs/workbench/services/search/node/searchService';
import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService';
import { MarkerService } from 'vs/platform/markers/common/markerService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { CodeEditorServiceImpl } from 'vs/editor/browser/services/codeEditorServiceImpl';
46
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
J
Johannes Rieken 已提交
47 48 49 50
import { IntegrityServiceImpl } from 'vs/platform/integrity/node/integrityServiceImpl';
import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
51
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
J
Johannes Rieken 已提交
52
import { IStorageService } from 'vs/platform/storage/common/storage';
J
Joao Moreno 已提交
53
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Johannes Rieken 已提交
54 55 56
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
S
Sandeep Somavarapu 已提交
57
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
J
Johannes Rieken 已提交
58 59
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
B
Benjamin Pasero 已提交
60
import { IMessageService, IChoiceService, Severity } from 'vs/platform/message/common/message';
J
Johannes Rieken 已提交
61 62 63 64
import { ChoiceChannel } from 'vs/platform/message/common/messageIpc';
import { ISearchService } from 'vs/platform/search/common/search';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/platform/commands/common/commandService';
65
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
66
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
67
import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService';
J
Johannes Rieken 已提交
68 69
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
70
import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
71
import { NodeCachedDataManager } from 'vs/workbench/electron-browser/nodeCachedDataManager';
J
Johannes Rieken 已提交
72 73 74
import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
75 76
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
B
Benjamin Pasero 已提交
77
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
C
Christof Marti 已提交
78
import { remote, ipcRenderer as ipc } from 'electron';
79
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
80 81
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
import * as browser from 'vs/base/browser/browser';
82
import 'vs/platform/opener/browser/opener.contribution';
83 84
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
85 86
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
87
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
88
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
89 90
import { TextMateService } from 'vs/workbench/services/textMate/electron-browser/TMSyntax';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
91
import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService';
B
Benjamin Pasero 已提交
92 93
import { HashService } from 'vs/workbench/services/hash/node/hashService';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
94

95 96 97 98 99 100
/**
 * Services that we require for the Shell
 */
export interface ICoreServices {
	contextService: IWorkspaceContextService;
	configurationService: IConfigurationService;
101
	environmentService: IEnvironmentService;
B
Benjamin Pasero 已提交
102
	timerService: ITimerService;
103
	storageService: IStorageService;
104 105
}

106 107
const currentWindow = remote.getCurrentWindow();

E
Erich Gamma 已提交
108
/**
B
Benjamin Pasero 已提交
109
 * The workbench shell contains the workbench with a rich header containing navigation and the activity bar.
E
Erich Gamma 已提交
110 111 112
 * With the Shell being the top level element in the page, it is also responsible for driving the layouting.
 */
export class WorkbenchShell {
B
Benjamin Pasero 已提交
113
	private storageService: IStorageService;
114
	private messageService: MessageService;
J
Johannes Rieken 已提交
115
	private environmentService: IEnvironmentService;
B
Benjamin Pasero 已提交
116
	private contextViewService: ContextViewService;
117 118
	private configurationService: IConfigurationService;
	private contextService: IWorkspaceContextService;
119
	private telemetryService: ITelemetryService;
120
	private experimentService: IExperimentService;
121
	private extensionService: ExtensionService;
122
	private broadcastService: IBroadcastService;
B
Benjamin Pasero 已提交
123
	private timerService: ITimerService;
B
Benjamin Pasero 已提交
124
	private themeService: WorkbenchThemeService;
125
	private lifecycleService: LifecycleService;
126 127
	private mainProcessServices: ServiceCollection;

E
Erich Gamma 已提交
128
	private container: HTMLElement;
129
	private toUnbind: IDisposable[];
E
Erich Gamma 已提交
130 131 132 133 134
	private previousErrorValue: string;
	private previousErrorTime: number;
	private content: HTMLElement;
	private contentsContainer: Builder;

135
	private configuration: IWindowConfiguration;
E
Erich Gamma 已提交
136 137
	private workbench: Workbench;

B
Benjamin Pasero 已提交
138
	constructor(container: HTMLElement, coreServices: ICoreServices, mainProcessServices: ServiceCollection, configuration: IWindowConfiguration) {
E
Erich Gamma 已提交
139 140
		this.container = container;

141
		this.configuration = configuration;
142

B
Benjamin Pasero 已提交
143 144 145 146 147
		this.contextService = coreServices.contextService;
		this.configurationService = coreServices.configurationService;
		this.environmentService = coreServices.environmentService;
		this.timerService = coreServices.timerService;
		this.storageService = coreServices.storageService;
E
Erich Gamma 已提交
148

149 150
		this.mainProcessServices = mainProcessServices;

E
Erich Gamma 已提交
151 152 153 154 155 156
		this.toUnbind = [];
		this.previousErrorTime = 0;
	}

	private createContents(parent: Builder): Builder {

157
		// ARIA
B
Benjamin Pasero 已提交
158
		aria.setARIAContainer(document.body);
159

E
Erich Gamma 已提交
160
		// Workbench Container
161
		const workbenchContainer = $(parent).div();
E
Erich Gamma 已提交
162 163

		// Instantiation service with services
164
		const [instantiationService, serviceCollection] = this.initServiceCollection(parent.getHTMLElement());
E
Erich Gamma 已提交
165 166

		// Workbench
167
		this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection, this.lifecycleService);
168 169
		try {
			this.workbench.startup({
170
				onWorkbenchStarted: (info: IWorkbenchStartedInfo) => this.onWorkbenchStarted(info, instantiationService)
171 172 173 174 175 176 177 178 179
			});
		} catch (error) {

			// Print out error
			console.error(toErrorMessage(error, true));

			// Rethrow
			throw error;
		}
E
Erich Gamma 已提交
180

181
		// Window
182
		this.workbench.getInstantiationService().createInstance(ElectronWindow, this.container);
E
Erich Gamma 已提交
183 184

		// Handle case where workbench is not starting up properly
185
		const timeoutHandle = setTimeout(() => {
E
Erich Gamma 已提交
186 187 188
			console.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
		}, 10000);

189
		this.lifecycleService.when(LifecyclePhase.Running).then(() => {
E
Erich Gamma 已提交
190 191 192 193 194 195
			clearTimeout(timeoutHandle);
		});

		return workbenchContainer;
	}

196
	private onWorkbenchStarted(info: IWorkbenchStartedInfo, instantiationService: IInstantiationService): void {
197 198

		// Telemetry: workspace info
B
Benjamin Pasero 已提交
199
		const { filesToOpen, filesToCreate, filesToDiff } = this.configuration;
K
kieferrm 已提交
200
		/* __GDPR__
K
kieferrm 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
			"workspaceLoad" : {
				"userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" },
				"experiments": { "${inline}": [ "${IExperiments}" ] },
				"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
			}
		*/
222 223 224
		this.telemetryService.publicLog('workspaceLoad', {
			userAgent: navigator.userAgent,
			windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
225
			emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY,
226 227 228
			'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0,
			'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0,
			'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0,
229
			customKeybindingsCount: info.customKeybindingsCount,
B
Benjamin Pasero 已提交
230
			theme: this.themeService.getColorTheme().id,
231
			language: platform.language,
232
			experiments: this.experimentService.getExperiments(),
233 234
			pinnedViewlets: info.pinnedViewlets,
			restoredViewlet: info.restoredViewlet,
235 236
			restoredEditors: info.restoredEditors.length,
			startupKind: this.lifecycleService.startupKind
237 238
		});

B
Benjamin Pasero 已提交
239
		// Telemetry: startup metrics
240
		this.timerService.workbenchStarted = Date.now();
B
Benjamin Pasero 已提交
241 242
		this.timerService.restoreEditorsDuration = info.restoreEditorsDuration;
		this.timerService.restoreViewletDuration = info.restoreViewletDuration;
243
		this.extensionService.onReady().done(() => {
K
kieferrm 已提交
244
			/* __GDPR__
K
kieferrm 已提交
245 246 247 248 249 250
				"startupTime" : {
					"${include}": [
						"${IStartupMetrics}"
					]
				}
			*/
B
Benjamin Pasero 已提交
251
			this.telemetryService.publicLog('startupTime', this.timerService.startupMetrics);
252
		});
B
Benjamin Pasero 已提交
253

254
		// Telemetry: workspace tags
255
		const workspaceStats: WorkspaceStats = <WorkspaceStats>this.workbench.getInstantiationService().createInstance(WorkspaceStats);
B
Benjamin Pasero 已提交
256
		workspaceStats.reportWorkspaceTags(this.configuration);
K
kieferrm 已提交
257
		workspaceStats.reportCloudStats();
J
Joao Moreno 已提交
258

259
		// Root Warning
J
Joao Moreno 已提交
260 261 262
		if ((platform.isLinux || platform.isMacintosh) && process.getuid() === 0) {
			this.messageService.show(Severity.Warning, nls.localize('runningAsRoot', "It is recommended not to run Code as 'root'."));
		}
263 264 265 266 267 268 269

		// Start cached data manager
		instantiationService.createInstance(NodeCachedDataManager);

		// Set lifecycle phase to `Runnning` so that other contributions
		// can now do something
		this.lifecycleService.phase = LifecyclePhase.Running;
B
Benjamin Pasero 已提交
270 271
	}

272
	private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
J
Johannes Rieken 已提交
273
		const disposables: IDisposable[] = [];
J
Joao Moreno 已提交
274

275 276 277
		const serviceCollection = new ServiceCollection();
		serviceCollection.set(IWorkspaceContextService, this.contextService);
		serviceCollection.set(IConfigurationService, this.configurationService);
278
		serviceCollection.set(IEnvironmentService, this.environmentService);
B
Benjamin Pasero 已提交
279
		serviceCollection.set(ITimerService, this.timerService);
280
		serviceCollection.set(IStorageService, this.storageService);
281 282 283
		this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
			serviceCollection.set(serviceIdentifier, serviceInstance);
		});
284

285
		const instantiationService: IInstantiationService = new InstantiationService(serviceCollection, true);
286

287 288
		this.broadcastService = new BroadcastService(currentWindow.id);
		serviceCollection.set(IBroadcastService, this.broadcastService);
289

290
		serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, currentWindow.id));
J
Joao Moreno 已提交
291

292
		const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
293
			.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${currentWindow.id}`));
294 295 296

		sharedProcess
			.done(client => client.registerChannel('choice', instantiationService.createInstance(ChoiceChannel)));
297

298 299 300 301
		// Warm up font cache information before building up too many dom elements
		restoreFontInfo(this.storageService);
		readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getConfiguration('editor'), browser.getZoomLevel()));

B
Benjamin Pasero 已提交
302 303 304
		// Hash
		serviceCollection.set(IHashService, new SyncDescriptor(HashService));

305 306 307 308
		// Experiments
		this.experimentService = instantiationService.createInstance(ExperimentService);
		serviceCollection.set(IExperimentService, this.experimentService);

309
		// Telemetry
C
Christof Marti 已提交
310
		this.sendMachineIdToMain(this.storageService);
311
		if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
312
			const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
313 314
			const commit = product.commit;
			const version = pkg.version;
315

316
			const config: ITelemetryServiceConfig = {
317
				appender: new TelemetryAppenderClient(channel),
318
				commonProperties: resolveWorkbenchCommonProperties(this.storageService, commit, version, this.environmentService.installSource),
319
				piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath]
320
			};
321

J
Joao Moreno 已提交
322
			const telemetryService = instantiationService.createInstance(TelemetryService, config);
323 324
			this.telemetryService = telemetryService;

J
Joao Moreno 已提交
325
			const errorTelemetry = new ErrorTelemetry(telemetryService);
326
			const idleMonitor = new IdleMonitor(2 * 60 * 1000); // 2 minutes
327

328
			const listener = idleMonitor.onStatusChange(status =>
K
kieferrm 已提交
329
				/* __GDPR__
K
kieferrm 已提交
330 331
					"UserIdleStart" : {}
				*/
K
kieferrm 已提交
332
				/* __GDPR__
K
kieferrm 已提交
333 334
					"UserIdleStop" : {}
				*/
335 336 337
				this.telemetryService.publicLog(status === UserStatus.Active
					? TelemetryService.IDLE_STOP_EVENT_NAME
					: TelemetryService.IDLE_START_EVENT_NAME
338
				));
339

J
Johannes Rieken 已提交
340
			disposables.push(telemetryService, errorTelemetry, listener, idleMonitor);
341
		} else {
342
			this.telemetryService = NullTelemetryService;
343
		}
E
Erich Gamma 已提交
344

345
		serviceCollection.set(ITelemetryService, this.telemetryService);
J
Johannes Rieken 已提交
346
		disposables.push(configurationTelemetry(this.telemetryService, this.configurationService));
E
Erich Gamma 已提交
347

348
		let crashReporterService = NullCrashReporterService;
349
		if (!this.environmentService.disableCrashReporter && product.crashReporter && product.hockeyApp) {
350 351 352 353
			crashReporterService = instantiationService.createInstance(CrashReporterService);
		}
		serviceCollection.set(ICrashReporterService, crashReporterService);

354
		this.messageService = instantiationService.createInstance(MessageService, container);
355
		serviceCollection.set(IMessageService, this.messageService);
J
Joao Moreno 已提交
356
		serviceCollection.set(IChoiceService, this.messageService);
E
Erich Gamma 已提交
357

358
		const lifecycleService = instantiationService.createInstance(LifecycleService);
J
Johannes Rieken 已提交
359
		this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
360
		this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
361
		serviceCollection.set(ILifecycleService, lifecycleService);
J
Johannes Rieken 已提交
362
		disposables.push(lifecycleTelemetry(this.telemetryService, lifecycleService));
363
		this.lifecycleService = lifecycleService;
364

S
Sandeep Somavarapu 已提交
365
		const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
366
		serviceCollection.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementChannelClient, extensionManagementChannel));
S
Sandeep Somavarapu 已提交
367

368 369
		const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
		serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
J
Johannes Rieken 已提交
370
		disposables.push(extensionEnablementService);
371

372
		this.extensionService = instantiationService.createInstance(ExtensionService);
373
		serviceCollection.set(IExtensionService, this.extensionService);
374 375

		this.timerService.beforeExtensionLoad = Date.now();
376
		this.extensionService.onReady().done(() => {
377
			this.timerService.afterExtensionLoad = Date.now();
378
		});
E
Erich Gamma 已提交
379

B
Benjamin Pasero 已提交
380 381 382
		this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
		serviceCollection.set(IWorkbenchThemeService, this.themeService);

383
		serviceCollection.set(ICommandService, new SyncDescriptor(CommandService));
384

385 386
		this.contextViewService = instantiationService.createInstance(ContextViewService, this.container);
		serviceCollection.set(IContextViewService, this.contextViewService);
E
Erich Gamma 已提交
387

388
		serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
E
Erich Gamma 已提交
389

390
		serviceCollection.set(IMarkerService, new SyncDescriptor(MarkerService));
E
Erich Gamma 已提交
391

392
		serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
393

394
		serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
395

396 397
		serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));

398
		serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
399

400
		serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
401

402
		serviceCollection.set(ITextMateService, new SyncDescriptor(TextMateService));
A
Alex Dima 已提交
403

404
		serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
405

406
		serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorServiceImpl));
407

408
		serviceCollection.set(IIntegrityService, new SyncDescriptor(IntegrityServiceImpl));
A
Alex Dima 已提交
409

410
		return [instantiationService, serviceCollection];
E
Erich Gamma 已提交
411 412
	}

C
Christof Marti 已提交
413 414 415 416 417 418
	private sendMachineIdToMain(storageService: IStorageService) {
		getOrCreateMachineId(storageService).then(machineId => {
			ipc.send(machineIdIpcChannel, machineId);
		}).then(null, errors.onUnexpectedError);
	}

E
Erich Gamma 已提交
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
	public open(): void {

		// Listen on unexpected errors
		errors.setUnexpectedErrorHandler((error: any) => {
			this.onUnexpectedError(error);
		});

		// Shell Class for CSS Scoping
		$(this.container).addClass('monaco-shell');

		// Controls
		this.content = $('.monaco-shell-content').appendTo(this.container).getHTMLElement();

		// Create Contents
		this.contentsContainer = this.createContents($(this.content));

		// Layout
		this.layout();

		// Listeners
		this.registerListeners();
	}

	private registerListeners(): void {

		// Resize
		$(window).on(dom.EventType.RESIZE, () => this.layout(), this.toUnbind);
	}

	public onUnexpectedError(error: any): void {
449
		const errorMsg = toErrorMessage(error, true);
E
Erich Gamma 已提交
450 451 452 453
		if (!errorMsg) {
			return;
		}

454
		const now = Date.now();
E
Erich Gamma 已提交
455 456 457 458 459 460 461 462 463 464 465
		if (errorMsg === this.previousErrorValue && now - this.previousErrorTime <= 1000) {
			return; // Return if error message identical to previous and shorter than 1 second
		}

		this.previousErrorTime = now;
		this.previousErrorValue = errorMsg;

		// Log to console
		console.error(errorMsg);

		// Show to user if friendly message provided
466
		if (error && error.friendlyMessage && this.messageService) {
B
Benjamin Pasero 已提交
467
			this.messageService.show(Severity.Error, error.friendlyMessage);
E
Erich Gamma 已提交
468 469 470
		}
	}

B
Benjamin Pasero 已提交
471
	private layout(): void {
472
		const clArea = $(this.container).getClientArea();
E
Erich Gamma 已提交
473

474
		const contentsSize = new Dimension(clArea.width, clArea.height);
E
Erich Gamma 已提交
475 476
		this.contentsContainer.size(contentsSize.width, contentsSize.height);

B
Benjamin Pasero 已提交
477
		this.contextViewService.layout();
E
Erich Gamma 已提交
478 479 480
		this.workbench.layout();
	}

B
Benjamin Pasero 已提交
481
	public dispose(): void {
E
Erich Gamma 已提交
482 483 484

		// Workbench
		if (this.workbench) {
B
Benjamin Pasero 已提交
485
			this.workbench.dispose();
E
Erich Gamma 已提交
486 487
		}

B
Benjamin Pasero 已提交
488
		this.contextViewService.dispose();
E
Erich Gamma 已提交
489 490

		// Listeners
J
Joao Moreno 已提交
491
		this.toUnbind = dispose(this.toUnbind);
E
Erich Gamma 已提交
492 493 494 495

		// Container
		$(this.container).empty();
	}
496
}
497 498

registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
B
Benjamin Pasero 已提交
499 500

	// Foreground
B
Benjamin Pasero 已提交
501
	const windowForeground = theme.getColor(foreground);
502 503 504
	if (windowForeground) {
		collector.addRule(`.monaco-shell { color: ${windowForeground}; }`);
	}
B
Benjamin Pasero 已提交
505

506 507 508 509 510 511
	// Selection
	const windowSelectionBackground = theme.getColor(selectionBackground);
	if (windowSelectionBackground) {
		collector.addRule(`.monaco-shell ::selection { background-color: ${windowSelectionBackground}; }`);
	}

512 513 514 515 516 517 518
	// Input placeholder
	const placeholderForeground = theme.getColor(inputPlaceholderForeground);
	if (placeholderForeground) {
		collector.addRule(`.monaco-shell input::-webkit-input-placeholder { color: ${placeholderForeground}; }`);
		collector.addRule(`.monaco-shell textarea::-webkit-input-placeholder { color: ${placeholderForeground}; }`);
	}

519 520 521 522 523 524 525 526 527 528 529
	// List highlight
	const listHighlightForegroundColor = theme.getColor(listHighlightForeground);
	if (listHighlightForegroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-tree .monaco-tree-row .monaco-highlighted-label .highlight,
			.monaco-shell .monaco-list .monaco-list-row .monaco-highlighted-label .highlight {
				color: ${listHighlightForegroundColor};
			}
		`);
	}

B
Benjamin Pasero 已提交
530
	// We need to set the workbench background color so that on Windows we get subpixel-antialiasing.
531 532 533 534 535 536 537 538 539 540 541 542 543
	let workbenchBackground: string;
	switch (theme.type) {
		case 'dark':
			workbenchBackground = '#252526';
			break;
		case 'light':
			workbenchBackground = '#F3F3F3';
			break;
		default:
			workbenchBackground = '#000000';
	}
	collector.addRule(`.monaco-workbench { background-color: ${workbenchBackground}; }`);

B
Benjamin Pasero 已提交
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
	// Scrollbars
	const scrollbarShadowColor = theme.getColor(scrollbarShadow);
	if (scrollbarShadowColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .shadow.top {
				box-shadow: ${scrollbarShadowColor} 0 6px 6px -6px inset;
			}

			.monaco-shell .monaco-scrollable-element > .shadow.left {
				box-shadow: ${scrollbarShadowColor} 6px 0 6px -6px inset;
			}

			.monaco-shell .monaco-scrollable-element > .shadow.top.left {
				box-shadow: ${scrollbarShadowColor} 6px 6px 6px -6px inset;
			}
		`);
	}

	const scrollbarSliderBackgroundColor = theme.getColor(scrollbarSliderBackground);
	if (scrollbarSliderBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider {
				background: ${scrollbarSliderBackgroundColor};
			}
		`);
	}

	const scrollbarSliderHoverBackgroundColor = theme.getColor(scrollbarSliderHoverBackground);
	if (scrollbarSliderHoverBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider:hover {
				background: ${scrollbarSliderHoverBackgroundColor};
			}
		`);
	}

	const scrollbarSliderActiveBackgroundColor = theme.getColor(scrollbarSliderActiveBackground);
	if (scrollbarSliderActiveBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider.active {
				background: ${scrollbarSliderActiveBackgroundColor};
			}
		`);
	}

	// Focus outline
590
	const focusOutline = theme.getColor(focusBorder);
B
Benjamin Pasero 已提交
591 592 593 594 595 596 597 598
	if (focusOutline) {
		collector.addRule(`
			.monaco-shell [tabindex="0"]:focus,
			.monaco-shell .synthetic-focus,
			.monaco-shell select:focus,
			.monaco-shell .monaco-tree.focused.no-focused-item:focus:before,
			.monaco-shell input[type="button"]:focus,
			.monaco-shell input[type="text"]:focus,
B
Benjamin Pasero 已提交
599
			.monaco-shell button:focus,
B
Benjamin Pasero 已提交
600 601 602 603 604 605 606
			.monaco-shell textarea:focus,
			.monaco-shell input[type="search"]:focus,
			.monaco-shell input[type="checkbox"]:focus {
				outline-color: ${focusOutline};
			}
		`);
	}
607
});