From 8b63eeeb834ee7ad53e8775caadf2bd992b025b3 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 9 Aug 2024 13:58:16 -0700 Subject: [PATCH] Dispose of handlers on dispose in QuickPick API (#225286) Dispose of handlers on dispose fixes https://github.com/microsoft/vscode/issues/225158 --- .../api/browser/mainThreadQuickOpen.ts | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadQuickOpen.ts b/src/vs/workbench/api/browser/mainThreadQuickOpen.ts index 001745bf29a..7d8ca24b5d0 100644 --- a/src/vs/workbench/api/browser/mainThreadQuickOpen.ts +++ b/src/vs/workbench/api/browser/mainThreadQuickOpen.ts @@ -8,10 +8,12 @@ import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, Transf import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { URI } from 'vs/base/common/uri'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore } from 'vs/base/common/lifecycle'; interface QuickInputSession { input: IQuickInput; handlesToItems: Map; + store: DisposableStore; } function reviveIconPathUris(iconPath: { dark: URI; light?: URI | undefined }) { @@ -40,6 +42,9 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { } public dispose(): void { + for (const [_id, session] of this.sessions) { + session.store.dispose(); + } } $show(instance: number, options: IPickOptions, token: CancellationToken): Promise { @@ -121,38 +126,40 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { const sessionId = params.id; let session = this.sessions.get(sessionId); if (!session) { - + const store = new DisposableStore(); const input = params.type === 'quickPick' ? this._quickInputService.createQuickPick() : this._quickInputService.createInputBox(); - input.onDidAccept(() => { + store.add(input); + store.add(input.onDidAccept(() => { this._proxy.$onDidAccept(sessionId); - }); - input.onDidTriggerButton(button => { + })); + store.add(input.onDidTriggerButton(button => { this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle); - }); - input.onDidChangeValue(value => { + })); + store.add(input.onDidChangeValue(value => { this._proxy.$onDidChangeValue(sessionId, value); - }); - input.onDidHide(() => { + })); + store.add(input.onDidHide(() => { this._proxy.$onDidHide(sessionId); - }); + })); if (params.type === 'quickPick') { // Add extra events specific for quickpick const quickpick = input as IQuickPick; - quickpick.onDidChangeActive(items => { + store.add(quickpick.onDidChangeActive(items => { this._proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItem).handle)); - }); - quickpick.onDidChangeSelection(items => { + })); + store.add(quickpick.onDidChangeSelection(items => { this._proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItem).handle)); - }); - quickpick.onDidTriggerItemButton((e) => { + })); + store.add(quickpick.onDidTriggerItemButton((e) => { this._proxy.$onDidTriggerItemButton(sessionId, (e.item as TransferQuickPickItem).handle, (e.button as TransferQuickInputButton).handle); - }); + })); } session = { input, - handlesToItems: new Map() + handlesToItems: new Map(), + store }; this.sessions.set(sessionId, session); } @@ -212,7 +219,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { $dispose(sessionId: number): Promise { const session = this.sessions.get(sessionId); if (session) { - session.input.dispose(); + session.store.dispose(); this.sessions.delete(sessionId); } return Promise.resolve(undefined);