Skip to content

SDK event system

Event names use colon notation, such as playback:trackChanged. Method invocations use dot notation, such as playback.play.

Subscribe

javascript
// Subscribe and retain the returned unsubscribe function.
const unsubscribe = fb.on('playback:trackChanged', (track) => {
    console.log('Now playing:', track.title);
});

// Unsubscribe.
unsubscribe();

Subscribe once

javascript
fb.once('playback:trackChanged', (track) => {
    console.log('First track:', track.title);
});

Unsubscribe

javascript
// Preferred: call the function returned by fb.on().
const unsub = fb.on('playback:time', handler);
unsub();

// Alternatively, remove the same handler explicitly.
fb.on('playback:time', handler);
fb.off('playback:time', handler);

Playback events

EventEmitted whenPayload
playback:trackChangedThe current track changesPlaybackTrackChangedPayload
playback:stateChangedPlayback state changes{ state, position?, duration? }
playback:pausedPause state changes{ paused }
playback:stoppedPlayback stops{ reason }
playback:startingPlayback is about to start{ command, paused? }
playback:seekedPlayback position is changed{ position }
playback:volumeChangedVolume or mute state changes{ volume, volumeDb, muted, isMuted }
playback:timeThe normal-resolution position updates{ position }
playback:timeHighResThe high-resolution position updates{ position }
playback:orderChangedPlayback order changes{ orderIndex, order }
playback:queueChangedPlayback queue changes{ origin }
playback:editedCurrent-track metadata changesPlaybackEditedPayload
playback:dynamicInfoStream information changes{ bitrate, streamTitle? }
playback:dynamicInfoTrackDynamic stream-track metadata changes{ artist?, title? }
playback:itemPlayedA track finishes playingPlaybackItemPlayedPayload
playback:stopAfterCurrentChangedStop-after-current changes{ enabled }
playback:followCursorChangedPlayback-follow-cursor changes{ enabled }
playback:cursorFollowChangedCursor-follow-playback changes{ enabled }

Playlist events

EventEmitted whenPayload
playlist:activatedActive playlist changes{ oldIndex, newIndex }
playlist:createdA playlist is created{ index, name }
playlist:removedA playlist is removed{ oldCount, newCount }
playlist:renamedA playlist is renamed{ index, name }
playlist:reorderedPlaylist order changes{ count }
playlist:lockChangedPlaylist lock state changes{ playlist, locked }
playlist:itemsAddedItems are added{ playlist, start, count }
playlist:itemsRemovedItems are removed{ playlist, oldCount, newCount }
playlist:itemsReorderedItems are reordered{ playlist, count }
playlist:itemsReplacedItems are replaced{ playlist, count }
playlist:selectionChangedSelection changes{ playlist }
playlist:focusChangedFocused item changes{ playlist, from, to }
playlist:defaultFormatChangedDefault formatting changesEmpty object
playlist:addCompleteAn asynchronous add completes{ operationId, success, addedCount, totalCount }

Library, metadata, and selection events

EventEmitted whenPayload
library:itemsAddedLibrary items are added{ count, timestamp }
library:itemsRemovedLibrary items are removed{ count, timestamp }
library:itemsModifiedLibrary items are modified{ count, timestamp }
library:initializedLibrary initialization completes{ timestamp }
library:getAllResultAn asynchronous library.getAll result is readyLibraryGetAllResultPayload
metadata:writeCompleteAn asynchronous metadata write completesMetadataWriteCompletePayload
metadb:changedMetadata changes{ tracks, count, fromHook, timestamp }
selection:changedGlobal selection changes{ count, type, handles, truncated, track, nowPlaying }

Audio events

EventEmitted whenPayload
audio:spectrumSubscribed spectrum data updates{ spectrum, fftSize?, bands? }
audio:streamSubscribed audio-stream data updatesCurrently typed as an empty object
audio:dspPresetChangedDSP preset changesEmpty object
audio:outputDeviceChangedOutput device changesEmpty object
audio:replaygainModeChangedReplayGain mode changes{ mode }
audio:fullWaveformReadyFull-waveform generation completesAudioFullWaveformReadyPayload
audio:fullWaveformFailedFull-waveform generation fails{ taskId, path, error, code }

Window, panel, UI, and desktop events

EventEmitted whenPayload
window:alwaysOnTopChangedAlways-on-top changes{ enabled }
window:stateChangedWindow state changesCanonical isMaximized, isMinimized, isActive, and isFullscreen fields plus compatibility aliases
window:popupOpenedA popup opens{ windowId, title, url }
window:popupClosedA popup closes{ windowId }
window:beforeCloseClose confirmation is requested{ windowId }
window:messageA cross-window message arrives{ sourceWindowId, message }
window:behaviorChangedPopup behavior changes{ windowId, profile, behavior, resolvedBehavior }
window:minimizeSuppressedA minimize action is suppressed{ windowId, reason }
window:backdropStateChangedA backdrop activation policy is applied{ windowId, active, mode, effect }
window:hoverStateChangedWindow hover state changes{ windowId, reason?, hovering? }
panel:initializedPanel initialization completesPanelInitializedPayload
panel:focus / panel:blurPanel focus changesEmpty object
panel:visibilityChangedDUI panel visibility changes{ visible }
panel:configChangedPanel configuration changesPanelConfigChangedPayload
ui:coloursChanged / ui:fontChangedUI colors or fonts changeUnspecified object
ui:menuItemClickedA UI menu item is clicked{ id, label }
ui:toastA toast is requested{ message, duration, type, position }
system:themeChangedSystem theme changes{ darkMode }
cursor:hiddenChangedCursor hidden state changesCursorHiddenChangedPayload
taskbar:buttonClickedA taskbar button is clicked{ id }
webview:processFailedA WebView process fails or recovers{ kind, kindRaw, recovered, recoveryAction }

Tray events

The tray icon is application-scoped and has no source window. Its events are broadcast to all windows.

EventEmitted whenPayload
tray:clickThe tray icon is clicked{ button, x, y }
tray:doubleClickThe tray icon is double-clicked{ x, y }
tray:beforeContextMenuBefore the context menu opens{ x, y }
tray:menuItemClickedAn ordinary tray item is selected or a rich value changes{ id, value? }

Ordinary user items and now-playing cards report { id } and close the menu. Rich value controls report { id, value } and keep it open: ratings use 0..5, sliders use an integer in [min, max], and segmented controls use the selected zero-based index. Built-in showPlaybackControls / showSystemItems injections and items declaring playbackAction execute natively and do not fire this event.

Application, keyboard, and menu events

EventEmitted whenPayload
app:beforeQuitfoobar2000 is about to quitEmpty object
keyboard:hotkeyA registered hotkey fires{ id, key, action }
menu:showA custom menu opens{ menuId }
menu:selectA custom-menu item is selected{ menuId, itemId }
menu:dismissA custom menu closes{ menuId, reason }

Cross-window events

EventEmitted whenPayload
port:connectedA named port connects{ portId, name, windowId }
port:disconnectedA named port disconnects{ portId, name, windowId }
port:messageA port message arrives{ portId, sourcePortId, sourceWindowId, message }
state:changedShared state changes{ key, value, previousValue, sourceWindowId, expiresAt? }
state:deletedShared state is removed or expires{ key, sourceWindowId, reason }

Plugin, HTTP, and JIT queue events

EventEmitted whenPayload
plugin:registered / plugin:unregisteredAn external plugin is registered or removedPluginRegisteredPayload / PluginUnregisteredPayload
api:registered / api:unregisteredAn external API is registered or removedApiRegisteredPayload / ApiUnregisteredPayload
http:responseAn asynchronous HTTP request completesHttpResponsePayload
http:downloadCompleteA download completesHttpDownloadCompletePayload
jitQueue:needNextThe host requests the next item{ currentTrackId, reason }
jitQueue:trackChangedThe JIT queue's current track changes{ trackId, title }
jitQueue:listExhaustedThe JIT queue buffer is exhausted{ lastTrackId }
jitQueue:preloadCompleteJIT preloading completesJitQueuePreloadCompletePayload
jitQueue:errorA JIT queue item fails{ trackId, error, url? or path? }

Host events are also dispatched as fb2k:* DOM CustomEvent instances.

See the event-system reference for the complete payload reference. SMP event-name mappings are documented in the SMP compatibility layer.