ConstClose the active self-drawn popup menu, if any.
mode is one of 'auto' | 'selection' | 'playlist' | 'nowPlaying' | 'handles'.
Prefer 'selection', 'playlist' or 'nowPlaying' whenever the target
is reachable from the host playlist: those resolve handles inside the
host and validate no paths. 'handles' validates every supplied path
individually, which costs filesystem metadata calls per entry and is
noticeably slower for network shares.
A command leaf's source is contextmenu_dynamic when it carries
subGuid, otherwise contextmenu_static.
root scopes the returned menu tree (e.g. 'View').
opts.locale selects the displayLabel translation locale; the
default 'auto' keeps the host's native labels untranslated.
opts.i18n: false disables label translation entirely.
opts.withAvailability (default true) includes per-submenu
command availability counters.
Leaf source follows the provider's node kind. Dynamic leaves without a
usable subGuid remain dynamic and are not executable. Addressability
is independent of enabled; addressCandidates is diagnostic only.
Every leaf of the v1 HMENU tier reports
hmenu_fallback. The flat fallback (fallback: true) keeps flags
and has no commandId; see MenuCommand.
Show a self-drawn popup menu and await the user's choice. Resolves
with the selected item id, or null when the menu is dismissed
(outside click, Escape, or any other close reason). Events are
matched by the menu id returned from menu.show, so overlapping
callers never cross-resolve. The listeners are attached before
menu.show is sent, so a result that reaches the page ahead of the
call's response still settles the promise.
opts is the same per-call presentation config as show;
windowModel: 'contentSized' is the recommended model for a context
menu. Rich controls report through menu:valueChanged without closing
the menu, so this promise stays pending until an ordinary row is chosen
or the menu is dismissed — subscribe to that event separately to track
value changes.
document.addEventListener('contextmenu', async (e) => {
e.preventDefault();
const id = await fb.menu.popup(items, undefined, {
windowModel: 'contentSized',
backdrop: 'acrylic',
});
if (id) console.log('selected', id);
});
Runs a context-menu command against the now-playing track, falling back to the active playlist selection.
command accepts a GUID or a command name. opts.subGuid addresses a
dynamically generated child (a rating value, a converter preset); without
it the owning container is targeted instead, which is a silent no-op.
executionConfirmed distinguishes "the host reported the command ran"
from "the command was dispatched through an entry point that returns
nothing". It is absent on the early-validation failures.
Runs the context-menu node whose commandId getContextMenu
reported. The host rebuilds the menu from opts.mode and opts.handles,
so pass the values that call used; an id the rebuilt menu lacks fails
with code: 'NOT_FOUND'.
An id is a position, so a changed menu or selection can make it run
another item. Pass the node's path as opts.expectPath and the menu's
targetKey as opts.expectTarget to have the host refuse instead; the
refusal carries details.reason and runs nothing, so reopen the menu.
Runs a main menu command.
command accepts a GUID ('{11213A01-...}'), a leaf name, or a
slash-separated path. Prefer the GUID: it is the only form that is stable
across hosts, because a localized build reports localized labels.
opts.subGuid addresses a dynamic child command, paired with its owning
command GUID. A path must match every ancestor; a wrong prefix never
falls back to the leaf name. Root-filtered results keep their full paths.
Business failures resolve as success: false with a code:
MENU_ITEM_DISABLED (command exists but is greyed out),
MENU_MATCH_AMBIGUOUS (identity is ambiguous; see details.candidates),
MENU_COMMAND_NOT_FOUND (no command has that name or path), NOT_FOUND
(no command owns that GUID), or OPERATION_FAILED (state cannot be read
or the provider fails). Dynamic containers cannot be executed.
Show a self-drawn (WebView-rendered) popup menu at position
(defaults to the cursor). Resolves with the new menu id; the
user's choice arrives asynchronously via the menu:select /
menu:dismiss events, and a rich control's value change via
menu:valueChanged (which leaves the menu open). Prefer
popup when you only need the chosen item id.
opts configures presentation per call. For a context menu prefer
windowModel: 'contentSized', which draws each panel in a compact
window carrying the real DWM MenuPopupOptions.backdrop material
and the system shadow; opts.css restyles the menu (and with
cssReplace: true takes the look over entirely).
const { menuId } = await fb.menu.show(items, { x: e.screenX, y: e.screenY }, {
windowModel: 'contentSized',
backdrop: 'acrylic',
css: '.fb-menu { background: rgba(32, 32, 32, 0.82); }',
});
Defaults to auto: handles, now playing, playlist selection, then
playlist context.
The same cost note as getContextMenu applies — prefer
mode: 'selection' over supplying handles for playlist rows.
menu- main menu, context menu, and self-drawn popup menu namespace.