Skip to content

Commit b8559c1

Browse files
authored
upon create send over the list of existing status bar items and their props (microsoft#183219)
microsoft#167874
1 parent 545faa5 commit b8559c1

File tree

5 files changed

+74
-30
lines changed

5 files changed

+74
-30
lines changed

src/vs/workbench/api/browser/mainThreadStatusBar.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,42 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { MainThreadStatusBarShape, MainContext } from '../common/extHost.protocol';
6+
import { MainThreadStatusBarShape, MainContext, ExtHostContext, StatusBarItemDto } from '../common/extHost.protocol';
77
import { ThemeColor } from 'vs/base/common/themables';
88
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
99
import { DisposableMap } from 'vs/base/common/lifecycle';
1010
import { Command } from 'vs/editor/common/languages';
1111
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
1212
import { IMarkdownString } from 'vs/base/common/htmlContent';
1313
import { IExtensionStatusBarItemService } from 'vs/workbench/api/browser/statusBarExtensionPoint';
14+
import { StatusbarAlignment } from 'vs/workbench/services/statusbar/browser/statusbar';
1415

1516
@extHostNamedCustomer(MainContext.MainThreadStatusBar)
1617
export class MainThreadStatusBar implements MainThreadStatusBarShape {
1718

1819
private readonly entries = new DisposableMap<string>();
1920

2021
constructor(
21-
_extHostContext: IExtHostContext,
22+
extHostContext: IExtHostContext,
2223
@IExtensionStatusBarItemService private readonly statusbarService: IExtensionStatusBarItemService
23-
) { }
24+
) {
25+
const proxy = extHostContext.getProxy(ExtHostContext.ExtHostStatusBar);
26+
27+
// once, at startup read existing items and send them over
28+
const entries: StatusBarItemDto[] = [];
29+
for (const [entryId, item] of statusbarService.getEntries()) {
30+
entries.push({
31+
entryId,
32+
name: item.entry.name,
33+
text: item.entry.text,
34+
command: typeof item.entry.command === 'string' ? item.entry.command : undefined,
35+
priority: item.priority,
36+
alignLeft: item.alignment === StatusbarAlignment.LEFT
37+
});
38+
}
39+
40+
proxy.$acceptStaticEntries(entries);
41+
}
2442

2543
dispose(): void {
2644
this.entries.dispose();
@@ -33,11 +51,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
3351
}
3452
}
3553

36-
async $hasEntry(entryId: string): Promise<boolean> {
37-
return this.statusbarService.hasEntry(entryId);
38-
}
39-
40-
$dispose(entryId: string) {
54+
$disposeEntry(entryId: string) {
4155
this.entries.deleteAndDispose(entryId);
4256
}
4357
}

src/vs/workbench/api/browser/statusBarExtensionPoint.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,25 @@ import { asStatusBarItemIdentifier } from 'vs/workbench/api/common/extHostTypes'
2626

2727
export const IExtensionStatusBarItemService = createDecorator<IExtensionStatusBarItemService>('IExtensionStatusBarItemService');
2828

29+
export interface IExtensionStatusBarItemChangeEvent {
30+
readonly added?: Readonly<{ entryId: string } & IStatusbarEntry>;
31+
readonly removed?: string;
32+
}
33+
2934
export interface IExtensionStatusBarItemService {
3035
readonly _serviceBrand: undefined;
3136

3237
setOrUpdateEntry(id: string, statusId: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): IDisposable;
3338

34-
hasEntry(id: string): boolean;
39+
getEntries(): Iterable<[string, { entry: IStatusbarEntry; alignment: MainThreadStatusBarAlignment; priority: number }]>;
3540
}
3641

3742

3843
class ExtensionStatusBarItemService implements IExtensionStatusBarItemService {
3944

4045
declare readonly _serviceBrand: undefined;
4146

42-
private readonly _entries: Map<string, { accessor: IStatusbarEntryAccessor; alignment: MainThreadStatusBarAlignment; priority: number }> = new Map();
47+
private readonly _entries: Map<string, { accessor: IStatusbarEntryAccessor; entry: IStatusbarEntry; alignment: MainThreadStatusBarAlignment; priority: number }> = new Map();
4348

4449
constructor(@IStatusbarService private readonly _statusbarService: IStatusbarService) { }
4550

@@ -88,13 +93,15 @@ class ExtensionStatusBarItemService implements IExtensionStatusBarItemService {
8893

8994
this._entries.set(entryId, {
9095
accessor: this._statusbarService.addEntry(entry, id, alignment, entryPriority),
96+
entry,
9197
alignment,
9298
priority
9399
});
94100

95101
} else {
96102
// Otherwise update
97103
existingEntry.accessor.update(entry);
104+
existingEntry.entry = entry;
98105
}
99106

100107
return toDisposable(() => {
@@ -106,8 +113,8 @@ class ExtensionStatusBarItemService implements IExtensionStatusBarItemService {
106113
});
107114
}
108115

109-
hasEntry(id: string): boolean {
110-
return this._entries.has(id);
116+
getEntries(): Iterable<[string, { entry: IStatusbarEntry; alignment: MainThreadStatusBarAlignment; priority: number }]> {
117+
return this._entries.entries();
111118
}
112119
}
113120

src/vs/workbench/api/common/extHost.api.impl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
206206
const extHostChat = rpcProtocol.set(ExtHostContext.ExtHostChat, new ExtHostChat(rpcProtocol, extHostLogService));
207207
const extHostSemanticSimilarity = rpcProtocol.set(ExtHostContext.ExtHostSemanticSimilarity, new ExtHostSemanticSimilarity(rpcProtocol));
208208
const extHostIssueReporter = rpcProtocol.set(ExtHostContext.ExtHostIssueReporter, new ExtHostIssueReporter(rpcProtocol));
209+
const extHostStatusBar = rpcProtocol.set(ExtHostContext.ExtHostStatusBar, new ExtHostStatusBar(rpcProtocol, extHostCommands.converter));
209210

210211
// Check that no named customers are missing
211212
const expected = Object.values<ProxyIdentifier<any>>(ExtHostContext);
@@ -216,7 +217,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
216217
const extHostClipboard = new ExtHostClipboard(rpcProtocol);
217218
const extHostMessageService = new ExtHostMessageService(rpcProtocol, extHostLogService);
218219
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
219-
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol, extHostCommands.converter);
220220

221221
// Register API-ish commands
222222
ExtHostApiCommands.register(extHostCommands);

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,21 @@ export interface MainThreadQuickOpenShape extends IDisposable {
614614
}
615615

616616
export interface MainThreadStatusBarShape extends IDisposable {
617-
$hasEntry(id: string): Promise<boolean>;
618617
$setEntry(id: string, statusId: string, extensionId: string | undefined, statusName: string, text: string, tooltip: IMarkdownString | string | undefined, command: ICommandDto | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): void;
619-
$dispose(id: string): void;
618+
$disposeEntry(id: string): void;
619+
}
620+
621+
export type StatusBarItemDto = {
622+
entryId: string;
623+
alignLeft: boolean;
624+
priority?: number;
625+
name: string;
626+
text: string;
627+
command?: string;
628+
};
629+
630+
export interface ExtHostStatusBarShape {
631+
$acceptStaticEntries(added?: StatusBarItemDto[]): void;
620632
}
621633

622634
export interface MainThreadStorageShape extends IDisposable {
@@ -2580,6 +2592,7 @@ export const ExtHostContext = {
25802592
ExtHostLanguageFeatures: createProxyIdentifier<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),
25812593
ExtHostQuickOpen: createProxyIdentifier<ExtHostQuickOpenShape>('ExtHostQuickOpen'),
25822594
ExtHostQuickDiff: createProxyIdentifier<ExtHostQuickDiffShape>('ExtHostQuickDiff'),
2595+
ExtHostStatusBar: createProxyIdentifier<ExtHostStatusBarShape>('ExtHostStatusBar'),
25832596
ExtHostShare: createProxyIdentifier<ExtHostShareShape>('ExtHostShare'),
25842597
ExtHostExtensionService: createProxyIdentifier<ExtHostExtensionServiceShape>('ExtHostExtensionService'),
25852598
ExtHostLogLevelServiceShape: createProxyIdentifier<ExtHostLogLevelServiceShape>('ExtHostLogLevelServiceShape'),

src/vs/workbench/api/common/extHostStatusBar.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { StatusBarAlignment as ExtHostStatusBarAlignment, Disposable, ThemeColor, asStatusBarItemIdentifier } from './extHostTypes';
77
import type * as vscode from 'vscode';
8-
import { MainContext, MainThreadStatusBarShape, IMainContext, ICommandDto } from './extHost.protocol';
8+
import { MainContext, MainThreadStatusBarShape, IMainContext, ICommandDto, ExtHostStatusBarShape, StatusBarItemDto } from './extHost.protocol';
99
import { localize } from 'vs/nls';
1010
import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
1111
import { DisposableStore } from 'vs/base/common/lifecycle';
@@ -54,22 +54,25 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
5454
private _timeoutHandle: any;
5555
private _accessibilityInformation?: vscode.AccessibilityInformation;
5656

57-
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, extension: IExtensionDescription, id?: string, alignment?: ExtHostStatusBarAlignment, priority?: number);
58-
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, extension: IExtensionDescription | undefined, id: string, alignment?: ExtHostStatusBarAlignment, priority?: number);
59-
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, extension?: IExtensionDescription, id?: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
57+
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, staticItems: ReadonlyMap<string, StatusBarItemDto>, extension: IExtensionDescription, id?: string, alignment?: ExtHostStatusBarAlignment, priority?: number);
58+
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, staticItems: ReadonlyMap<string, StatusBarItemDto>, extension: IExtensionDescription | undefined, id: string, alignment?: ExtHostStatusBarAlignment, priority?: number);
59+
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, staticItems: ReadonlyMap<string, StatusBarItemDto>, extension?: IExtensionDescription, id?: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
6060
this.#proxy = proxy;
6161
this.#commands = commands;
6262

6363
if (id && extension) {
6464
this._entryId = asStatusBarItemIdentifier(extension.identifier, id);
65-
proxy.$hasEntry(this._entryId).then(exits => {
66-
if (exits && this._visible === undefined) {
67-
// mark new item as visible if it already exists
68-
// this can only happen when an item was contributed by an extension
69-
this._visible = true;
70-
this.update();
71-
}
72-
});
65+
// if new item already exists mark it as visible and copy properties
66+
// this can only happen when an item was contributed by an extension
67+
const item = staticItems.get(this._entryId);
68+
if (item) {
69+
this._visible = true;
70+
this._alignment = item.alignLeft ? ExtHostStatusBarAlignment.Left : ExtHostStatusBarAlignment.Right;
71+
this._priority = item.priority;
72+
this.name = item.name;
73+
this.text = item.text;
74+
this.command = item.command;
75+
}
7376
} else {
7477
this._entryId = String(ExtHostStatusBarEntry.ID_GEN++);
7578
}
@@ -208,7 +211,7 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
208211
public hide(): void {
209212
clearTimeout(this._timeoutHandle);
210213
this._visible = false;
211-
this.#proxy.$dispose(this._entryId);
214+
this.#proxy.$disposeEntry(this._entryId);
212215
}
213216

214217
private update(): void {
@@ -307,22 +310,29 @@ class StatusBarMessage {
307310
}
308311
}
309312

310-
export class ExtHostStatusBar {
313+
export class ExtHostStatusBar implements ExtHostStatusBarShape {
311314

312315
private readonly _proxy: MainThreadStatusBarShape;
313316
private readonly _commands: CommandsConverter;
314317
private readonly _statusMessage: StatusBarMessage;
318+
private readonly _existingItems = new Map<string, StatusBarItemDto>();
315319

316320
constructor(mainContext: IMainContext, commands: CommandsConverter) {
317321
this._proxy = mainContext.getProxy(MainContext.MainThreadStatusBar);
318322
this._commands = commands;
319323
this._statusMessage = new StatusBarMessage(this);
320324
}
321325

326+
$acceptStaticEntries(added: StatusBarItemDto[]): void {
327+
for (const item of added) {
328+
this._existingItems.set(item.entryId, item);
329+
}
330+
}
331+
322332
createStatusBarEntry(extension: IExtensionDescription | undefined, id: string, alignment?: ExtHostStatusBarAlignment, priority?: number): vscode.StatusBarItem;
323333
createStatusBarEntry(extension: IExtensionDescription, id?: string, alignment?: ExtHostStatusBarAlignment, priority?: number): vscode.StatusBarItem;
324334
createStatusBarEntry(extension: IExtensionDescription, id: string, alignment?: ExtHostStatusBarAlignment, priority?: number): vscode.StatusBarItem {
325-
return new ExtHostStatusBarEntry(this._proxy, this._commands, extension, id, alignment, priority);
335+
return new ExtHostStatusBarEntry(this._proxy, this._commands, this._existingItems, extension, id, alignment, priority);
326336
}
327337

328338
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): Disposable {

0 commit comments

Comments
 (0)