shell.ts 26.6 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
Johannes Rieken 已提交
11
import { TPromise } from 'vs/base/common/winjs.base';
J
Joao Moreno 已提交
12
import * as platform from 'vs/base/common/platform';
J
Johannes Rieken 已提交
13
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
E
Erich Gamma 已提交
14
import dom = require('vs/base/browser/dom');
15
import aria = require('vs/base/browser/ui/aria/aria');
J
Johannes Rieken 已提交
16
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
E
Erich Gamma 已提交
17
import errors = require('vs/base/common/errors');
J
Johannes Rieken 已提交
18
import { toErrorMessage } from 'vs/base/common/errorMessage';
19
import product from 'vs/platform/node/product';
20
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
21
import pkg from 'vs/platform/node/package';
J
Johannes Rieken 已提交
22
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
23
import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench';
24
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
25
import { NullTelemetryService, configurationTelemetry, lifecycleTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
26
import { IExperimentService, ExperimentService } from 'vs/platform/telemetry/common/experiments';
J
Johannes Rieken 已提交
27 28 29
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 已提交
30
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
31
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
C
Christof Marti 已提交
32 33
import { resolveWorkbenchCommonProperties, getOrCreateMachineId } from 'vs/platform/telemetry/node/workbenchCommonProperties';
import { machineIdIpcChannel } from 'vs/platform/telemetry/node/commonProperties';
34
import { WorkspaceStats } from 'vs/workbench/services/telemetry/node/workspaceStats';
35
import { IWindowsService, IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows';
J
Joao Moreno 已提交
36
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
J
Johannes Rieken 已提交
37
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
J
Joao Moreno 已提交
38
import { IRequestService } from 'vs/platform/request/node/request';
39
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
J
Johannes Rieken 已提交
40 41 42 43 44 45 46 47 48 49 50 51
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';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
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';
52
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
J
Johannes Rieken 已提交
53
import { IStorageService } from 'vs/platform/storage/common/storage';
J
Joao Moreno 已提交
54
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Johannes Rieken 已提交
55 56 57
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 已提交
58
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
J
Johannes Rieken 已提交
59 60
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
B
Benjamin Pasero 已提交
61
import { IMessageService, IChoiceService, Severity } from 'vs/platform/message/common/message';
J
Johannes Rieken 已提交
62 63 64 65
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';
66
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
67
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
68
import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService';
J
Johannes Rieken 已提交
69 70
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
71 72
import { ICrashReporterService, NullCrashReporterService } from 'vs/workbench/services/crashReporter/common/crashReporterService';
import { CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
73
import { NodeCachedDataManager } from 'vs/workbench/electron-browser/nodeCachedDataManager';
J
Johannes Rieken 已提交
74 75 76
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';
77 78
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
B
Benjamin Pasero 已提交
79
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
C
Christof Marti 已提交
80
import { remote, ipcRenderer as ipc } from 'electron';
81
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
82 83
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
import * as browser from 'vs/base/browser/browser';
84
import 'vs/platform/opener/browser/opener.contribution';
85 86
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
87 88
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
89
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
90
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
91 92
import { TextMateService } from 'vs/workbench/services/textMate/electron-browser/TMSyntax';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
93
import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService';
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
B
Benjamin Pasero 已提交
167
		this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection);
E
Erich Gamma 已提交
168
		this.workbench.startup({
169
			onWorkbenchStarted: (info: IWorkbenchStartedInfo) => {
170 171

				// run workbench started logic
B
Benjamin Pasero 已提交
172
				this.onWorkbenchStarted(info);
173 174 175

				// start cached data manager
				instantiationService.createInstance(NodeCachedDataManager);
176 177 178 179

				// Set lifecycle phase to `Runnning` so that other contributions
				// can now do something
				this.lifecycleService.phase = LifecyclePhase.Running;
E
Erich Gamma 已提交
180 181 182
			}
		});

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

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

		this.workbench.joinCreation().then(() => {
			clearTimeout(timeoutHandle);
		});

		return workbenchContainer;
	}

B
Benjamin Pasero 已提交
198
	private onWorkbenchStarted(info: IWorkbenchStartedInfo): void {
199 200

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

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

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

		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'."));
		}
B
Benjamin Pasero 已提交
264 265
	}

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

269 270 271
		const serviceCollection = new ServiceCollection();
		serviceCollection.set(IWorkspaceContextService, this.contextService);
		serviceCollection.set(IConfigurationService, this.configurationService);
272
		serviceCollection.set(IEnvironmentService, this.environmentService);
B
Benjamin Pasero 已提交
273
		serviceCollection.set(ITimerService, this.timerService);
274
		serviceCollection.set(IStorageService, this.storageService);
275 276 277
		this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
			serviceCollection.set(serviceIdentifier, serviceInstance);
		});
278

279
		const instantiationService: IInstantiationService = new InstantiationService(serviceCollection, true);
280

281 282
		this.broadcastService = new BroadcastService(currentWindow.id);
		serviceCollection.set(IBroadcastService, this.broadcastService);
283

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

286
		const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
287
			.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${currentWindow.id}`));
288 289 290

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

292 293 294 295
		// Warm up font cache information before building up too many dom elements
		restoreFontInfo(this.storageService);
		readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getConfiguration('editor'), browser.getZoomLevel()));

296 297 298 299
		// Experiments
		this.experimentService = instantiationService.createInstance(ExperimentService);
		serviceCollection.set(IExperimentService, this.experimentService);

300
		// Telemetry
C
Christof Marti 已提交
301
		this.sendMachineIdToMain(this.storageService);
302
		if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
303
			const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
304 305
			const commit = product.commit;
			const version = pkg.version;
306

307
			const config: ITelemetryServiceConfig = {
308
				appender: new TelemetryAppenderClient(channel),
309
				commonProperties: resolveWorkbenchCommonProperties(this.storageService, commit, version, this.environmentService.installSource),
310
				piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath]
311
			};
312

J
Joao Moreno 已提交
313
			const telemetryService = instantiationService.createInstance(TelemetryService, config);
314 315
			this.telemetryService = telemetryService;

J
Joao Moreno 已提交
316
			const errorTelemetry = new ErrorTelemetry(telemetryService);
317
			const idleMonitor = new IdleMonitor(2 * 60 * 1000); // 2 minutes
318

319
			const listener = idleMonitor.onStatusChange(status =>
K
kieferrm 已提交
320
				/* __GDPR__
K
kieferrm 已提交
321 322
					"UserIdleStart" : {}
				*/
K
kieferrm 已提交
323
				/* __GDPR__
K
kieferrm 已提交
324 325
					"UserIdleStop" : {}
				*/
326 327 328
				this.telemetryService.publicLog(status === UserStatus.Active
					? TelemetryService.IDLE_STOP_EVENT_NAME
					: TelemetryService.IDLE_START_EVENT_NAME
329
				));
330

J
Johannes Rieken 已提交
331
			disposables.push(telemetryService, errorTelemetry, listener, idleMonitor);
332
		} else {
333
			this.telemetryService = NullTelemetryService;
334
		}
E
Erich Gamma 已提交
335

336
		serviceCollection.set(ITelemetryService, this.telemetryService);
J
Johannes Rieken 已提交
337
		disposables.push(configurationTelemetry(this.telemetryService, this.configurationService));
E
Erich Gamma 已提交
338

339 340 341 342 343 344
		let crashReporterService = NullCrashReporterService;
		if (product.crashReporter && product.hockeyApp) {
			crashReporterService = instantiationService.createInstance(CrashReporterService);
		}
		serviceCollection.set(ICrashReporterService, crashReporterService);

345
		this.messageService = instantiationService.createInstance(MessageService, container);
346
		serviceCollection.set(IMessageService, this.messageService);
J
Joao Moreno 已提交
347
		serviceCollection.set(IChoiceService, this.messageService);
E
Erich Gamma 已提交
348

349
		const lifecycleService = instantiationService.createInstance(LifecycleService);
J
Johannes Rieken 已提交
350
		this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
351
		this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
352
		serviceCollection.set(ILifecycleService, lifecycleService);
J
Johannes Rieken 已提交
353
		disposables.push(lifecycleTelemetry(this.telemetryService, lifecycleService));
354
		this.lifecycleService = lifecycleService;
355

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

359 360
		const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
		serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
J
Johannes Rieken 已提交
361
		disposables.push(extensionEnablementService);
362

363
		this.extensionService = instantiationService.createInstance(ExtensionService);
364
		serviceCollection.set(IExtensionService, this.extensionService);
365 366

		this.timerService.beforeExtensionLoad = Date.now();
367
		this.extensionService.onReady().done(() => {
368
			this.timerService.afterExtensionLoad = Date.now();
369
		});
E
Erich Gamma 已提交
370

B
Benjamin Pasero 已提交
371 372 373
		this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
		serviceCollection.set(IWorkbenchThemeService, this.themeService);

374
		serviceCollection.set(ICommandService, new SyncDescriptor(CommandService));
375

376 377
		this.contextViewService = instantiationService.createInstance(ContextViewService, this.container);
		serviceCollection.set(IContextViewService, this.contextViewService);
E
Erich Gamma 已提交
378

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

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

383
		serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
384

385
		serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
386

387 388
		serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));

389
		serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
390

391
		serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
392

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

395
		serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
396

397
		serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorServiceImpl));
398

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

401
		return [instantiationService, serviceCollection];
E
Erich Gamma 已提交
402 403
	}

C
Christof Marti 已提交
404 405 406 407 408 409
	private sendMachineIdToMain(storageService: IStorageService) {
		getOrCreateMachineId(storageService).then(machineId => {
			ipc.send(machineIdIpcChannel, machineId);
		}).then(null, errors.onUnexpectedError);
	}

E
Erich Gamma 已提交
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
	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 {
440
		const errorMsg = toErrorMessage(error, true);
E
Erich Gamma 已提交
441 442 443 444
		if (!errorMsg) {
			return;
		}

445
		const now = Date.now();
E
Erich Gamma 已提交
446 447 448 449 450 451 452 453 454 455 456
		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
457
		if (error && error.friendlyMessage && this.messageService) {
B
Benjamin Pasero 已提交
458
			this.messageService.show(Severity.Error, error.friendlyMessage);
E
Erich Gamma 已提交
459 460 461
		}
	}

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

465
		const contentsSize = new Dimension(clArea.width, clArea.height);
E
Erich Gamma 已提交
466 467
		this.contentsContainer.size(contentsSize.width, contentsSize.height);

B
Benjamin Pasero 已提交
468
		this.contextViewService.layout();
E
Erich Gamma 已提交
469 470 471 472 473 474 475
		this.workbench.layout();
	}

	public joinCreation(): TPromise<boolean> {
		return this.workbench.joinCreation();
	}

B
Benjamin Pasero 已提交
476
	public dispose(): void {
E
Erich Gamma 已提交
477 478 479

		// Workbench
		if (this.workbench) {
B
Benjamin Pasero 已提交
480
			this.workbench.dispose();
E
Erich Gamma 已提交
481 482
		}

B
Benjamin Pasero 已提交
483
		this.contextViewService.dispose();
E
Erich Gamma 已提交
484 485

		// Listeners
J
Joao Moreno 已提交
486
		this.toUnbind = dispose(this.toUnbind);
E
Erich Gamma 已提交
487 488 489 490

		// Container
		$(this.container).empty();
	}
491
}
492 493

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

	// Foreground
B
Benjamin Pasero 已提交
496
	const windowForeground = theme.getColor(foreground);
497 498 499
	if (windowForeground) {
		collector.addRule(`.monaco-shell { color: ${windowForeground}; }`);
	}
B
Benjamin Pasero 已提交
500

501 502 503 504 505 506
	// Selection
	const windowSelectionBackground = theme.getColor(selectionBackground);
	if (windowSelectionBackground) {
		collector.addRule(`.monaco-shell ::selection { background-color: ${windowSelectionBackground}; }`);
	}

507 508 509 510 511 512 513
	// 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}; }`);
	}

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