Skip to content

Commit a1d7ea6

Browse files
committed
enable moving entire view containers with cache
1 parent 7298303 commit a1d7ea6

5 files changed

Lines changed: 135 additions & 18 deletions

File tree

src/vs/workbench/browser/actions/layoutActions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ export class ResetViewLocationsAction extends Action {
498498
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], defaultContainer);
499499
}
500500
});
501+
502+
const defaultContainerLocation = this.viewDescriptorService.getDefaultViewContainerLocation(viewContainer);
503+
const currentContainerLocation = this.viewDescriptorService.getViewContainerLocation(viewContainer);
504+
if (defaultContainerLocation !== null && currentContainerLocation !== defaultContainerLocation) {
505+
this.viewDescriptorService.moveViewContainerToLocation(viewContainer, defaultContainerLocation);
506+
}
501507
});
502508
}
503509
}

src/vs/workbench/browser/parts/compositeBar.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,10 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
5959
return;
6060
}
6161

62-
this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation);
63-
const newContainer = this.viewDescriptorService.getViewContainerById(viewsToMove[0].id)!;
64-
this.moveComposite(newContainer.id, targetCompositeId, before);
65-
66-
if (viewsToMove.length > 1) {
67-
this.viewDescriptorService.moveViewsToContainer(viewsToMove.slice(1), newContainer);
68-
}
62+
this.viewDescriptorService.moveViewContainerToLocation(currentContainer, this.targetContainerLocation);
63+
this.moveComposite(currentContainer.id, targetCompositeId, before);
6964

70-
this.openComposite(newContainer.id, true).then(composite => {
71-
if (composite && viewsToMove.length === 1) {
72-
composite.openView(viewsToMove[0].id, true);
73-
}
74-
});
65+
this.openComposite(currentContainer.id, true);
7566
}
7667
}
7768

src/vs/workbench/browser/parts/views/views.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ export class ViewsService extends Disposable implements IViewsService {
6868

6969
this.viewDescriptorService.getViewContainers().forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!));
7070
this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer, viewContainerLocation }) => this.onDidRegisterViewContainer(viewContainer, viewContainerLocation)));
71-
7271
this._register(this.viewContainersRegistry.onDidDeregister(e => this.viewPaneContainers.delete(e.viewContainer.id)));
72+
this._register(this.viewDescriptorService.onDidChangeContainerLocation(({ viewContainer, from, to }) => this.onDidChangeContainerLocation(viewContainer, from, to)));
7373
}
7474

7575
private registerViewPaneContainer(viewPaneContainer: ViewPaneContainer): void {
@@ -107,6 +107,11 @@ export class ViewsService extends Disposable implements IViewsService {
107107
return contextKey;
108108
}
109109

110+
private onDidChangeContainerLocation(viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation): void {
111+
this.deregisterViewletOrPanel(viewContainer, from);
112+
this.registerViewletOrPanel(viewContainer, to);
113+
}
114+
110115
private onDidRegisterViewContainer(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void {
111116
this.registerViewletOrPanel(viewContainer, viewContainerLocation);
112117
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
@@ -364,6 +369,27 @@ export class ViewsService extends Disposable implements IViewsService {
364369
viewContainer.icon instanceof URI ? viewContainer.icon : undefined
365370
));
366371
}
372+
373+
private deregisterViewletOrPanel(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void {
374+
switch (viewContainerLocation) {
375+
case ViewContainerLocation.Panel:
376+
this.deregisterPanel(viewContainer);
377+
break;
378+
case ViewContainerLocation.Sidebar:
379+
if (viewContainer.ctorDescriptor) {
380+
this.deregisterViewlet(viewContainer);
381+
}
382+
break;
383+
}
384+
}
385+
386+
private deregisterPanel(viewContainer: ViewContainer): void {
387+
Registry.as<PanelRegistry>(PanelExtensions.Panels).deregisterPanel(viewContainer.id);
388+
}
389+
390+
private deregisterViewlet(viewContainer: ViewContainer): void {
391+
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).deregisterViewlet(viewContainer.id);
392+
}
367393
}
368394

369395
export function createFileIconThemableTreeContainerScope(container: HTMLElement, themeService: IThemeService): IDisposable {

src/vs/workbench/common/views.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ export interface IViewDescriptorService {
482482

483483
readonly onDidChangeContainer: Event<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>;
484484
readonly onDidChangeLocation: Event<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }>;
485+
readonly onDidChangeContainerLocation: Event<{ viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation }>;
485486

486487
moveViewContainerToLocation(viewContainer: ViewContainer, location: ViewContainerLocation): void;
487488

@@ -499,6 +500,8 @@ export interface IViewDescriptorService {
499500

500501
getViewContainerLocation(viewContainer: ViewContainer): ViewContainerLocation | null;
501502

503+
getDefaultViewContainerLocation(viewContainer: ViewContainer): ViewContainerLocation | null;
504+
502505
getDefaultContainerById(id: string): ViewContainer | null;
503506

504507
getViewLocationById(id: string): ViewContainerLocation | null;

src/vs/workbench/services/views/browser/viewDescriptorService.ts

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
2929
_serviceBrand: undefined;
3030

3131
private static readonly CACHED_VIEW_POSITIONS = 'views.cachedViewPositions';
32+
private static readonly CACHED_VIEW_CONTAINER_LOCATIONS = 'views.cachedViewContainerLocations';
3233
private static readonly COMMON_CONTAINER_ID_PREFIX = 'workbench.views.service';
3334

3435
private readonly _onDidChangeContainer: Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>());
@@ -37,6 +38,9 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
3738
private readonly _onDidChangeLocation: Emitter<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }>());
3839
readonly onDidChangeLocation: Event<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }> = this._onDidChangeLocation.event;
3940

41+
private readonly _onDidChangeContainerLocation: Emitter<{ viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation }> = this._register(new Emitter<{ viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation }>());
42+
readonly onDidChangeContainerLocation: Event<{ viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation }> = this._onDidChangeContainerLocation.event;
43+
4044
private readonly viewContainerModels: Map<ViewContainer, { viewContainerModel: ViewContainerModel, disposable: IDisposable; }>;
4145
private readonly activeViewContextKeys: Map<string, IContextKey<boolean>>;
4246
private readonly movableViewContextKeys: Map<string, IContextKey<boolean>>;
@@ -46,6 +50,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
4650
private readonly viewContainersRegistry: IViewContainersRegistry;
4751

4852
private cachedViewInfo: Map<string, ICachedViewContainerInfo>;
53+
private cachedViewContainerInfo: Map<string, ViewContainerLocation>;
4954

5055
private _cachedViewPositionsValue: string | undefined;
5156
private get cachedViewPositionsValue(): string {
@@ -63,6 +68,22 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
6368
}
6469
}
6570

71+
private _cachedViewContainerLocationsValue: string | undefined;
72+
private get cachedViewContainerLocationsValue(): string {
73+
if (!this._cachedViewContainerLocationsValue) {
74+
this._cachedViewContainerLocationsValue = this.getStoredCachedViewContainerLocationsValue();
75+
}
76+
77+
return this._cachedViewContainerLocationsValue;
78+
}
79+
80+
private set cachedViewContainerLocationsValue(value: string) {
81+
if (this._cachedViewContainerLocationsValue !== value) {
82+
this._cachedViewContainerLocationsValue = value;
83+
this.setStoredCachedViewContainerLocationsValue(value);
84+
}
85+
}
86+
6687
constructor(
6788
@IInstantiationService private readonly instantiationService: IInstantiationService,
6889
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@@ -83,9 +104,10 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
83104
this.viewsRegistry = Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry);
84105

85106
this.cachedViewInfo = this.getCachedViewPositions();
107+
this.cachedViewContainerInfo = this.getCachedViewContainerLocations();
86108

87109
// Register all containers that were registered before this ctor
88-
this.viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer));
110+
this.getViewContainers().forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer));
89111

90112
// Try generating all generated containers that don't need extensions
91113
this.tryGenerateContainers();
@@ -252,6 +274,11 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
252274
}
253275

254276
getViewContainerLocation(viewContainer: ViewContainer): ViewContainerLocation {
277+
const location = this.cachedViewContainerInfo.get(viewContainer.id);
278+
return location !== undefined ? location : this.getDefaultViewContainerLocation(viewContainer);
279+
}
280+
281+
getDefaultViewContainerLocation(viewContainer: ViewContainer): ViewContainerLocation {
255282
return this.viewContainersRegistry.getViewContainerLocation(viewContainer);
256283
}
257284

@@ -267,14 +294,26 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
267294
return this.viewContainersRegistry.get(id) || null;
268295
}
269296
getViewContainersByLocation(location: ViewContainerLocation): ViewContainer[] {
270-
return this.viewContainersRegistry.getViewContainers(location);
297+
return this.getViewContainers().filter(v => this.getViewContainerLocation(v) === location);
271298
}
272299
getViewContainers(): ViewContainer[] {
273300
return this.viewContainersRegistry.all;
274301
}
275302

276303
moveViewContainerToLocation(viewContainer: ViewContainer, location: ViewContainerLocation): void {
277-
// to be implemented
304+
const from = this.getViewContainerLocation(viewContainer);
305+
const to = location;
306+
if (from !== to) {
307+
if (this.getDefaultViewContainerLocation(viewContainer) === to) {
308+
this.cachedViewContainerInfo.delete(viewContainer.id);
309+
} else {
310+
this.cachedViewContainerInfo.set(viewContainer.id, to);
311+
}
312+
313+
this._onDidChangeContainerLocation.fire({ viewContainer, from, to });
314+
315+
this.saveViewContainerLocationsToCache();
316+
}
278317
}
279318

280319
moveViewToLocation(view: IViewDescriptor, location: ViewContainerLocation): void {
@@ -376,6 +415,10 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
376415
return result;
377416
}
378417

418+
private getCachedViewContainerLocations(): Map<string, ViewContainerLocation> {
419+
return new Map<string, ViewContainerLocation>(JSON.parse(this.cachedViewContainerLocationsValue));
420+
}
421+
379422
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
380423
if (e.key === ViewDescriptorService.CACHED_VIEW_POSITIONS && e.scope === StorageScope.GLOBAL
381424
&& this.cachedViewPositionsValue !== this.getStoredCachedViewPositionsValue() /* This checks if current window changed the value or not */) {
@@ -407,7 +450,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
407450
}
408451

409452
// If a value is not present in the cache, it must be reset to default
410-
this.viewContainersRegistry.all.forEach(viewContainer => {
453+
this.getViewContainers().forEach(viewContainer => {
411454
const viewContainerModel = this.getViewContainerModel(viewContainer);
412455
viewContainerModel.allViewDescriptors.forEach(viewDescriptor => {
413456
if (!newCachedPositions.has(viewDescriptor.id)) {
@@ -424,6 +467,35 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
424467

425468
this.cachedViewInfo = this.getCachedViewPositions();
426469
}
470+
471+
472+
if (e.key === ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS && e.scope === StorageScope.GLOBAL
473+
&& this.cachedViewContainerLocationsValue !== this.getStoredCachedViewContainerLocationsValue() /* This checks if current window changed the value or not */) {
474+
this._cachedViewContainerLocationsValue = this.getStoredCachedViewContainerLocationsValue();
475+
const newCachedLocations = this.getCachedViewContainerLocations();
476+
477+
for (const [containerId, location] of newCachedLocations.entries()) {
478+
const container = this.getViewContainerById(containerId);
479+
if (container) {
480+
if (location !== this.getViewContainerLocation(container)) {
481+
this.moveViewContainerToLocation(container, location);
482+
}
483+
}
484+
}
485+
486+
this.getViewContainers().forEach(viewContainer => {
487+
if (!newCachedLocations.has(viewContainer.id)) {
488+
const currentLocation = this.getViewContainerLocation(viewContainer);
489+
const defaultLocation = this.getDefaultViewContainerLocation(viewContainer);
490+
491+
if (currentLocation !== defaultLocation) {
492+
this.moveViewContainerToLocation(viewContainer, defaultLocation);
493+
}
494+
}
495+
});
496+
497+
this.cachedViewContainerInfo = this.getCachedViewContainerLocations();
498+
}
427499
}
428500

429501
// Generated Container Id Format
@@ -442,8 +514,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
442514
this.storageService.store(ViewDescriptorService.CACHED_VIEW_POSITIONS, value, StorageScope.GLOBAL);
443515
}
444516

517+
private getStoredCachedViewContainerLocationsValue(): string {
518+
return this.storageService.get(ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, StorageScope.GLOBAL, '[]');
519+
}
520+
521+
private setStoredCachedViewContainerLocationsValue(value: string): void {
522+
this.storageService.store(ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, value, StorageScope.GLOBAL);
523+
}
524+
445525
private saveViewPositionsToCache(): void {
446-
this.viewContainersRegistry.all.forEach(viewContainer => {
526+
this.getViewContainers().forEach(viewContainer => {
447527
const viewContainerModel = this.getViewContainerModel(viewContainer);
448528
viewContainerModel.allViewDescriptors.forEach(viewDescriptor => {
449529
const containerLocation = this.getViewContainerLocation(viewContainer);
@@ -467,6 +547,17 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
467547
this.cachedViewPositionsValue = JSON.stringify([...this.cachedViewInfo]);
468548
}
469549

550+
private saveViewContainerLocationsToCache(): void {
551+
for (const [containerId, location] of this.cachedViewContainerInfo) {
552+
const container = this.getViewContainerById(containerId);
553+
if (container && location === this.getDefaultViewContainerLocation(container)) {
554+
this.cachedViewContainerInfo.delete(containerId);
555+
}
556+
}
557+
558+
this.cachedViewContainerLocationsValue = JSON.stringify([...this.cachedViewContainerInfo]);
559+
}
560+
470561
private getViewsByContainer(viewContainer: ViewContainer): IViewDescriptor[] {
471562
const result = this.viewsRegistry.getViews(viewContainer).filter(viewDescriptor => {
472563
const cachedContainer = this.cachedViewInfo.get(viewDescriptor.id)?.containerId || viewContainer.id;

0 commit comments

Comments
 (0)