scootlaunch CLI reference
Every scootlaunch command and flag that ships today, and how it
behaves at the edges. What scootlaunch is for is in
Overview. The panel’s keys, config and theming are in
The panel.
Commands
Section titled “Commands”scootlaunch # open the panel (see The panel)scootlaunch --font PATH # the panel with an explicit typefacescootlaunch --config PATH # the panel with an explicit config filescootlaunch --check [--config PATH] # validate the config file and exitscootlaunch --list # every visible entry: id and name per linescootlaunch --list --all # hidden entries too, with their reasonscootlaunch --list --json # the agent JSON schema, one arrayscootlaunch --list --all --json # hidden entries included, with hidden setscootlaunch --list --lenient # Exec quoting the way GLib reads itscootlaunch --query TEXT # entries ranked for TEXT, best firstscootlaunch --query TEXT --json # the agent JSON schema, in ranked orderscootlaunch --query "" # empty query: by frecency, then namescootlaunch --run-id ID [--action A] # launch one entry headlessly, one JSON objectscootlaunch --dmenu [flags] # lines on stdin, the pick on stdoutscootlaunch --run # the panel over executables on $PATHscootlaunch --windows # the panel over open windows; Enter activatesscootlaunch --help # print helpscootlaunch --version # print the version--all and --json need --list or --query (--lenient
also shapes the panel’s index and --run-id). --action needs
--run-id. --font is a panel option; --config belongs to the
panel and --check. --list, --query, --run-id, --check,
--dmenu, --run and --windows cannot combine. --check refuses a bad config
file with exit 1, except a bad value in [effects]: that prints on
stderr and exits 0, as the panel ignores it. TEXT is the next
argument after --query, whatever it holds. Anything else is a loud
error: exit 2, naming the flag and the supported list, never silently
ignored. The panel launches the picked entry (exit 0) or nothing on
dismiss (exit 1): a launch prints nothing.
Dmenu mode
Section titled “Dmenu mode”--dmenu reads lines on stdin and prints the pick on stdout, with
fuzzel’s meaning for every flag the repo’s call sites pass. A dmenu
pick prints and launches nothing. The panel is drawn with the look’s
shadow, fill and opening (Depth and motion), and exits
the moment it prints, with no fade.
printf 'wifi-a\nwifi-b\n' | scootlaunch --dmenu --prompt='wifi: ' --no-run-if-empty --only-matchStdin is read to EOF before the first frame, with a 5 s bound on a
writer that never closes (after which what arrived is shown). Bounds:
at most 1 MiB and 65,536 lines, each line at most 4 KiB (longer lines
are cut at a character boundary). Non-UTF-8 input is decoded lossily;
NUL bytes ride through as text (there is no icon protocol in v1, so
foo\0icon\x1fbar is one literal line). An empty query shows stdin
order — the writer’s order, with no frecency to break it.
| Flag | Type / default | Example |
|---|---|---|
--prompt TEXT |
text, "> " |
--prompt='wifi: ' |
--prompt-only TEXT |
text, none (needs --dmenu) |
--prompt-only='key for net: ' |
--password |
flag, * |
--password |
--no-run-if-empty |
flag, off | --no-run-if-empty |
--only-match |
flag, off | --only-match |
--index |
flag, off | --index |
--placeholder TEXT |
text, empty | --placeholder='pick one' |
--layer overlay |
top or overlay, overlay |
--layer=overlay |
--prompt text takes its value attached (--prompt=TEXT) or as the
next argument. --prompt-only is an input field with no list: stdin
is not read at all (a password or WiFi-key prompt reading from
/dev/null). --password masks the entry with *; the secret is written to stdout
only on Enter, never logged, and wiped when the panel closes.
--password also hides the list, as --prompt-only does, so stdin
lines are never filtered or highlighted on the secret and Enter prints
what was typed. --no-run-if-empty exits 1 without
opening on empty stdin. With --prompt-only stdin is never read, so
--prompt-only --no-run-if-empty always exits 1 without opening.
--only-match makes Enter with no match do
nothing (without it the typed text prints); Ctrl+Enter still prints
the typed text, even with --only-match. --index prints the
0-based stdin position of the pick instead of its line. The panel is
always the overlay layer; top is accepted and draws the same.
Exit codes: 0 for a printed pick, 1 for a dismiss (Escape), an empty
feed with --no-run-if-empty, or a runtime failure, 2 for a usage
error (an unsupported flag, a missing value, --dmenu combined with
another command). A second scootlaunch --dmenu while one is open
opens a second panel: dmenu instances neither listen for nor send the
single-instance toggle.
Run mode
Section titled “Run mode”--run (alias --list-executables-in-path, fuzzel’s flag) opens the
panel over every executable file on $PATH: the first directory
naming a basename wins, at most 65,536 names. Typing filters,
frecency orders (keyed run:<basename> in the same history file),
and Enter launches the pick by basename through a PATH lookup —
under the same token, scope and fallback rules as an apps pick, and
recording the same history. Ctrl+Enter runs the typed text split on
spaces. Nothing prints; dismissing exits 1.
Run mode shares the panel’s single-instance toggle with the bare
panel. A second scootlaunch --run (or bare scootlaunch) while one
is open dismisses the first, which exits 1, and itself exits 0 without
opening or launching anything.
scootlaunch --runscootlaunch --list-executables-in-pathWindows mode
Section titled “Windows mode”--windows opens the panel over the compositor’s open windows through
wlr-foreign-toplevel-management. Enter (or a click) activates the
chosen window and exits 0; Escape exits 1. It takes the panel’s flags
(--font, --config, --lenient for the icon index, the
per-invocation colors and --layer) and no
dmenu flag. A compositor without the protocol is a refusal naming it
(exit 1) before any panel opens. Rows, icons, the bind to use and the
failure cases are in The panel.
Windows mode shares the panel’s single-instance toggle: a second
scootlaunch --windows (or a bare scootlaunch or --run) while one
is open dismisses the first, which exits 1, and itself exits 0 without
opening. --dmenu neither listens nor signals.
scootlaunch --windowsPer-invocation colors
Section titled “Per-invocation colors”Seven rrggbbaa flags override the look’s roles for one open,
above the user’s file and the look — the same seven the look passes
the repo’s pickers.
--layer=overlay rides along the same way (the launcher script
passes it to the bare panel too).
| Flag | Role |
|---|---|
--background-color |
panel fill (its alpha becomes the panel’s opacity) |
--text-color |
input and row text |
--border-color |
panel border |
--selection-color |
selected row fill |
--selection-text-color |
selected row text |
--match-color |
matched characters (on the selected row too when it contrasts with the fill; else the inverted chip, so the row stays legible) |
--prompt-color |
prompt text |
Only --background-color may be translucent; any other color with an
alpha past ff is refused loudly (exit 2), since the panel draws
those roles solid.
Ranking
Section titled “Ranking”The query matches case-insensitively (Unicode folded, so strasse
finds Straße) against the name, generic name, keywords and Exec
basename, in that weight order. A prefix beats a scattered match.
Each launch adds frecency weight: recent and frequent entries rank
higher, but never above a much better text match. The history lives
at $XDG_STATE_HOME/scootlaunch/history (default
~/.); deleting it clears the bonus. An entry’s desktop
actions rank as their own rows (“Firefox: New Private Window”) but
print once, at the best row’s position. Dmenu mode keeps no history:
an empty query shows stdin order.
The agent JSON schema
Section titled “The agent JSON schema”--list --json prints one JSON array. Each entry carries id,
name, generic_name, comment, keywords, icon (name or path),
exec (the expanded argv), terminal, dbus_activatable, actions
([{id, name}]), path (the desktop file) and hidden (null, or the
reason: NoDisplay, OnlyShowIn, NotShowIn, TryExec). Absent
optionals serialize away rather than as nulls. --query TEXT --json
prints the same schema in ranked order.
scootlaunch --list --json | jq '.[] | select(.id == "org.mozilla.firefox.desktop")'scootlaunch --query "fire" --json | jq '.[0] | {id, name}'Run one entry headlessly
Section titled “Run one entry headlessly”--run-id ID [--action A] launches one entry with no compositor
connection and no surface, through the same spawn path as a panel
pick (activation first for DBusActivatable entries, else Exec;
the environment rules, the systemd scope, the detached fallback with
no bus, frecency). A fresh spawn still takes focus on map. No token:
there is no surface and no serial to mint from.
Stdout carries exactly one JSON object, nothing else. Exit 0 prints a success object; exit 1 prints an error object. Notes and warnings go to stderr.
| Field | Type / default | Example |
|---|---|---|
ok |
true on success |
true |
pid |
number, when a child was spawned | 4242 |
scope |
text, when the scope move landed | "app-scootlaunch-firefox. |
activated |
true, when the launch was an in-place activation |
true |
detached |
true, when the launch went through the bus-less fallback |
true |
Only the fields that happened are present. A spawn whose scope move
was refused still runs: pid is set, scope is absent, and one
warning names the refusal on stderr.
scootlaunch --run-id org.mozilla.firefox.desktop# {"ok":true,"pid":4242,"scope":"app-scootlaunch-org.mozilla.firefox.desktop-1a2b3c4d.scope"}scootlaunch --run-id org.mozilla.firefox.desktop --action new-private-window# {"ok":true,"pid":4310,"scope":"app-scootlaunch-org.mozilla.firefox.desktop-9f8e7d6c.scope"}The id matches exactly (firefox.); the . suffix may
be left off when it names exactly one entry (firefox). Anything
else never launches: a prefix, a fuzzy match, or a suffix-insensitive
form naming more than one entry is an error. Hidden entries (--all)
are still launchable by id. The action must name one of the entry’s
actions exactly.
code |
Meaning |
|---|---|
invalid-id |
empty, longer than 1024 bytes, or holding control characters |
unknown-id |
no entry matches |
ambiguous-id |
the suffix-insensitive form matches more than one entry |
invalid-action |
empty, longer than 1024 bytes, or holding control characters |
unknown-action |
the entry has no action with that id |
launch-failed |
the spawn or activation failed (nothing started) |
Exit codes: 0 for a launch, 1 for a refused launch (the error object
above), 2 for a usage error (--action without --run-id,
--run-id combined with another command, a missing value). Commands
an agent can paste:
scootlaunch --list --json | jq '.[] | {id, name}'scootlaunch --query "fire" --json | jq '.[0] | {id, name}'scootlaunch --run-id org.mozilla.firefox.desktopscoot msg windows | jq '.windows[] | {app_id, title}'Symptom:
--run-idsaysunknown-idfor an app the list shows.
The list shows the exact id: copy it whole, suffix included. A typed prefix never launches.
Symptom:
--run-idsayslaunch-failedwith no window.
The Exec target vanished between the index and the launch, or the
activation was refused and no Exec fallback exists. The object’s
error names the step; the index note on stderr names the file.
Troubleshooting
Section titled “Troubleshooting”Symptom: an app is missing from the list.
Ask for the hidden entries with their reasons:
scootlaunch --list --all --json | jq '.[] | select(.hidden != null) | {id, hidden}'A TryExec reason means its helper is not installed or not
executable. An entry dropped entirely (not even listed with
--all) has no usable Exec — an unknown %x field code is the
usual cause — and the run says so on stderr with the file and the
reason. --lenient recovers the entries whose quoting breaks the
spec’s rule but parses the way GLib reads them.
Symptom: the list is stale after editing a desktop file.
The cache key covers every directory and file walked plus the locale
and $XDG_CURRENT_DESKTOP, so an edit rescans on the next run. A
bad cache is never an error: any mismatch means a rescan.
Symptom: a dmenu script that worked under fuzzel fails loudly.
scootlaunch --dmenu speaks the flags in the table above and
--index / --placeholder only. Any other fuzzel flag exits 2
naming the flag, so a script with another flag fails instead of
silently changing meaning.
