fb.menu Menu APIs
fb.menu queries and executes main or context menu commands and provides WebView-rendered popup menus.
SDK Method Stubs
This block maintains SDK-facing method coverage and may be expanded with complete examples and best practices.
getContextMenu()
Signature: fb.menu.getContextMenu(options?: MenuGetContextMenuParams): Promise<MenuGetContextMenuResponse>
| Parameter | Type | Required | Description |
|---|---|---|---|
options.mode | string | No | Context mode: 'auto', 'selection', 'playlist', 'nowPlaying', or 'handles'. |
options.handles | unknown[] | No | Handles used by handle-based context. |
options.path | string | No | Optional track path. |
options.subsong | number | No | Optional subsong index. |
options.locale | string | No | Locale selector; defaults to 'auto'. |
options.i18n | boolean | No | Enables localized labels. |
options.withAvailability | boolean | No | Includes availability metadata. |
Returns a MenuGetContextMenuResponse containing the recursive items menu tree and context metadata.
const result = await fb.menu.getContextMenu({ mode: 'nowPlaying' });Use selection for the selected tracks in the active playlist. playlist is the playlist-level context and may contain only playlist-wide commands.
const result = await fb.menu.getContextMenu({ mode: 'selection' });getMainMenu()
Signature: fb.menu.getMainMenu(root?: string): Promise<MenuGetMainMenuResponse>
| Parameter | Type | Required | Description |
|---|---|---|---|
root | string | No | Limits the returned tree, for example 'Main' or 'View'. |
Returns a MenuGetMainMenuResponse. The optional items field is a recursive MenuItem[] tree.
const result = await fb.menu.getMainMenu('View');runContextCommand()
Signature: fb.menu.runContextCommand(command: string): Promise<BaseResponse & { guid?: string; itemCount?: number }>
| Parameter | Type | Required | Description |
|---|---|---|---|
command | string | Yes | Context-menu command path or name. |
Invokes only menu.runContextCommand. The response may include the command guid and affected itemCount.
const result = await fb.menu.runContextCommand('Properties');runMainMenuCommand()
Signature: fb.menu.runMainMenuCommand(command: string): Promise<BaseResponse & { guid?: string }>
| Parameter | Type | Required | Description |
|---|---|---|---|
command | string | Yes | Main-menu command path. |
Returns the menu.runMainMenuCommand response envelope and may include the resolved guid.
const result = await fb.menu.runMainMenuCommand('View/Console');showNativePopup()
Signature: fb.menu.showNativePopup(options?: MenuShowNativePopupParams): Promise<MenuShowNativePopupResponse>
| Parameter | Type | Required | Description |
|---|---|---|---|
options.mode | string | No | Context mode; defaults to 'auto'. Auto tries handles, now playing, playlist selection, then playlist context. |
options.handles | unknown[] | No | Optional handle list. |
options.path | string | No | Optional track path. |
options.subsong | number | No | Optional subsong index. |
Returns the menu.showNativePopup response envelope. Native rendering is scheduled by the host.
const result = await fb.menu.showNativePopup({ mode: 'selection' });Self-drawn Popup Menus
menu.show, menu.close, and menu.popup render a context menu in WebView rather than through the native Win32 popup. The renderer supports submenus, keyboard navigation, and ::part() theme hooks.
Boundary with tray zones: public
menu.showalways uses direct item children under#menu > .fb-item; it does not produce.fb-zonecontainers. Zoned layout throughlayoutMode: 'zones'is an opt-in capability oftray.setContextMenuwithrender: 'webview'.
fb.menu.popup(items, position?)
Preferred convenience API. It displays a self-drawn menu and waits for a selection. It resolves to the selected item's id, or null when the menu is dismissed by an outside click, Escape, or another close reason. Events are correlated by menu ID, so overlapping calls do not resolve one another.
const id = await fb.menu.popup(
[
{ id: 'play', label: 'Play' },
{ id: 'queue', label: 'Add to queue', checked: true },
{ type: 'separator' },
{ id: 'more', label: 'More', submenu: [
{ id: 'props', label: 'Properties' },
{ id: 'remove', label: 'Remove', enabled: false },
] },
],
{ x: 200, y: 150 },
);
if (id) console.log('selected', id);2
3
4
5
6
7
8
9
10
11
12
13
Omit position or either coordinate to use the current cursor coordinate for that axis.
fb.menu.show(items, position?)
Low-level API. It shows the menu and resolves with MenuShowResponse, including { success, menuId } on success. User interaction arrives asynchronously through menu:select and menu:dismiss.
const { menuId } = await fb.menu.show([{ id: 'a', label: 'A' }]);
fb.on('menu:select', (e) => { if (e.menuId === menuId) console.log(e.itemId); });
fb.on('menu:dismiss', (e) => { if (e.menuId === menuId) console.log('dismissed', e.reason); });2
3
Caller, Security, and Resource Boundaries
- Public entry points: theme pages may call
menu.show,menu.close, andmenu.popup. Internal endpoints such asmenu.__select,menu.__valueChanged,menu.__dismiss,menu.__ready, andmenu.__getMenuStatebelong to the overlay window and are not part of the public SDK contract. - Authorization: an unauthorized internal IPC call, including an incorrect caller or mismatched
menuId, returnsINVALID_PARAMSwithout changing menu state. - Validation limits: validation is transactional before the overlay opens. Exceeding a limit returns
success: false;detailsidentifiesfield,limit, andactual.- At most 512 total items.
- At most 8 recursive levels, with the root at level 1.
- The shared renderer allows at most 64 options in one internally supplied
segmenteditem.segmentedis not part of the publicMenuPopupItemtype. - The shared renderer allows at most 256 KiB of SVG
contentper menu after oversized individual icons are discarded. The publicMenuPopupItemtype does not expose an SVG field.
- Individual SVG limit: within the shared renderer, an icon larger than 32 KiB is discarded without failing the entire menu.
- This API is a generic self-drawn menu, not the tray-zone configuration surface. Use
tray.setContextMenuortray.appendMenuItemsfor top, playback, and bottom tray zones.
fb.menu.close(reason?)
Closes the active self-drawn menu. The facade omits the reason field when no reason is supplied.
await fb.menu.close('api');MenuPopupItem
| Field | Type | Description |
|---|---|---|
id | string | Stable ID echoed through menu:select. |
label | string | Visible row text; omitted for separators. |
type | 'normal' | 'separator' | 'separator' renders a divider. |
enabled | boolean | Disabled rows cannot be selected; defaults to enabled. |
checked | boolean | Displays a check mark. |
submenu | MenuPopupItem[] | Nested child items rendered as a flyout. |
Events
| Event | Payload | Timing |
|---|---|---|
menu:show | MenuShowPayload with { menuId } | The menu becomes visible. |
menu:select | MenuSelectPayload with { menuId, itemId } | An item is selected; the menu then closes. |
menu:dismiss | MenuDismissPayload with { menuId, reason } | The menu closes. Host reasons include outside, escape, select, api, timeout, and blur. |
Main and Context Menu Query/Execution
await fb.menu.getMainMenu('View');
await fb.menu.getContextMenu({ mode: 'auto' });
await fb.menu.runMainMenuCommand('View/Console');
await fb.menu.runContextCommand('Properties');
await fb.menu.runContextCommandById(3, { mode: 'selection' });
await fb.menu.showNativePopup({ mode: 'selection' });2
3
4
5
6
runContextCommandById(id, options?) is a separate facade method even though it is not listed in the generated stub block. options is Omit<MenuRunContextCommandByIdParams, 'id'>.