shell.ts 24.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
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';
J
Johannes Rieken 已提交
34
import { WorkspaceStats } from 'vs/workbench/services/telemetry/common/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;
202 203 204
		this.telemetryService.publicLog('workspaceLoad', {
			userAgent: navigator.userAgent,
			windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
205
			emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY,
B
Benjamin Pasero 已提交
206 207 208
			'workbench.filesToOpen': filesToOpen && filesToOpen.length || void 0,
			'workbench.filesToCreate': filesToCreate && filesToCreate.length || void 0,
			'workbench.filesToDiff': filesToDiff && filesToDiff.length || void 0,
209
			customKeybindingsCount: info.customKeybindingsCount,
B
Benjamin Pasero 已提交
210
			theme: this.themeService.getColorTheme().id,
211
			language: platform.language,
212
			experiments: this.experimentService.getExperiments(),
213 214
			pinnedViewlets: info.pinnedViewlets,
			restoredViewlet: info.restoredViewlet,
215 216
			restoredEditors: info.restoredEditors.length,
			startupKind: this.lifecycleService.startupKind
217 218
		});

B
Benjamin Pasero 已提交
219
		// Telemetry: startup metrics
220
		this.timerService.workbenchStarted = Date.now();
B
Benjamin Pasero 已提交
221 222
		this.timerService.restoreEditorsDuration = info.restoreEditorsDuration;
		this.timerService.restoreViewletDuration = info.restoreViewletDuration;
223
		this.extensionService.onReady().done(() => {
B
Benjamin Pasero 已提交
224
			this.telemetryService.publicLog('startupTime', this.timerService.startupMetrics);
225
		});
B
Benjamin Pasero 已提交
226

227
		// Telemetry: workspace tags
228
		const workspaceStats: WorkspaceStats = <WorkspaceStats>this.workbench.getInstantiationService().createInstance(WorkspaceStats);
B
Benjamin Pasero 已提交
229
		workspaceStats.reportWorkspaceTags(this.configuration);
K
kieferrm 已提交
230
		workspaceStats.reportCloudStats();
J
Joao Moreno 已提交
231 232 233 234

		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 已提交
235 236
	}

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

240 241 242
		const serviceCollection = new ServiceCollection();
		serviceCollection.set(IWorkspaceContextService, this.contextService);
		serviceCollection.set(IConfigurationService, this.configurationService);
243
		serviceCollection.set(IEnvironmentService, this.environmentService);
B
Benjamin Pasero 已提交
244
		serviceCollection.set(ITimerService, this.timerService);
245
		serviceCollection.set(IStorageService, this.storageService);
246 247 248
		this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
			serviceCollection.set(serviceIdentifier, serviceInstance);
		});
249

250
		const instantiationService: IInstantiationService = new InstantiationService(serviceCollection, true);
251

252 253
		this.broadcastService = new BroadcastService(currentWindow.id);
		serviceCollection.set(IBroadcastService, this.broadcastService);
254

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

257
		const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
258
			.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${currentWindow.id}`));
259 260 261

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

263 264 265 266
		// Warm up font cache information before building up too many dom elements
		restoreFontInfo(this.storageService);
		readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getConfiguration('editor'), browser.getZoomLevel()));

267 268 269 270
		// Experiments
		this.experimentService = instantiationService.createInstance(ExperimentService);
		serviceCollection.set(IExperimentService, this.experimentService);

271
		// Telemetry
C
Christof Marti 已提交
272
		this.sendMachineIdToMain(this.storageService);
273
		if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !!product.enableTelemetry) {
274
			const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
275 276
			const commit = product.commit;
			const version = pkg.version;
277

278
			const config: ITelemetryServiceConfig = {
279
				appender: new TelemetryAppenderClient(channel),
280
				commonProperties: resolveWorkbenchCommonProperties(this.storageService, commit, version),
281
				piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath]
282
			};
283

J
Joao Moreno 已提交
284
			const telemetryService = instantiationService.createInstance(TelemetryService, config);
285 286
			this.telemetryService = telemetryService;

J
Joao Moreno 已提交
287
			const errorTelemetry = new ErrorTelemetry(telemetryService);
288
			const idleMonitor = new IdleMonitor(2 * 60 * 1000); // 2 minutes
289

290 291 292 293
			const listener = idleMonitor.onStatusChange(status =>
				this.telemetryService.publicLog(status === UserStatus.Active
					? TelemetryService.IDLE_STOP_EVENT_NAME
					: TelemetryService.IDLE_START_EVENT_NAME
294
				));
295

J
Johannes Rieken 已提交
296
			disposables.push(telemetryService, errorTelemetry, listener, idleMonitor);
297
		} else {
298
			this.telemetryService = NullTelemetryService;
299
		}
E
Erich Gamma 已提交
300

301
		serviceCollection.set(ITelemetryService, this.telemetryService);
J
Johannes Rieken 已提交
302
		disposables.push(configurationTelemetry(this.telemetryService, this.configurationService));
E
Erich Gamma 已提交
303

304 305 306 307 308 309
		let crashReporterService = NullCrashReporterService;
		if (product.crashReporter && product.hockeyApp) {
			crashReporterService = instantiationService.createInstance(CrashReporterService);
		}
		serviceCollection.set(ICrashReporterService, crashReporterService);

310
		this.messageService = instantiationService.createInstance(MessageService, container);
311
		serviceCollection.set(IMessageService, this.messageService);
J
Joao Moreno 已提交
312
		serviceCollection.set(IChoiceService, this.messageService);
E
Erich Gamma 已提交
313

314
		const lifecycleService = instantiationService.createInstance(LifecycleService);
J
Johannes Rieken 已提交
315
		this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
316
		this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
317
		serviceCollection.set(ILifecycleService, lifecycleService);
J
Johannes Rieken 已提交
318
		disposables.push(lifecycleTelemetry(this.telemetryService, lifecycleService));
319
		this.lifecycleService = lifecycleService;
320

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

324 325
		const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
		serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
J
Johannes Rieken 已提交
326
		disposables.push(extensionEnablementService);
327

328
		this.extensionService = instantiationService.createInstance(ExtensionService);
329
		serviceCollection.set(IExtensionService, this.extensionService);
330 331

		this.timerService.beforeExtensionLoad = Date.now();
332
		this.extensionService.onReady().done(() => {
333
			this.timerService.afterExtensionLoad = Date.now();
334
		});
E
Erich Gamma 已提交
335

B
Benjamin Pasero 已提交
336 337 338
		this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
		serviceCollection.set(IWorkbenchThemeService, this.themeService);

339
		serviceCollection.set(ICommandService, new SyncDescriptor(CommandService));
340

341 342
		this.contextViewService = instantiationService.createInstance(ContextViewService, this.container);
		serviceCollection.set(IContextViewService, this.contextViewService);
E
Erich Gamma 已提交
343

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

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

348
		serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
349

350
		serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
351

352 353
		serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));

354
		serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
355

356
		serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
357

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

360
		serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
361

362
		serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorServiceImpl));
363

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

366
		return [instantiationService, serviceCollection];
E
Erich Gamma 已提交
367 368
	}

C
Christof Marti 已提交
369 370 371 372 373 374
	private sendMachineIdToMain(storageService: IStorageService) {
		getOrCreateMachineId(storageService).then(machineId => {
			ipc.send(machineIdIpcChannel, machineId);
		}).then(null, errors.onUnexpectedError);
	}

E
Erich Gamma 已提交
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
	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 {
405
		const errorMsg = toErrorMessage(error, true);
E
Erich Gamma 已提交
406 407 408 409
		if (!errorMsg) {
			return;
		}

410
		const now = Date.now();
E
Erich Gamma 已提交
411 412 413 414 415 416 417 418 419 420 421
		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
422
		if (error && error.friendlyMessage && this.messageService) {
B
Benjamin Pasero 已提交
423
			this.messageService.show(Severity.Error, error.friendlyMessage);
E
Erich Gamma 已提交
424 425 426
		}
	}

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

430
		const contentsSize = new Dimension(clArea.width, clArea.height);
E
Erich Gamma 已提交
431 432
		this.contentsContainer.size(contentsSize.width, contentsSize.height);

B
Benjamin Pasero 已提交
433
		this.contextViewService.layout();
E
Erich Gamma 已提交
434 435 436 437 438 439 440
		this.workbench.layout();
	}

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

B
Benjamin Pasero 已提交
441
	public dispose(): void {
E
Erich Gamma 已提交
442 443 444

		// Workbench
		if (this.workbench) {
B
Benjamin Pasero 已提交
445
			this.workbench.dispose();
E
Erich Gamma 已提交
446 447
		}

B
Benjamin Pasero 已提交
448
		this.contextViewService.dispose();
E
Erich Gamma 已提交
449 450

		// Listeners
J
Joao Moreno 已提交
451
		this.toUnbind = dispose(this.toUnbind);
E
Erich Gamma 已提交
452 453 454 455

		// Container
		$(this.container).empty();
	}
456
}
457 458

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

	// Foreground
B
Benjamin Pasero 已提交
461
	const windowForeground = theme.getColor(foreground);
462 463 464
	if (windowForeground) {
		collector.addRule(`.monaco-shell { color: ${windowForeground}; }`);
	}
B
Benjamin Pasero 已提交
465

466 467 468 469 470 471
	// Selection
	const windowSelectionBackground = theme.getColor(selectionBackground);
	if (windowSelectionBackground) {
		collector.addRule(`.monaco-shell ::selection { background-color: ${windowSelectionBackground}; }`);
	}

472 473 474 475 476 477 478
	// 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}; }`);
	}

479 480 481 482 483 484 485 486 487 488 489
	// 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 已提交
490
	// We need to set the workbench background color so that on Windows we get subpixel-antialiasing.
491 492 493 494 495 496 497 498 499 500 501 502 503
	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 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
	// 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
550
	const focusOutline = theme.getColor(focusBorder);
B
Benjamin Pasero 已提交
551 552 553 554 555 556 557 558
	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 已提交
559
			.monaco-shell button:focus,
B
Benjamin Pasero 已提交
560 561 562 563 564 565 566
			.monaco-shell textarea:focus,
			.monaco-shell input[type="search"]:focus,
			.monaco-shell input[type="checkbox"]:focus {
				outline-color: ${focusOutline};
			}
		`);
	}
567
});