feat(blankpad): desk.sh profile switcher, hotplug autoswitch daemon, keybinds doc generator + bats suite
- desk.sh: list/current/switch/cycle/match/capture over cfg/desk-*.kdl profiles; apply = relink display.kdl, niri validate (rollback on fail), load-config-file, noctalia notification; match scores // requires: lines (EDID long names) against live niri msg outputs - desk-autoswitch.sh: watch niri msg --json event-stream for OutputsChanged, debounced desk.sh match --apply, reconnect loop - blankpad-desk-autoswitch.service: ConditionHost=blankpad user unit - gen-keybinds.sh: keybinds.kdl -> markdown cheat sheet (sections from // --- headers, hotkey-overlay-title preferred over action) - tests/: 27 bats cases, all green (desk 16, gen-keybinds 6, niri-config 5 incl. real niri validate on the assembled tree with each desk profile active)
This commit is contained in:
1 parent
4ec47a5b7e
commit
f63d11de85
10 files changed
+703
No files matched your search
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/desk-autoswitch.sh — hotplug daemon: apply the matching desk profile
|
||||
# whenever niri reports an OutputsChanged event.
|
||||
#
|
||||
# Usage: desk-autoswitch.sh watch
|
||||
#
|
||||
# Environment overrides:
|
||||
# DESK_AUTO_HOSTNAME only run on this hostname (default: blankpad)
|
||||
# DESK_SCRIPT path to desk.sh (default ~/.local/bin/desk.sh)
|
||||
# DESK_NIRI niri binary (default niri)
|
||||
# DESK_DEBOUNCE_S debounce window in seconds (default 1.5)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HOST="${DESK_AUTO_HOSTNAME:-blankpad}"
|
||||
DESK="${DESK_SCRIPT:-$HOME/.local/bin/desk.sh}"
|
||||
NIRI="${DESK_NIRI:-niri}"
|
||||
DEBOUNCE="${DESK_DEBOUNCE_S:-1.5}"
|
||||
|
||||
usage() {
|
||||
sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'
|
||||
}
|
||||
|
||||
watch_mode() {
|
||||
[ "$(hostname)" = "$HOST" ] || { echo "desk-autoswitch: not on $HOST, exiting"; exit 0; }
|
||||
echo "desk-autoswitch: initial match"
|
||||
"$DESK" match --apply || true
|
||||
|
||||
local last=0 now
|
||||
# One JSON event per line; reconnect forever (niri restart drops the stream).
|
||||
while "$NIRI" msg --json event-stream 2>/dev/null | while IFS= read -r line; do
|
||||
case "$line" in
|
||||
*OutputsChanged*)
|
||||
now="$(date +%s.%N)"
|
||||
# swallow bursts inside the debounce window
|
||||
if awk -v l="$last" -v n="$now" -v d="$DEBOUNCE" 'BEGIN { exit !(n - l >= d) }'; then
|
||||
last="$now"
|
||||
echo "desk-autoswitch: OutputsChanged"
|
||||
"$DESK" match --apply || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done; do :; done
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
watch) watch_mode ;;
|
||||
-h|--help) usage ;;
|
||||
*) usage >&2; exit 1 ;;
|
||||
esac
|
||||
Reference in new issue
Block a user