A key with `folder: NAME` swaps the deck to the keys defined under `folders.NAME`. Every folder shows a back key (slot 0 by default, drawn with a built-in chevron) that pops back to the parent; folders nest. The daemon now runs one page at a time: per-key setup moved into setupKey(), openPage() draws a page under its own context, and page.stop() tears it down before the next page is drawn (and on exit, so device death no longer waits on uncancelled goroutines). streamdeck-ctl gains `key set -folder`, reports kind "folder", lists every folder in status, and refuses to `key press` a navigation-only key. The Omarchy grid shows a folder glyph. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ARLa4moGb154fzc9TevgV
127 lines
4.0 KiB
YAML
127 lines
4.0 KiB
YAML
icons_dir: ./icons
|
||
brightness: 70
|
||
|
||
# Device USB IDs — defaults match Stream Deck XL v2.
|
||
# Run `lsusb | grep Elgato` to confirm yours.
|
||
device:
|
||
vendor_id: 0x0fd9
|
||
product_id: 0x00ba
|
||
|
||
# Keys are 0-indexed, left-to-right, top-to-bottom.
|
||
# Stream Deck XL layout (8 columns × 4 rows):
|
||
#
|
||
# 0 1 2 3 4 5 6 7
|
||
# 8 9 10 11 12 13 14 15
|
||
# 16 17 18 19 20 21 22 23
|
||
# 24 25 26 27 28 29 30 31
|
||
#
|
||
# icon: filename inside icons_dir (PNG or JPEG)
|
||
# command: any shell command
|
||
|
||
keys:
|
||
# Regular key: show an icon and run a command on press.
|
||
0:
|
||
icon: ghostty.png
|
||
command: ghostty
|
||
1:
|
||
icon: terminal.png
|
||
command: alacritty
|
||
2:
|
||
icon: files.png
|
||
command: nautilus
|
||
|
||
# Toggle/status key: polls a command to determine state and shows one of two
|
||
# icons. Pressing the button runs `command` and the icon updates automatically.
|
||
#
|
||
# `match` is a substring to find in the poll command's stdout.
|
||
# If match is found → icon_on is shown; otherwise → icon_off.
|
||
# Omit `match` entirely to use exit code instead (0 = on, non-zero = off).
|
||
#
|
||
# Examples:
|
||
# Microphone mute:
|
||
# command: pactl set-source-mute @DEFAULT_SOURCE@ toggle
|
||
# poll.command: pactl get-source-mute @DEFAULT_SOURCE@
|
||
# poll.match: "yes" # "Mute: yes" → muted → show icon_on (mic-muted.png)
|
||
#
|
||
# VPN toggle:
|
||
# command: nmcli connection up my-vpn / nmcli connection down my-vpn
|
||
# poll.command: nmcli connection show --active my-vpn
|
||
# (no match — uses exit code: 0 = connected)
|
||
#
|
||
# Systemd service:
|
||
# command: systemctl --user toggle my-service
|
||
# poll.command: systemctl --user is-active my-service
|
||
# (no match — uses exit code)
|
||
#
|
||
# 3:
|
||
# command: pactl set-source-mute @DEFAULT_SOURCE@ toggle
|
||
# icon_true: mic-muted.png
|
||
# icon_false: mic-active.png
|
||
# poll:
|
||
# command: pactl get-source-mute @DEFAULT_SOURCE@
|
||
# interval: 2s
|
||
# match: "yes"
|
||
|
||
# --- Dynamic text from command output ---
|
||
#
|
||
# text_command: a shell command whose stdout is rendered as the key's label,
|
||
# re-run every `refresh` interval (default 1s; floored to 250ms). Newlines
|
||
# in the output become label line breaks; trailing whitespace is trimmed.
|
||
# `text` (if set) is the static fallback shown before the first run or when
|
||
# the command errors / outputs nothing. Composited over `icon` each tick.
|
||
#
|
||
# NOTE: use the ABSOLUTE binary path — the service runs with a minimal PATH.
|
||
# Apple Silicon Homebrew installs may live at /opt/homebrew/bin/flow instead.
|
||
#
|
||
# Pomodoro (`flow`) live countdown — press toggles start/pause:
|
||
# 8:
|
||
# icon: pomodoro.png # base icon; text on top
|
||
# text_command: "/usr/local/bin/flow status --short" # prints e.g. WORK\n24:12 (real newline)
|
||
# refresh: 1s
|
||
# text_color: "#FFFFFF"
|
||
# command: "/usr/local/bin/flow toggle"
|
||
#
|
||
# Separate icon-swap indicator (running vs paused):
|
||
# 9:
|
||
# icon_true: running.png
|
||
# icon_false: paused.png
|
||
# command: "/usr/local/bin/flow toggle"
|
||
# poll:
|
||
# command: "/usr/local/bin/flow status" # prints: state=running phase=work remaining=24:12
|
||
# interval: 1s
|
||
# match: "state=running"
|
||
#
|
||
# Control keys:
|
||
# 10:
|
||
# icon: skip.png
|
||
# command: "/usr/local/bin/flow skip"
|
||
# 11:
|
||
# icon: stop.png
|
||
# command: "/usr/local/bin/flow stop"
|
||
# 12:
|
||
# icon: gui.png
|
||
# command: "/usr/local/bin/flow gui"
|
||
#
|
||
# A text-only live clock (no icon → white text on black), refreshed each second:
|
||
# 13:
|
||
# text_command: "date +%H:%M:%S"
|
||
# refresh: 1s
|
||
|
||
# Folders: a key with `folder:` opens a second page of keys. Every folder shows
|
||
# a back key (slot 0 by default, built-in arrow) that returns to the parent.
|
||
# Folders can open other folders.
|
||
#
|
||
# 7:
|
||
# icon: folder.png
|
||
# text: Media
|
||
# folder: media
|
||
#
|
||
# folders:
|
||
# media:
|
||
# back: # optional: key, icon, text, text_color
|
||
# key: 0
|
||
# keys:
|
||
# 1:
|
||
# icon: play.png
|
||
# command: playerctl play-pause
|