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

import 'vs/css!./media/activityaction';
7 8
import { localize } from 'vs/nls';
import { EventType, addDisposableListener, EventHelper } from 'vs/base/browser/dom';
P
Pine Wu 已提交
9
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
B
Benjamin Pasero 已提交
10
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
11
import { Action, IAction, Separator, SubmenuAction, toAction } from 'vs/base/common/actions';
P
Pine Wu 已提交
12
import { KeyCode } from 'vs/base/common/keyCodes';
13 14
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IMenuService, MenuId, IMenu, registerAction2, Action2, IAction2Options } from 'vs/platform/actions/common/actions';
15
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
P
Pine Wu 已提交
16 17
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
18
import { IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
19
import { ActivityAction, ActivityActionViewItem, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
20
import { CATEGORIES } from 'vs/workbench/common/actions';
21
import { IActivity } from 'vs/workbench/common/activity';
22
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_BACKGROUND } from 'vs/workbench/common/theme';
23
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
24
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
P
Pine Wu 已提交
25
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
26
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
27
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
S
SteVen Batten 已提交
28
import { isMacintosh, isWeb } from 'vs/base/common/platform';
29
import { getCurrentAuthenticationSessionInfo, IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
30 31
import { AuthenticationSession } from 'vs/editor/common/modes';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
S
SteVen Batten 已提交
32
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
S
Sandeep Somavarapu 已提交
33
import { IProductService } from 'vs/platform/product/common/productService';
34
import { AnchorAlignment, AnchorAxisAlignment } from 'vs/base/browser/ui/contextview/contextview';
35
import { getTitleBarStyle } from 'vs/platform/windows/common/windows';
36
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
37
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
E
Erich Gamma 已提交
38

39
export class ViewContainerActivityAction extends ActivityAction {
40

41
	private static readonly preventDoubleClickDelay = 300;
42

43
	private lastRun = 0;
44 45

	constructor(
46
		activity: IActivity,
47 48 49 50
		@IViewletService private readonly viewletService: IViewletService,
		@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
		@ITelemetryService private readonly telemetryService: ITelemetryService,
		@IConfigurationService private readonly configurationService: IConfigurationService
51
	) {
52
		super(activity);
S
Sandeep Somavarapu 已提交
53 54
	}

55
	updateActivity(activity: IActivity): void {
S
Sandeep Somavarapu 已提交
56
		this.activity = activity;
57 58
	}

59
	async run(event: unknown): Promise<void> {
60
		if (event instanceof MouseEvent && event.button === 2) {
61
			return; // do not run on right click
62 63 64 65
		}

		// prevent accident trigger on a doubleclick (to help nervous people)
		const now = Date.now();
C
ChaseKnowlden 已提交
66
		if (now > this.lastRun /* https://github.com/microsoft/vscode/issues/25830 */ && now - this.lastRun < ViewContainerActivityAction.preventDoubleClickDelay) {
67
			return;
68 69 70
		}
		this.lastRun = now;

71
		const sideBarVisible = this.layoutService.isVisible(Parts.SIDEBAR_PART);
72
		const activeViewlet = this.viewletService.getActiveViewlet();
S
SteVen Batten 已提交
73
		const focusBehavior = this.configurationService.getValue<string>('workbench.activityBar.iconClickBehavior');
74

B
Benjamin Pasero 已提交
75
		if (sideBarVisible && activeViewlet?.getId() === this.activity.id) {
S
SteVen Batten 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88
			switch (focusBehavior) {
				case 'focus':
					this.logAction('refocus');
					this.viewletService.openViewlet(this.activity.id, true);
					break;
				case 'toggle':
				default:
					// Hide sidebar if selected viewlet already visible
					this.logAction('hide');
					this.layoutService.setSideBarHidden(true);
					break;
			}

89
			return;
90 91
		}

92
		this.logAction('show');
93
		await this.viewletService.openViewlet(this.activity.id, true);
94

95
		return this.activate();
96
	}
97 98

	private logAction(action: string) {
99
		type ActivityBarActionClassification = {
100 101
			viewletId: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
			action: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
102
		};
103
		this.telemetryService.publicLog2<{ viewletId: String, action: String; }, ActivityBarActionClassification>('activityBarAction', { viewletId: this.activity.id, action });
104
	}
105 106
}

107
class MenuActivityActionViewItem extends ActivityActionViewItem {
108

109
	constructor(
110
		private readonly menuId: MenuId,
111
		action: ActivityAction,
112
		private contextMenuActionsProvider: () => IAction[],
113 114
		colors: (theme: IColorTheme) => ICompositeBarColors,
		@IThemeService themeService: IThemeService,
115 116 117 118 119
		@IMenuService protected readonly menuService: IMenuService,
		@IContextMenuService protected readonly contextMenuService: IContextMenuService,
		@IContextKeyService protected readonly contextKeyService: IContextKeyService,
		@IConfigurationService protected readonly configurationService: IConfigurationService,
		@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService
120 121 122 123 124 125 126 127 128 129
	) {
		super(action, { draggable: false, colors, icon: true }, themeService);
	}

	render(container: HTMLElement): void {
		super.render(container);

		// Context menus are triggered on mouse down so that an item can be picked
		// and executed with releasing the mouse over it

130 131
		this._register(addDisposableListener(this.container, EventType.MOUSE_DOWN, (e: MouseEvent) => {
			EventHelper.stop(e, true);
132
			this.showContextMenu(e);
133 134
		}));

135
		this._register(addDisposableListener(this.container, EventType.KEY_UP, (e: KeyboardEvent) => {
136 137
			let event = new StandardKeyboardEvent(e);
			if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
138
				EventHelper.stop(e, true);
139 140 141 142
				this.showContextMenu();
			}
		}));

143 144
		this._register(addDisposableListener(this.container, TouchEventType.Tap, (e: GestureEvent) => {
			EventHelper.stop(e, true);
145 146 147 148
			this.showContextMenu();
		}));
	}

149
	private async showContextMenu(e?: MouseEvent): Promise<void> {
150 151
		const disposables = new DisposableStore();

152 153 154 155 156
		let actions: IAction[];
		if (e?.button !== 2) {
			const menu = disposables.add(this.menuService.createMenu(this.menuId, this.contextKeyService));
			actions = await this.resolveMainMenuActions(menu, disposables);
		} else {
157
			actions = await this.resolveContextMenuActions(disposables);
158
		}
159

R
Robo 已提交
160
		const isUsingCustomMenu = isWeb || (getTitleBarStyle(this.configurationService) !== 'native' && !isMacintosh); // see #40262
161 162 163 164 165 166 167 168 169 170 171
		const position = this.configurationService.getValue('workbench.sideBar.location');

		this.contextMenuService.showContextMenu({
			getAnchor: () => isUsingCustomMenu ? this.container : e || this.container,
			anchorAlignment: isUsingCustomMenu ? (position === 'left' ? AnchorAlignment.RIGHT : AnchorAlignment.LEFT) : undefined,
			anchorAxisAlignment: isUsingCustomMenu ? AnchorAxisAlignment.HORIZONTAL : AnchorAxisAlignment.VERTICAL,
			getActions: () => actions,
			onHide: () => disposables.dispose()
		});
	}

172
	protected async resolveMainMenuActions(menu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
173 174 175 176 177 178
		const actions: IAction[] = [];

		disposables.add(createAndFillInActionBarActions(menu, undefined, { primary: [], secondary: actions }));

		return actions;
	}
179

180
	protected async resolveContextMenuActions(disposables: DisposableStore): Promise<IAction[]> {
181 182
		return this.contextMenuActionsProvider();
	}
183 184 185 186 187 188 189 190 191
}

export class HomeActivityActionViewItem extends MenuActivityActionViewItem {

	static readonly HOME_BAR_VISIBILITY_PREFERENCE = 'workbench.activity.showHomeIndicator';

	constructor(
		private readonly goHomeHref: string,
		action: ActivityAction,
192
		contextMenuActionsProvider: () => IAction[],
193 194 195 196 197 198
		colors: (theme: IColorTheme) => ICompositeBarColors,
		@IThemeService themeService: IThemeService,
		@IMenuService menuService: IMenuService,
		@IContextMenuService contextMenuService: IContextMenuService,
		@IContextKeyService contextKeyService: IContextKeyService,
		@IConfigurationService configurationService: IConfigurationService,
199 200
		@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
		@IStorageService private readonly storageService: IStorageService
201
	) {
202
		super(MenuId.MenubarHomeMenu, action, contextMenuActionsProvider, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
203 204
	}

205
	protected async resolveMainMenuActions(homeMenu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
206 207 208
		const actions = [];

		// Go Home
209
		actions.push(toAction({ id: 'goHome', label: localize('goHome', "Go Home"), run: () => window.location.href = this.goHomeHref }));
210 211

		// Contributed
212
		const contributedActions = await super.resolveMainMenuActions(homeMenu, disposables);
213
		if (contributedActions.length) {
214
			actions.push(disposables.add(new Separator()));
215
			actions.push(...contributedActions);
216 217 218 219
		}

		return actions;
	}
220 221 222 223 224

	protected async resolveContextMenuActions(disposables: DisposableStore): Promise<IAction[]> {
		const actions = await super.resolveContextMenuActions(disposables);

		actions.unshift(...[
225
			toAction({ id: 'hideHomeButton', label: localize('hideHomeButton', "Hide Home Button"), run: () => this.storageService.store(HomeActivityActionViewItem.HOME_BAR_VISIBILITY_PREFERENCE, false, StorageScope.GLOBAL, StorageTarget.USER) }),
226 227 228 229 230
			new Separator()
		]);

		return actions;
	}
231 232 233 234 235 236 237 238
}

export class AccountsActivityActionViewItem extends MenuActivityActionViewItem {

	static readonly ACCOUNTS_VISIBILITY_PREFERENCE_KEY = 'workbench.activity.showAccounts';

	constructor(
		action: ActivityAction,
239
		contextMenuActionsProvider: () => IAction[],
240 241 242 243 244 245 246 247 248
		colors: (theme: IColorTheme) => ICompositeBarColors,
		@IThemeService themeService: IThemeService,
		@IContextMenuService contextMenuService: IContextMenuService,
		@IMenuService menuService: IMenuService,
		@IContextKeyService contextKeyService: IContextKeyService,
		@IAuthenticationService private readonly authenticationService: IAuthenticationService,
		@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
		@IProductService private readonly productService: IProductService,
		@IConfigurationService configurationService: IConfigurationService,
249
		@IStorageService private readonly storageService: IStorageService
250
	) {
251
		super(MenuId.AccountsContext, action, contextMenuActionsProvider, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
252 253
	}

254 255
	protected async resolveMainMenuActions(accountsMenu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
		await super.resolveMainMenuActions(accountsMenu, disposables);
256

257 258
		const otherCommands = accountsMenu.getActions();
		const providers = this.authenticationService.getProviderIds();
259
		const allSessions = providers.map(async providerId => {
R
Rachel Macfarlane 已提交
260
			try {
261
				const sessions = await this.authenticationService.getSessions(providerId);
R
Rachel Macfarlane 已提交
262

263
				const groupedSessions: { [label: string]: AuthenticationSession[]; } = {};
R
Rachel Macfarlane 已提交
264 265 266 267 268 269 270 271
				sessions.forEach(session => {
					if (groupedSessions[session.account.label]) {
						groupedSessions[session.account.label].push(session);
					} else {
						groupedSessions[session.account.label] = [session];
					}
				});

272
				return { providerId, sessions: groupedSessions };
R
Rachel Macfarlane 已提交
273
			} catch {
274
				return { providerId };
R
Rachel Macfarlane 已提交
275
			}
276 277 278
		});

		const result = await Promise.all(allSessions);
279
		let menus: IAction[] = [];
280
		const authenticationSession = this.environmentService.options?.credentialsProvider ? await getCurrentAuthenticationSessionInfo(this.environmentService, this.productService) : undefined;
281
		result.forEach(sessionInfo => {
282
			const providerDisplayName = this.authenticationService.getLabel(sessionInfo.providerId);
283

R
Rachel Macfarlane 已提交
284 285
			if (sessionInfo.sessions) {
				Object.keys(sessionInfo.sessions).forEach(accountName => {
286
					const manageExtensionsAction = disposables.add(new Action(`configureSessions${accountName}`, localize('manageTrustedExtensions', "Manage Trusted Extensions"), '', true, () => {
R
Rachel Macfarlane 已提交
287
						return this.authenticationService.manageTrustedExtensionsForAccount(sessionInfo.providerId, accountName);
288 289
					}));

290
					const signOutAction = disposables.add(new Action('signOut', localize('signOut', "Sign Out"), '', true, () => {
R
Rachel Macfarlane 已提交
291
						return this.authenticationService.signOutOfAccount(sessionInfo.providerId, accountName);
292 293 294
					}));

					const providerSubMenuActions = [manageExtensionsAction];
R
Rachel Macfarlane 已提交
295

296
					const hasEmbedderAccountSession = sessionInfo.sessions[accountName].some(session => session.id === (authenticationSession?.id));
297
					if (!hasEmbedderAccountSession || authenticationSession?.canSignOut) {
298
						providerSubMenuActions.push(signOutAction);
299
					}
300

301 302
					const providerSubMenu = disposables.add(new SubmenuAction('activitybar.submenu', `${accountName} (${providerDisplayName})`, providerSubMenuActions));
					menus.push(providerSubMenu);
R
Rachel Macfarlane 已提交
303 304
				});
			} else {
305
				const providerUnavailableAction = disposables.add(new Action('providerUnavailable', localize('authProviderUnavailable', '{0} is currently unavailable', providerDisplayName)));
306
				menus.push(providerUnavailableAction);
R
Rachel Macfarlane 已提交
307
			}
308 309
		});

R
Rachel Macfarlane 已提交
310
		if (menus.length && otherCommands.length) {
311
			menus.push(disposables.add(new Separator()));
312 313
		}

314
		otherCommands.forEach((group, i) => {
315 316
			const actions = group[1];
			menus = menus.concat(actions);
317
			if (i !== otherCommands.length - 1) {
318
				menus.push(disposables.add(new Separator()));
319
			}
320 321 322 323
		});

		return menus;
	}
324 325 326 327 328

	protected async resolveContextMenuActions(disposables: DisposableStore): Promise<IAction[]> {
		const actions = await super.resolveContextMenuActions(disposables);

		actions.unshift(...[
329
			toAction({ id: 'hideAccounts', label: localize('hideAccounts', "Hide Accounts"), run: () => this.storageService.store(AccountsActivityActionViewItem.ACCOUNTS_VISIBILITY_PREFERENCE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER) }),
330 331 332 333 334
			new Separator()
		]);

		return actions;
	}
335 336
}

337
export class GlobalActivityActionViewItem extends MenuActivityActionViewItem {
B
Benjamin Pasero 已提交
338 339

	constructor(
340
		action: ActivityAction,
341
		contextMenuActionsProvider: () => IAction[],
M
Martin Aeschlimann 已提交
342
		colors: (theme: IColorTheme) => ICompositeBarColors,
B
Benjamin Pasero 已提交
343
		@IThemeService themeService: IThemeService,
344 345 346 347 348
		@IMenuService menuService: IMenuService,
		@IContextMenuService contextMenuService: IContextMenuService,
		@IContextKeyService contextKeyService: IContextKeyService,
		@IConfigurationService configurationService: IConfigurationService,
		@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
B
Benjamin Pasero 已提交
349
	) {
350
		super(MenuId.GlobalActivity, action, contextMenuActionsProvider, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
B
Benjamin Pasero 已提交
351 352 353
	}
}

354
export class PlaceHolderViewContainerActivityAction extends ViewContainerActivityAction { }
B
Benjamin Pasero 已提交
355

356
export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinnedAction {
B
Benjamin Pasero 已提交
357 358

	constructor(id: string, compositeBar: ICompositeBar) {
R
Rob Lourens 已提交
359
		super({ id, name: id, cssClass: undefined }, compositeBar);
B
Benjamin Pasero 已提交
360 361 362 363 364 365 366
	}

	setActivity(activity: IActivity): void {
		this.label = activity.name;
	}
}

367
class SwitchSideBarViewAction extends Action2 {
P
Pine Wu 已提交
368 369

	constructor(
370 371
		desc: Readonly<IAction2Options>,
		private readonly offset: number
P
Pine Wu 已提交
372
	) {
373
		super(desc);
P
Pine Wu 已提交
374 375
	}

376 377 378
	async run(accessor: ServicesAccessor): Promise<void> {
		const activityBarService = accessor.get(IActivityBarService);
		const viewletService = accessor.get(IViewletService);
P
Pine Wu 已提交
379

380 381 382
		const visibleViewletIds = activityBarService.getVisibleViewContainerIds();

		const activeViewlet = viewletService.getActiveViewlet();
P
Pine Wu 已提交
383
		if (!activeViewlet) {
384
			return;
P
Pine Wu 已提交
385
		}
M
Matt Bierner 已提交
386
		let targetViewletId: string | undefined;
S
SteVen Batten 已提交
387 388
		for (let i = 0; i < visibleViewletIds.length; i++) {
			if (visibleViewletIds[i] === activeViewlet.getId()) {
389
				targetViewletId = visibleViewletIds[(i + visibleViewletIds.length + this.offset) % visibleViewletIds.length];
P
Pine Wu 已提交
390 391 392
				break;
			}
		}
393

394
		await viewletService.openViewlet(targetViewletId, true);
P
Pine Wu 已提交
395 396 397
	}
}

398 399 400 401 402
registerAction2(
	class PreviousSideBarViewAction extends SwitchSideBarViewAction {
		constructor() {
			super({
				id: 'workbench.action.previousSideBarView',
403
				title: { value: localize('previousSideBarView', "Previous Side Bar View"), original: 'Previous Side Bar View' },
404 405 406
				category: CATEGORIES.View,
				f1: true
			}, -1);
407 408
		}
	}
409 410 411 412 413 414 415
);

registerAction2(
	class NextSideBarViewAction extends SwitchSideBarViewAction {
		constructor() {
			super({
				id: 'workbench.action.nextSideBarView',
416
				title: { value: localize('nextSideBarView', "Next Side Bar View"), original: 'Next Side Bar View' },
417 418 419 420
				category: CATEGORIES.View,
				f1: true
			}, 1);
		}
B
Benjamin Pasero 已提交
421
	}
422
);
P
Pine Wu 已提交
423

424
registerThemingParticipant((theme, collector) => {
425 426 427 428 429 430 431 432
	const activityBarBackgroundColor = theme.getColor(ACTIVITY_BAR_BACKGROUND);
	if (activityBarBackgroundColor) {
		collector.addRule(`
			.monaco-workbench .activitybar > .content > .home-bar > .home-bar-icon-badge {
				background-color: ${activityBarBackgroundColor};
			}
		`);
	}
433

434 435
	const activityBarForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
	if (activityBarForegroundColor) {
436
		collector.addRule(`
M
Miguel Solorio 已提交
437 438 439
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label:not(.codicon),
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label:not(.codicon),
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label:not(.codicon) {
440
				background-color: ${activityBarForegroundColor} !important;
441
			}
B
Benjamin Pasero 已提交
442
			.monaco-workbench .activitybar > .content .home-bar > .monaco-action-bar .action-item .action-label.codicon,
M
Miguel Solorio 已提交
443 444 445
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label.codicon,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label.codicon,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.codicon {
446
				color: ${activityBarForegroundColor} !important;
M
Miguel Solorio 已提交
447
			}
448 449 450
		`);
	}

451 452
	const activityBarActiveBorderColor = theme.getColor(ACTIVITY_BAR_ACTIVE_BORDER);
	if (activityBarActiveBorderColor) {
453
		collector.addRule(`
454
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked .active-item-indicator:before {
455
				border-left-color: ${activityBarActiveBorderColor};
456 457 458 459
			}
		`);
	}

460 461
	const activityBarActiveFocusBorderColor = theme.getColor(ACTIVITY_BAR_ACTIVE_FOCUS_BORDER);
	if (activityBarActiveFocusBorderColor) {
462 463 464 465 466 467 468
		collector.addRule(`
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:focus::before {
				visibility: hidden;
			}

			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:focus .active-item-indicator:before {
				visibility: visible;
469
				border-left-color: ${activityBarActiveFocusBorderColor};
470 471 472 473
			}
		`);
	}

474 475
	const activityBarActiveBackgroundColor = theme.getColor(ACTIVITY_BAR_ACTIVE_BACKGROUND);
	if (activityBarActiveBackgroundColor) {
476
		collector.addRule(`
477
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked .active-item-indicator {
478
				z-index: 0;
479
				background-color: ${activityBarActiveBackgroundColor};
480 481 482 483
			}
		`);
	}

484
	// Styling with Outline color (e.g. high contrast theme)
485
	const outline = theme.getColor(activeContrastBorder);
486 487
	if (outline) {
		collector.addRule(`
S
SteVen Batten 已提交
488
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:before {
489 490
				content: "";
				position: absolute;
491 492 493
				top: 9px;
				left: 9px;
				height: 32px;
494
				width: 32px;
M
Miguel Solorio 已提交
495
				z-index: 1;
496 497
			}

S
SteVen Batten 已提交
498 499 500 501
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active:hover:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:hover:before {
502 503 504
				outline: 1px solid;
			}

S
SteVen Batten 已提交
505
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover:before {
506 507 508
				outline: 1px dashed;
			}

S
SteVen Batten 已提交
509
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus:before {
510 511 512
				border-left-color: ${outline};
			}

S
SteVen Batten 已提交
513 514 515 516 517
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active:hover:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked:hover:before,
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover:before {
518 519 520 521 522 523 524
				outline-color: ${outline};
			}
		`);
	}

	// Styling without outline color
	else {
525
		const focusBorderColor = theme.getColor(focusBorder);
526 527
		if (focusBorderColor) {
			collector.addRule(`
S
SteVen Batten 已提交
528
					.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus:before {
529 530 531
						border-left-color: ${focusBorderColor};
					}
				`);
532
		}
533
	}
534
});