shell.ts 26.7 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';
31
import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties';
32
import { IWindowsService, IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows';
J
Joao Moreno 已提交
33
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
J
Johannes Rieken 已提交
34
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
J
Joao Moreno 已提交
35
import { IRequestService } from 'vs/platform/request/node/request';
36
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
J
Johannes Rieken 已提交
37 38 39 40 41 42 43
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';
44
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
J
Johannes Rieken 已提交
45 46 47 48
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';
49
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
J
Johannes Rieken 已提交
50
import { IStorageService } from 'vs/platform/storage/common/storage';
J
Joao Moreno 已提交
51
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Johannes Rieken 已提交
52 53 54
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 已提交
55
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
J
Johannes Rieken 已提交
56 57
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
B
Benjamin Pasero 已提交
58
import { IMessageService, IChoiceService, Severity } from 'vs/platform/message/common/message';
J
Johannes Rieken 已提交
59 60 61 62
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';
63
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
64
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
65
import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService';
J
Johannes Rieken 已提交
66 67
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
68
import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
J
Johannes Rieken 已提交
69 70 71
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';
72 73
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
B
Benjamin Pasero 已提交
74
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
75
import { remote } from 'electron';
76
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
77 78
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
import * as browser from 'vs/base/browser/browser';
79
import 'vs/platform/opener/browser/opener.contribution';
80 81
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
82 83
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
84
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
85
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
86 87
import { TextMateService } from 'vs/workbench/services/textMate/electron-browser/TMSyntax';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
88
import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService';
B
Benjamin Pasero 已提交
89 90
import { HashService } from 'vs/workbench/services/hash/node/hashService';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
J
Joao Moreno 已提交
91
import { ILogService } from 'vs/platform/log/common/log';
92

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

105 106
const currentWindow = remote.getCurrentWindow();

E
Erich Gamma 已提交
107
/**
B
Benjamin Pasero 已提交
108
 * The workbench shell contains the workbench with a rich header containing navigation and the activity bar.
E
Erich Gamma 已提交
109 110 111
 * 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 已提交
112
	private storageService: IStorageService;
113
	private messageService: MessageService;
J
Johannes Rieken 已提交
114
	private environmentService: IEnvironmentService;
J
Joao Moreno 已提交
115
	private logService: ILogService;
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
		this.contextService = coreServices.contextService;
		this.configurationService = coreServices.configurationService;
		this.environmentService = coreServices.environmentService;
J
Joao Moreno 已提交
146
		this.logService = coreServices.logService;
B
Benjamin Pasero 已提交
147 148
		this.timerService = coreServices.timerService;
		this.storageService = coreServices.storageService;
E
Erich Gamma 已提交
149

150 151
		this.mainProcessServices = mainProcessServices;

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

	private createContents(parent: Builder): Builder {

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

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

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

		// Workbench
168
		this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection, this.lifecycleService);
169
		try {
B
Benjamin Pasero 已提交
170
			this.workbench.startup().done(startupInfos => this.onWorkbenchStarted(startupInfos, instantiationService));
171 172 173 174 175 176 177 178
		} catch (error) {

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

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

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

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

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

		return workbenchContainer;
	}

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

197 198 199 200 201 202 203 204 205 206 207 208 209 210
		// Startup Telemetry
		this.logStartupTelemetry(info);

		// Root Warning
		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'."));
		}

		// Set lifecycle phase to `Runnning` so that other contributions can now do something
		this.lifecycleService.phase = LifecyclePhase.Running;

		// Set lifecycle phase to `Runnning For A Bit` after a short delay
		let timeoutHandle = setTimeout(() => {
			timeoutHandle = void 0;
B
Benjamin Pasero 已提交
211
			this.lifecycleService.phase = LifecyclePhase.Eventually;
212 213 214 215 216 217 218 219 220 221 222
		}, 3000);
		this.toUnbind.push({
			dispose: () => {
				if (timeoutHandle) {
					clearTimeout(timeoutHandle);
				}
			}
		});
	}

	private logStartupTelemetry(info: IWorkbenchStartedInfo): void {
B
Benjamin Pasero 已提交
223
		const { filesToOpen, filesToCreate, filesToDiff } = this.configuration;
K
kieferrm 已提交
224
		/* __GDPR__
K
kieferrm 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
			"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" }
			}
		*/
246 247 248
		this.telemetryService.publicLog('workspaceLoad', {
			userAgent: navigator.userAgent,
			windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
249
			emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY,
250 251 252
			'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0,
			'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0,
			'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0,
253
			customKeybindingsCount: info.customKeybindingsCount,
B
Benjamin Pasero 已提交
254
			theme: this.themeService.getColorTheme().id,
255
			language: platform.language,
256
			experiments: this.experimentService.getExperiments(),
257 258
			pinnedViewlets: info.pinnedViewlets,
			restoredViewlet: info.restoredViewlet,
259 260
			restoredEditors: info.restoredEditors.length,
			startupKind: this.lifecycleService.startupKind
261 262
		});

B
Benjamin Pasero 已提交
263
		// Telemetry: startup metrics
264
		this.timerService.workbenchStarted = Date.now();
B
Benjamin Pasero 已提交
265 266
		this.timerService.restoreEditorsDuration = info.restoreEditorsDuration;
		this.timerService.restoreViewletDuration = info.restoreViewletDuration;
267
		this.extensionService.whenInstalledExtensionsRegistered().done(() => {
K
kieferrm 已提交
268
			/* __GDPR__
K
kieferrm 已提交
269 270 271 272 273 274
				"startupTime" : {
					"${include}": [
						"${IStartupMetrics}"
					]
				}
			*/
B
Benjamin Pasero 已提交
275
			this.telemetryService.publicLog('startupTime', this.timerService.startupMetrics);
276
		});
B
Benjamin Pasero 已提交
277 278
	}

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

282 283 284
		const serviceCollection = new ServiceCollection();
		serviceCollection.set(IWorkspaceContextService, this.contextService);
		serviceCollection.set(IConfigurationService, this.configurationService);
285
		serviceCollection.set(IEnvironmentService, this.environmentService);
J
Joao Moreno 已提交
286
		serviceCollection.set(ILogService, this.logService);
B
Benjamin Pasero 已提交
287
		serviceCollection.set(ITimerService, this.timerService);
288
		serviceCollection.set(IStorageService, this.storageService);
289 290 291
		this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
			serviceCollection.set(serviceIdentifier, serviceInstance);
		});
292

293
		const instantiationService: IInstantiationService = new InstantiationService(serviceCollection, true);
294

295 296
		this.broadcastService = new BroadcastService(currentWindow.id);
		serviceCollection.set(IBroadcastService, this.broadcastService);
297

298
		serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, currentWindow.id, this.configuration));
J
Joao Moreno 已提交
299

300
		const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
301
			.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${currentWindow.id}`));
302 303 304

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

306 307
		// Warm up font cache information before building up too many dom elements
		restoreFontInfo(this.storageService);
308
		readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
309

B
Benjamin Pasero 已提交
310 311 312
		// Hash
		serviceCollection.set(IHashService, new SyncDescriptor(HashService));

313 314 315 316
		// Experiments
		this.experimentService = instantiationService.createInstance(ExperimentService);
		serviceCollection.set(IExperimentService, this.experimentService);

317
		// Telemetry
318
		if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
319
			const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
320 321
			const commit = product.commit;
			const version = pkg.version;
322

323
			const config: ITelemetryServiceConfig = {
324
				appender: new TelemetryAppenderClient(channel),
325
				commonProperties: resolveWorkbenchCommonProperties(this.storageService, commit, version, this.configuration.machineId, this.environmentService.installSourcePath),
326
				piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath]
327
			};
328

J
Joao Moreno 已提交
329
			const telemetryService = instantiationService.createInstance(TelemetryService, config);
330 331
			this.telemetryService = telemetryService;

J
Joao Moreno 已提交
332
			const errorTelemetry = new ErrorTelemetry(telemetryService);
333
			const idleMonitor = new IdleMonitor(2 * 60 * 1000); // 2 minutes
334

335
			const listener = idleMonitor.onStatusChange(status =>
K
kieferrm 已提交
336
				/* __GDPR__
K
kieferrm 已提交
337 338
					"UserIdleStart" : {}
				*/
K
kieferrm 已提交
339
				/* __GDPR__
K
kieferrm 已提交
340 341
					"UserIdleStop" : {}
				*/
342 343 344
				this.telemetryService.publicLog(status === UserStatus.Active
					? TelemetryService.IDLE_STOP_EVENT_NAME
					: TelemetryService.IDLE_START_EVENT_NAME
345
				));
346

J
Johannes Rieken 已提交
347
			disposables.push(telemetryService, errorTelemetry, listener, idleMonitor);
348
		} else {
349
			this.telemetryService = NullTelemetryService;
350
		}
E
Erich Gamma 已提交
351

352
		serviceCollection.set(ITelemetryService, this.telemetryService);
J
Johannes Rieken 已提交
353
		disposables.push(configurationTelemetry(this.telemetryService, this.configurationService));
E
Erich Gamma 已提交
354

355
		let crashReporterService = NullCrashReporterService;
356
		if (!this.environmentService.disableCrashReporter && product.crashReporter && product.hockeyApp) {
357 358 359 360
			crashReporterService = instantiationService.createInstance(CrashReporterService);
		}
		serviceCollection.set(ICrashReporterService, crashReporterService);

361
		this.messageService = instantiationService.createInstance(MessageService, container);
362
		serviceCollection.set(IMessageService, this.messageService);
J
Joao Moreno 已提交
363
		serviceCollection.set(IChoiceService, this.messageService);
E
Erich Gamma 已提交
364

365
		const lifecycleService = instantiationService.createInstance(LifecycleService);
J
Johannes Rieken 已提交
366
		this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
367
		this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
368
		serviceCollection.set(ILifecycleService, lifecycleService);
J
Johannes Rieken 已提交
369
		disposables.push(lifecycleTelemetry(this.telemetryService, lifecycleService));
370
		this.lifecycleService = lifecycleService;
371

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

375 376
		const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
		serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
J
Johannes Rieken 已提交
377
		disposables.push(extensionEnablementService);
378

379
		this.extensionService = instantiationService.createInstance(ExtensionService);
380
		serviceCollection.set(IExtensionService, this.extensionService);
381 382

		this.timerService.beforeExtensionLoad = Date.now();
383
		this.extensionService.whenInstalledExtensionsRegistered().done(() => {
384
			this.timerService.afterExtensionLoad = Date.now();
385
		});
E
Erich Gamma 已提交
386

B
Benjamin Pasero 已提交
387 388 389
		this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
		serviceCollection.set(IWorkbenchThemeService, this.themeService);

390
		serviceCollection.set(ICommandService, new SyncDescriptor(CommandService));
391

392 393
		this.contextViewService = instantiationService.createInstance(ContextViewService, this.container);
		serviceCollection.set(IContextViewService, this.contextViewService);
E
Erich Gamma 已提交
394

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

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

399
		serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
400

401
		serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
402

403 404
		serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));

405
		serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
406

407
		serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
408

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

411
		serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
412

413
		serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorServiceImpl));
414

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

417
		return [instantiationService, serviceCollection];
E
Erich Gamma 已提交
418 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 449
	}

	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 {
450
		const errorMsg = toErrorMessage(error, true);
E
Erich Gamma 已提交
451 452 453 454
		if (!errorMsg) {
			return;
		}

455
		const now = Date.now();
E
Erich Gamma 已提交
456 457 458 459 460 461 462 463 464 465 466
		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
467
		if (error && error.friendlyMessage && this.messageService) {
B
Benjamin Pasero 已提交
468
			this.messageService.show(Severity.Error, error.friendlyMessage);
E
Erich Gamma 已提交
469 470 471
		}
	}

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

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

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

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

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

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

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

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

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

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

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

513 514 515 516 517 518 519
	// 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}; }`);
	}

520 521 522 523 524 525 526 527 528 529 530
	// 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 已提交
531
	// We need to set the workbench background color so that on Windows we get subpixel-antialiasing.
532 533 534 535 536 537 538 539 540 541 542 543 544
	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 已提交
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 590
	// 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
591
	const focusOutline = theme.getColor(focusBorder);
B
Benjamin Pasero 已提交
592 593 594 595 596 597 598 599
	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 已提交
600
			.monaco-shell button:focus,
B
Benjamin Pasero 已提交
601 602 603 604 605 606 607
			.monaco-shell textarea:focus,
			.monaco-shell input[type="search"]:focus,
			.monaco-shell input[type="checkbox"]:focus {
				outline-color: ${focusOutline};
			}
		`);
	}
608
});