Skip to content

Commit

Permalink
aux window - introduce common super type for multi-window parts (#199010
Browse files Browse the repository at this point in the history
)
  • Loading branch information
bpasero authored Nov 24, 2023
1 parent 8405442 commit 5ab8d9b
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 118 deletions.
45 changes: 44 additions & 1 deletion src/vs/workbench/browser/part.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
import 'vs/css!./media/part';
import { Component } from 'vs/workbench/common/component';
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
import { Dimension, size, IDimension } from 'vs/base/browser/dom';
import { Dimension, size, IDimension, getActiveDocument } from 'vs/base/browser/dom';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ISerializableView, IViewSize } from 'vs/base/browser/ui/grid/grid';
import { Event, Emitter } from 'vs/base/common/event';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { assertIsDefined } from 'vs/base/common/types';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';

export interface IPartOptions {
readonly hasTitle?: boolean;
Expand Down Expand Up @@ -181,3 +182,45 @@ class PartLayout {
return { titleSize, contentSize };
}
}

export interface IMultiWindowPart {
readonly element: HTMLElement;
}

export abstract class MultiWindowParts<T extends IMultiWindowPart> extends Disposable {

protected readonly _parts = new Set<T>();
get parts() { return Array.from(this._parts); }

protected abstract mainPart: T;

protected registerPart(part: T): IDisposable {
this._parts.add(part);

return this._register(toDisposable(() => this.unregisterPart(part)));
}

protected unregisterPart(part: T): void {
this._parts.delete(part);
}

getPart(container: HTMLElement): T {
return this.getPartByDocument(container.ownerDocument);
}

protected getPartByDocument(document: Document): T {
if (this._parts.size > 1) {
for (const part of this._parts) {
if (part.element?.ownerDocument === document) {
return part;
}
}
}

return this.mainPart;
}

get activePart(): T {
return this.getPartByDocument(getActiveDocument());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class AuxiliaryEditorPart {
auxiliaryWindow.container.appendChild(editorPartContainer);

const editorPart = disposables.add(this.instantiationService.createInstance(AuxiliaryEditorPartImpl, auxiliaryWindow.window.vscodeWindowId, this.editorPartsView, label));
disposables.add(this.editorPartsView.registerEditorPart(editorPart));
disposables.add(this.editorPartsView.registerPart(editorPart));
editorPart.create(editorPartContainer, { restorePreviousState: false });

// Titlebar
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function validateEditorPartOptions(options: IEditorPartOptions): IEditorPartOpti
export interface IEditorPartsView {

readonly mainPart: IEditorGroupsView;
registerEditorPart(part: IEditorPart): IDisposable;
registerPart(part: IEditorPart): IDisposable;

readonly activeGroup: IEditorGroupView;
readonly groups: IEditorGroupView[];
Expand Down
43 changes: 11 additions & 32 deletions src/vs/workbench/browser/parts/editor/editorParts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import { localize } from 'vs/nls';
import { EditorGroupLayout, GroupDirection, GroupLocation, GroupOrientation, GroupsArrangement, GroupsOrder, IAuxiliaryEditorPart, IAuxiliaryEditorPartCreateEvent, IEditorDropTargetDelegate, IEditorGroupsService, IEditorSideGroup, IFindGroupScope, IMergeGroupOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
import { Emitter } from 'vs/base/common/event';
import { getActiveDocument } from 'vs/base/browser/dom';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { GroupIdentifier } from 'vs/workbench/common/editor';
import { EditorPart, MainEditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { IEditorGroupView, IEditorPartsView } from 'vs/workbench/browser/parts/editor/editor';
Expand All @@ -16,8 +15,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IAuxiliaryWindowOpenOptions } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';
import { distinct } from 'vs/base/common/arrays';
import { AuxiliaryEditorPart } from 'vs/workbench/browser/parts/editor/auxiliaryEditorPart';
import { MultiWindowParts } from 'vs/workbench/browser/part';

export class EditorParts extends Disposable implements IEditorGroupsService, IEditorPartsView {
export class EditorParts extends MultiWindowParts<EditorPart> implements IEditorGroupsService, IEditorPartsView {

declare readonly _serviceBrand: undefined;

Expand All @@ -28,7 +28,7 @@ export class EditorParts extends Disposable implements IEditorGroupsService, IEd
) {
super();

this._register(this.registerEditorPart(this.mainPart));
this._register(this.registerPart(this.mainPart));
}

protected createMainEditorPart(): MainEditorPart {
Expand Down Expand Up @@ -56,22 +56,17 @@ export class EditorParts extends Disposable implements IEditorGroupsService, IEd

//#region Registration

private readonly _parts = new Set<EditorPart>();
get parts() { return Array.from(this._parts); }

registerEditorPart(part: EditorPart): IDisposable {
this._parts.add(part);

override registerPart(part: EditorPart): IDisposable {
const disposables = this._register(new DisposableStore());
disposables.add(toDisposable(() => this.unregisterEditorPart(part)));
disposables.add(super.registerPart(part));

this.registerEditorPartListeners(part, disposables);

return disposables;
}

private unregisterEditorPart(part: EditorPart): void {
this._parts.delete(part);
protected override unregisterPart(part: EditorPart): void {
super.unregisterPart(part);

// Notify all parts about a groups label change
// given it is computed based on the index
Expand Down Expand Up @@ -111,25 +106,9 @@ export class EditorParts extends Disposable implements IEditorGroupsService, IEd

//#region Helpers

get activePart(): EditorPart {
return this.getPartByDocument(getActiveDocument());
}

private getPartByDocument(document: Document): EditorPart {
if (this._parts.size > 1) {
for (const part of this._parts) {
if (part.element?.ownerDocument === document) {
return part;
}
}
}

return this.mainPart;
}

getPart(group: IEditorGroupView | GroupIdentifier): EditorPart;
getPart(element: HTMLElement): EditorPart;
getPart(groupOrElement: IEditorGroupView | GroupIdentifier | HTMLElement): EditorPart {
override getPart(group: IEditorGroupView | GroupIdentifier): EditorPart;
override getPart(element: HTMLElement): EditorPart;
override getPart(groupOrElement: IEditorGroupView | GroupIdentifier | HTMLElement): EditorPart {
if (this._parts.size > 1) {
if (groupOrElement instanceof HTMLElement) {
const element = groupOrElement;
Expand Down
49 changes: 5 additions & 44 deletions src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import 'vs/css!./media/statusbarpart';
import { localize } from 'vs/nls';
import { Disposable, DisposableStore, dispose, disposeIfDisposable, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Part } from 'vs/workbench/browser/part';
import { MultiWindowParts, Part } from 'vs/workbench/browser/part';
import { EventType as TouchEventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { StatusbarAlignment, IStatusbarService, IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarStyleOverride, isStatusbarEntryLocation, IStatusbarEntryLocation, isStatusbarEntryPriority, IStatusbarEntryPriority } from 'vs/workbench/services/statusbar/browser/statusbar';
Expand All @@ -16,7 +16,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { STATUS_BAR_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_BORDER, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER, STATUS_BAR_ITEM_COMPACT_HOVER_BACKGROUND, STATUS_BAR_ITEM_FOCUS_BORDER, STATUS_BAR_FOCUS_BORDER } from 'vs/workbench/common/theme';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { EventHelper, createStyleSheet, addDisposableListener, EventType, clearNode, getWindow, getActiveDocument } from 'vs/base/browser/dom';
import { EventHelper, createStyleSheet, addDisposableListener, EventType, clearNode, getWindow } from 'vs/base/browser/dom';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
Expand Down Expand Up @@ -701,7 +701,7 @@ export class AuxiliaryStatusbarPart extends StatusbarPart implements IAuxiliaryS
}
}

export class StatusbarService extends Disposable implements IStatusbarService {
export class StatusbarService extends MultiWindowParts<StatusbarPart> implements IStatusbarService {

declare readonly _serviceBrand: undefined;

Expand All @@ -712,7 +712,7 @@ export class StatusbarService extends Disposable implements IStatusbarService {
) {
super();

this._register(this.registerStatusbarPart(this.mainPart));
this._register(this.registerPart(this.mainPart));
}

//#region Auxiliary Statusbar Parts
Expand All @@ -727,7 +727,7 @@ export class StatusbarService extends Disposable implements IStatusbarService {
container.appendChild(statusbarPartContainer);

const statusbarPart = this.instantiationService.createInstance(AuxiliaryStatusbarPart, statusbarPartContainer);
const disposable = this.registerStatusbarPart(statusbarPart);
const disposable = this.registerPart(statusbarPart);

statusbarPart.create(statusbarPartContainer);

Expand All @@ -742,45 +742,6 @@ export class StatusbarService extends Disposable implements IStatusbarService {

//#endregion

//#region Registration

private readonly parts = new Set<StatusbarPart>();

private registerStatusbarPart(part: StatusbarPart): IDisposable {
this.parts.add(part);

const disposables = this._register(new DisposableStore());
disposables.add(toDisposable(() => this.parts.delete(part)));

return disposables;
}

//#endregion

//#region Helpers

getPart(container: HTMLElement): IStatusbarEntryContainer {
return this.getPartByDocument(container.ownerDocument);
}

private get activePart(): StatusbarPart {
return this.getPartByDocument(getActiveDocument());
}

private getPartByDocument(document: Document): StatusbarPart {
if (this.parts.size > 1) {
for (const part of this.parts) {
if (part.element?.ownerDocument === document) {
return part;
}
}
}

return this.mainPart;
}

//#endregion

//#region Service Implementation

readonly onDidChangeEntryVisibility = this.mainPart.onDidChangeEntryVisibility;
Expand Down
44 changes: 5 additions & 39 deletions src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

import 'vs/css!./media/titlebarpart';
import { localize } from 'vs/nls';
import { Part } from 'vs/workbench/browser/part';
import { MultiWindowParts, Part } from 'vs/workbench/browser/part';
import { ITitleService } from 'vs/workbench/services/title/browser/titleService';
import { getZoomFactor, isWCOEnabled } from 'vs/base/browser/browser';
import { MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility } from 'vs/platform/window/common/window';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ThemeIcon } from 'vs/base/common/themables';
Expand Down Expand Up @@ -74,7 +74,7 @@ export interface ITitlebarPart extends IDisposable {
updateProperties(properties: ITitleProperties): void;
}

export class BrowserTitleService extends Disposable implements ITitleService {
export class BrowserTitleService extends MultiWindowParts<BrowserTitlebarPart> implements ITitleService {

declare _serviceBrand: undefined;

Expand All @@ -85,7 +85,7 @@ export class BrowserTitleService extends Disposable implements ITitleService {
) {
super();

this._register(this.registerTitlebarPart(this.mainPart));
this._register(this.registerPart(this.mainPart));
}

protected createMainTitlebarPart(): BrowserTitlebarPart {
Expand All @@ -104,7 +104,7 @@ export class BrowserTitleService extends Disposable implements ITitleService {
const disposables = new DisposableStore();

const titlebarPart = this.doCreateAuxiliaryTitlebarPart(titlebarPartContainer, editorGroupsContainer);
disposables.add(this.registerTitlebarPart(titlebarPart));
disposables.add(this.registerPart(titlebarPart));

disposables.add(Event.runAndSubscribe(titlebarPart.onDidChange, () => titlebarPartContainer.style.height = `${titlebarPart.height}px`));
titlebarPart.create(titlebarPartContainer);
Expand All @@ -120,40 +120,6 @@ export class BrowserTitleService extends Disposable implements ITitleService {

//#endregion

//#region Registration

private readonly parts = new Set<BrowserTitlebarPart>();

private registerTitlebarPart(part: BrowserTitlebarPart): IDisposable {
this.parts.add(part);

const disposables = this._register(new DisposableStore());
disposables.add(toDisposable(() => this.parts.delete(part)));

return disposables;
}

//#endregion

//#region Helpers

getPart(container: HTMLElement): ITitlebarPart {
return this.getPartByDocument(container.ownerDocument);
}

private getPartByDocument(document: Document): ITitlebarPart {
if (this.parts.size > 1) {
for (const part of this.parts) {
if (part.element?.ownerDocument === document) {
return part;
}
}
}

return this.mainPart;
}

//#endregion

//#region Service Implementation

Expand Down

0 comments on commit 5ab8d9b

Please sign in to comment.