From 31809121455535dff94f33a96a8289336a82ef17 Mon Sep 17 00:00:00 2001 From: Dmitriy Vasyura Date: Thu, 18 Dec 2025 21:30:01 -0800 Subject: [PATCH] Use new toggles in the public API --- .../quickinput/browser/quickInputUtils.ts | 2 +- .../api/browser/mainThreadQuickOpen.ts | 88 +++---------------- .../workbench/api/common/extHost.protocol.ts | 2 +- .../workbench/api/common/extHostQuickOpen.ts | 12 +-- 4 files changed, 14 insertions(+), 90 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickInputUtils.ts b/src/vs/platform/quickinput/browser/quickInputUtils.ts index 12794f59b17..00a6baa1247 100644 --- a/src/vs/platform/quickinput/browser/quickInputUtils.ts +++ b/src/vs/platform/quickinput/browser/quickInputUtils.ts @@ -85,8 +85,8 @@ export function quickInputButtonToAction(button: IQuickInputButton, id: string, const action = button.toggle ? new QuickInputToggleButtonAction( id, - '', button.tooltip || '', + '', cssClasses, true, button.toggle.checked, diff --git a/src/vs/workbench/api/browser/mainThreadQuickOpen.ts b/src/vs/workbench/api/browser/mainThreadQuickOpen.ts index 3b8d8deae9e..1b1f906d1a6 100644 --- a/src/vs/workbench/api/browser/mainThreadQuickOpen.ts +++ b/src/vs/workbench/api/browser/mainThreadQuickOpen.ts @@ -3,10 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Toggle } from '../../../base/browser/ui/toggle/toggle.js'; import { CancellationToken } from '../../../base/common/cancellation.js'; import { Lazy } from '../../../base/common/lazy.js'; -import { DisposableStore, IDisposable } from '../../../base/common/lifecycle.js'; +import { DisposableStore } from '../../../base/common/lifecycle.js'; import { basenameOrAuthority, dirname, hasTrailingPathSeparator } from '../../../base/common/resources.js'; import { ThemeIcon } from '../../../base/common/themables.js'; import { isUriComponents, URI } from '../../../base/common/uri.js'; @@ -15,8 +14,7 @@ import { getIconClasses } from '../../../editor/common/services/getIconClasses.j import { IModelService } from '../../../editor/common/services/model.js'; import { FileKind } from '../../../platform/files/common/files.js'; import { ILabelService } from '../../../platform/label/common/label.js'; -import { IInputOptions, IPickOptions, IQuickInput, IQuickInputService, IQuickPick, IQuickPickItem, QuickInputButtonLocation } from '../../../platform/quickinput/common/quickInput.js'; -import { asCssVariable, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground } from '../../../platform/theme/common/colorRegistry.js'; +import { IInputOptions, IPickOptions, IQuickInput, IQuickInputService, IQuickPick, IQuickPickItem } from '../../../platform/quickinput/common/quickInput.js'; import { ICustomEditorLabelService } from '../../services/editor/common/customEditorLabelService.js'; import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js'; import { ExtHostContext, ExtHostQuickOpenShape, IInputBoxOptions, MainContext, MainThreadQuickOpenShape, TransferQuickInput, TransferQuickInputButton, TransferQuickPickItem, TransferQuickPickItemOrSeparator } from '../common/extHost.protocol.js'; @@ -24,7 +22,6 @@ import { ExtHostContext, ExtHostQuickOpenShape, IInputBoxOptions, MainContext, M interface QuickInputSession { input: IQuickInput; handlesToItems: Map; - handlesToToggles: Map; store: DisposableStore; } @@ -143,7 +140,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { this._proxy.$onDidAccept(sessionId); })); store.add(input.onDidTriggerButton(button => { - this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle); + this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle, button.toggle?.checked); })); store.add(input.onDidChangeValue(value => { this._proxy.$onDidChangeValue(sessionId, value); @@ -153,15 +150,15 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { })); if (params.type === 'quickPick') { - // Add extra events specific for quickpick - const quickpick = input as IQuickPick; - store.add(quickpick.onDidChangeActive(items => { + // Add extra events specific for quick pick + const quickPick = input as IQuickPick; + store.add(quickPick.onDidChangeActive(items => { this._proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItem).handle)); })); - store.add(quickpick.onDidChangeSelection(items => { + store.add(quickPick.onDidChangeSelection(items => { this._proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItem).handle)); })); - store.add(quickpick.onDidTriggerItemButton((e) => { + store.add(quickPick.onDidTriggerItemButton((e) => { this._proxy.$onDidTriggerItemButton(sessionId, (e.item as TransferQuickPickItem).handle, (e.button as TransferQuickInputButton).handle); })); } @@ -169,7 +166,6 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { session = { input, handlesToItems: new Map(), - handlesToToggles: new Map(), store }; this.sessions.set(sessionId, session); @@ -217,24 +213,16 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { break; case 'buttons': { - const buttons = [], toggles = []; + const buttons = []; for (const button of params.buttons!) { if (button.handle === -1) { buttons.push(this._quickInputService.backButton); } else { this.expandIconPath(button); - - // Currently buttons are only supported outside of the input box - // and toggles only inside. When/if that changes, this will need to be updated. - if (button.location === QuickInputButtonLocation.Input) { - toggles.push(button); - } else { - buttons.push(button); - } + buttons.push(button); } } input.buttons = buttons; - this.updateToggles(sessionId, session, toggles); break; } @@ -310,60 +298,4 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { target.iconPath = { dark: URI.from(dark), light: URI.from(light) }; } } - - /** - * Updates the toggles for a given quick input session by creating new {@link Toggle}-s - * from buttons, updating existing toggles props and removing old ones. - */ - private updateToggles(sessionId: number, session: QuickInputSession, buttons: TransferQuickInputButton[]) { - const { input, handlesToToggles, store } = session; - - // Add new or update existing toggles. - const toggles = []; - for (const button of buttons) { - const title = button.tooltip || ''; - const isChecked = !!button.checked; - - // TODO: Toggle class only supports ThemeIcon at the moment, but not other formats of IconPath. - // We should consider adding support for the full IconPath to Toggle, in this code should be updated. - const icon = ThemeIcon.isThemeIcon(button.iconPathDto) ? button.iconPathDto : undefined; - - let { toggle } = handlesToToggles.get(button.handle) || {}; - if (toggle) { - // Toggle already exists, update its props. - toggle.setTitle(title); - toggle.setIcon(icon); - toggle.checked = isChecked; - } else { - // Create a new toggle from the button. - toggle = store.add(new Toggle({ - title, - icon, - isChecked, - inputActiveOptionBorder: asCssVariable(inputActiveOptionBorder), - inputActiveOptionForeground: asCssVariable(inputActiveOptionForeground), - inputActiveOptionBackground: asCssVariable(inputActiveOptionBackground) - })); - - const listener = store.add(toggle.onChange(() => { - this._proxy.$onDidTriggerButton(sessionId, button.handle, toggle!.checked); - })); - - handlesToToggles.set(button.handle, { toggle, listener }); - } - toggles.push(toggle); - } - - // Remove toggles that are no longer present from the session map. - for (const [handle, { toggle, listener }] of handlesToToggles) { - if (!buttons.some(button => button.handle === handle)) { - handlesToToggles.delete(handle); - store.delete(toggle); - store.delete(listener); - } - } - - // Update toggle interfaces on the input widget. - input.toggles = toggles; - } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ed8da261c94..d1367994bb8 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -678,7 +678,7 @@ export interface TransferQuickPickItem { export interface TransferQuickInputButton extends quickInput.IQuickInputButton { handle: number; iconPathDto: IconPathDto; - checked?: boolean; + toggle?: { checked: boolean }; // TODO: These properties are not used for transfer (iconPathDto is used instead) but they cannot be removed // because this type is used as IQuickInputButton on the main thread. Ideally IQuickInputButton should also use IconPath. diff --git a/src/vs/workbench/api/common/extHostQuickOpen.ts b/src/vs/workbench/api/common/extHostQuickOpen.ts index a25615a4108..4af39358c5d 100644 --- a/src/vs/workbench/api/common/extHostQuickOpen.ts +++ b/src/vs/workbench/api/common/extHostQuickOpen.ts @@ -10,7 +10,7 @@ import { ExtHostCommands } from './extHostCommands.js'; import { IExtHostWorkspaceProvider } from './extHostWorkspace.js'; import { InputBox, InputBoxOptions, InputBoxValidationMessage, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode'; import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickInput, TransferQuickInputButton, TransferQuickPickItemOrSeparator } from './extHost.protocol.js'; -import { QuickInputButtons, QuickPickItemKind, InputBoxValidationSeverity, QuickInputButtonLocation } from './extHostTypes.js'; +import { QuickInputButtons, QuickPickItemKind, InputBoxValidationSeverity } from './extHostTypes.js'; import { isCancellationError } from '../../../base/common/errors.js'; import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js'; import { coalesce } from '../../../base/common/arrays.js'; @@ -397,14 +397,6 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx checkProposedApiEnabled(this._extension, 'quickInputButtonLocation'); } - if (buttons.some(button => - typeof button.location === 'number' && - button.location !== QuickInputButtonLocation.Input && - typeof button.toggle === 'object' && - typeof button.toggle.checked === 'boolean')) { - throw new Error('QuickInputButtons with toggle set are only supported in the Input location.'); - } - this._buttons = buttons.slice(); this._handlesToButtons.clear(); buttons.forEach((button, i) => { @@ -418,7 +410,7 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx tooltip: button.tooltip, handle: button === QuickInputButtons.Back ? -1 : i, location: typeof button.location === 'number' ? button.location : undefined, - checked: typeof button.toggle === 'object' && typeof button.toggle.checked === 'boolean' ? button.toggle.checked : undefined + toggle: typeof button.toggle === 'object' && typeof button.toggle.checked === 'boolean' ? { checked: button.toggle.checked } : undefined, }; }) });