Skip to content

1 How it works

Deulfi edited this page Oct 7, 2026 · 4 revisions

Plain-language overview. The other pages cover the syntax.

What is a state?

A normal uosc button has one fixed icon and one fixed command. A ucm button has several states — different looks for the same button slot, each with its own icon, badge, tooltip and command, and its own active/hidden state. The button shows its current state; when nothing else applies, it shows the default state.

The control bar only fits so many buttons, and you rarely use every action at once. ucm lets you

  • put several similar actions on one button — the main one by default, the rarer ones revealed when you need them,
  • let a button follow the player — current resolution, current audio device, loop/shuffle on or off,
  • show a different set of buttons per situation — fullscreen, music, anime (hide the buttons you don't need, keep the bar minimal).

Ways a button changes

  • Keys (the basic way — no extra tools needed) — a key in input.conf sends set <state> or cycle to ucm; the button shows that state and stays there.
  • Modifier keys (needs inputevent) — hold a modifier (e.g. right mouse button) and the button shows the state mapped to it; release and it reverts to the default (short delay).
  • The player itself — a field can reference an mpv property and updates automatically when it changes (a badge with the resolution, a button active while loop is on).
  • Other scripts — can read and change buttons anytime via script messages — see Script messages.

Real examples (the commented buttons in ucm.conf)

  • Sibling actions — alt_previous / alt_next: previous/next track by default, hold the modifier for previous/next chapter. Same for alt_control_items: playlist, open file, file dialog — three actions, one button.
  • Following the player — alt_control_loop is active exactly while loop-playlist is on; alt_resolution's badge shows ?(p) (the current resolution) and its tooltip the exact w x h; alt_format shows the media format and the codec.
  • Audio device — audiodevice_button has one state per device and is active while that device is in use; a script can promote a state so the button always shows the device you're listening on.
  • Fullscreen — a button can have a dedicated fullscreen state (alt_control_items has one), and auto-profiles switch the default state per situation — see Profiles.

Why placeholders?

A button is written once but has to keep working across every video you play, and the player's situation keeps changing while you watch — the codec, the resolution, loop/shuffle on/off, which audio device is in use. A placeholder makes a field follow the player instead of being hardcoded: it asks mpv for a value right now and drops the answer into the field.

A property is any piece of mpv's live state — the play/pause flag, the volume, the current title, whether loop-playlist is on. mpv exposes hundreds of them (the manual lists them all), and a [[]] placeholder just asks for one by name. In the example conf you'll see it three ways:

  • alt_resolution badges with ?(p) (the current resolution) and the exact w x h in its tooltip.
  • alt_loop stays active while loop-playlist is on — the loop icon lights up only when you're looping.
  • alt_format shows the media format and the codec.

The other placeholder forms build on the same idea:

  • ?(p) — shows the current resolution as a label (FHD, 4K, …) instead of raw numbers.
  • ?(f) — shows the media format label.
  • [[property??value]] — highlights the button (active) while the property equals value.

See Placeholders for the full list — including the ?! / !! markers and UCM_NIL, which aren't covered above.

Clone this wiki locally