Skip to content

Commit

Permalink
Properly dispose tab/title-based resources on tab close
Browse files Browse the repository at this point in the history
Fixes #14203
  • Loading branch information
martin-fleck-at committed Oct 28, 2024
1 parent a5f26a3 commit cf33381
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions packages/plugin-ext/src/main/browser/tabs/tabs-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class TabsMainImpl implements TabsMain, Disposable {
private applicationShell: ApplicationShell;

private disposableTabBarListeners: DisposableCollection = new DisposableCollection();
private disposableTitleListeners: Map<string, DisposableCollection> = new Map();
private toDisposeOnDestroy: DisposableCollection = new DisposableCollection();

private groupIdCounter = 1;
Expand Down Expand Up @@ -131,6 +132,7 @@ export class TabsMainImpl implements TabsMain, Disposable {
}
const newTabGroupModel = new Map<TabBar<Widget>, TabGroupDto>();
this.tabInfoLookup.clear();
this.disposableTitleListeners.forEach(disposable => disposable.dispose());
this.disposableTabBarListeners.dispose();
this.applicationShell.mainAreaTabBars
.forEach(tabBar => {
Expand Down Expand Up @@ -185,12 +187,21 @@ export class TabsMainImpl implements TabsMain, Disposable {
};
}

protected getTitleDisposables(title: Title<Widget>): DisposableCollection {
let disposable = this.disposableTitleListeners.get(title.owner.id);
if (!disposable) {
disposable = new DisposableCollection();
this.disposableTitleListeners.set(title.owner.id, disposable);
}
return disposable;
}

protected attachListenersToTabBar(tabBar: TabBar<Widget> | undefined): void {
if (!tabBar) {
return;
}
tabBar.titles.forEach(title => {
this.connectToSignal(this.disposableTabBarListeners, title.changed, this.onTabTitleChanged);
this.connectToSignal(this.getTitleDisposables(title), title.changed, this.onTabTitleChanged);
});

this.connectToSignal(this.disposableTabBarListeners, tabBar.tabMoved, this.onTabMoved);
Expand Down Expand Up @@ -261,7 +272,7 @@ export class TabsMainImpl implements TabsMain, Disposable {
// #region event listeners
private onTabCreated(tabBar: TabBar<Widget>, args: TabBar.ITabActivateRequestedArgs<Widget>): void {
const group = this.getOrRebuildModel(this.tabGroupModel, tabBar);
this.connectToSignal(this.disposableTabBarListeners, args.title.changed, this.onTabTitleChanged);
this.connectToSignal(this.getTitleDisposables(args.title), args.title.changed, this.onTabTitleChanged);
const tabDto = this.createTabDto(args.title, group.groupId, true);
this.tabInfoLookup.set(args.title, { group, tab: tabDto, tabIndex: args.index });
group.tabs.splice(args.index, 0, tabDto);
Expand Down Expand Up @@ -306,6 +317,8 @@ export class TabsMainImpl implements TabsMain, Disposable {
}

private onTabClosed(tabInfo: TabInfo, title: Title<Widget>): void {
this.disposableTitleListeners.get(title.owner.id)?.dispose();
this.disposableTitleListeners.delete(title.owner.id);
tabInfo.group.tabs.splice(tabInfo.tabIndex, 1);
this.tabInfoLookup.delete(title);
this.updateTabIndices(tabInfo, tabInfo.tabIndex);
Expand Down Expand Up @@ -384,5 +397,7 @@ export class TabsMainImpl implements TabsMain, Disposable {
dispose(): void {
this.toDisposeOnDestroy.dispose();
this.disposableTabBarListeners.dispose();
this.disposableTitleListeners.forEach(disposable => disposable.dispose());
this.disposableTitleListeners.clear();
}
}

0 comments on commit cf33381

Please sign in to comment.