aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dot_config/waybar
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:35 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:35 +0100
commitaba0bd84ac3b92d45f55b03692814e496358fe25 (patch)
treebecb1b13e2f6c29bfb832a78158904202c783111 /dot_config/waybar
parent54eacef87b906835f9778d9c4b02128398bf88d0 (diff)
downloaddotfiles-aba0bd84ac3b92d45f55b03692814e496358fe25.tar.gz
dotfiles-aba0bd84ac3b92d45f55b03692814e496358fe25.tar.bz2
dotfiles-aba0bd84ac3b92d45f55b03692814e496358fe25.zip
feat(waybar): pacdiff + failed-units reminders
Two live waybar modules — no timer/state-file pipeline because the inputs are cheap to compute on every poll: custom/pacdiff (interval 300s) Counts unresolved .pacnew / .pacsave files via `pacdiff -o` (output mode — lists only, takes no action). Hidden at zero. Yellow 'pacdiff N' otherwise. Mako fires once on the 0→N transition, so you get exactly one nudge per upgrade wave, not a sustained re-nag for files you've decided to defer. Click runs `sudo DIFFPROG='nvim -d' pacdiff` in a floating ghostty. custom/failed-units (interval 30s) Sums `systemctl --failed` (system) and `systemctl --user --failed` counts. Hidden at zero. Red 'failed N' otherwise. Mako fires only on upward transition (count went up since last poll), so already-known failures don't keep paging you while you investigate. Click prints both `systemctl --failed` outputs in a floating ghostty. Both modules use the same $XDG_RUNTIME_DIR/waybar-X-prev pattern as the update reminder for state, which makes 'reboot resets the nag' the default behaviour — exactly the right semantics for both: a fresh boot deserves a fresh look at pending pacdiffs and any failed units.
Diffstat (limited to 'dot_config/waybar')
-rwxr-xr-xdot_config/waybar/executable_failed-units-status.sh53
-rwxr-xr-xdot_config/waybar/executable_pacdiff-status.sh52
2 files changed, 105 insertions, 0 deletions
diff --git a/dot_config/waybar/executable_failed-units-status.sh b/dot_config/waybar/executable_failed-units-status.sh
new file mode 100755
index 0000000..da7db49
--- /dev/null
+++ b/dot_config/waybar/executable_failed-units-status.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Waybar custom/failed-units: shows count of failed systemd units across
+# the system bus and the current user's session bus. Hidden when zero.
+# Mako fires only on transition upward (count went up since last check),
+# so transient failures you've already seen don't re-nag.
+#
+# Click handler shows `systemctl --failed` and `systemctl --user --failed`
+# in a floating ghostty.
+
+set -eu
+
+STATE=${XDG_RUNTIME_DIR:-/tmp}/waybar-failed-units-prev
+
+emit_empty() {
+ printf '{"text":"","class":"fresh","tooltip":""}\n'
+ printf 0 >"$STATE" 2>/dev/null || :
+ exit 0
+}
+
+count_failed() {
+ systemctl "$@" --failed --no-legend --plain 2>/dev/null |
+ grep -c . || :
+}
+
+sys=$(count_failed)
+usr=$(count_failed --user)
+case "$sys" in '' | *[!0-9]*) sys=0 ;; esac
+case "$usr" in '' | *[!0-9]*) usr=0 ;; esac
+total=$((sys + usr))
+
+[ "$total" -eq 0 ] && emit_empty
+
+text="failed ${total}"
+tooltip="${sys} system + ${usr} user unit(s) failed — click for details"
+printf '{"text":"%s","class":"critical","tooltip":"%s"}\n' "$text" "$tooltip"
+
+prev=0
+if [ -f "$STATE" ]; then
+ prev=$(cat "$STATE" 2>/dev/null || printf 0)
+ case "$prev" in '' | *[!0-9]*) prev=0 ;; esac
+fi
+
+if [ "$total" -gt "$prev" ] &&
+ command -v notify-send >/dev/null 2>&1; then
+ notify-send \
+ --app-name=systemd \
+ --urgency=critical \
+ --icon=dialog-error \
+ "Systemd unit failure" \
+ "${sys} system + ${usr} user unit(s) failed. Click the bar entry for details."
+fi
+
+printf '%s' "$total" >"$STATE"
diff --git a/dot_config/waybar/executable_pacdiff-status.sh b/dot_config/waybar/executable_pacdiff-status.sh
new file mode 100755
index 0000000..dad3166
--- /dev/null
+++ b/dot_config/waybar/executable_pacdiff-status.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Waybar custom/pacdiff: shows count of unresolved .pacnew/.pacsave files.
+# Source of truth is `pacdiff -o` (output mode — lists differing files,
+# does nothing). Hidden when zero. Mako fires once when the count goes
+# from "no problems" to "non-zero" (i.e. on the post-`pacman -Syu`
+# settle), so you're nudged exactly once per upgrade wave.
+#
+# Click handler runs `sudo DIFFPROG='nvim -d' pacdiff` in a floating
+# ghostty.
+
+set -eu
+
+STATE=${XDG_RUNTIME_DIR:-/tmp}/waybar-pacdiff-prev
+
+emit_empty() {
+ printf '{"text":"","class":"fresh","tooltip":""}\n'
+ printf 0 >"$STATE" 2>/dev/null || :
+ exit 0
+}
+
+command -v pacdiff >/dev/null 2>&1 || emit_empty
+
+count=$(pacdiff -o 2>/dev/null | grep -c . || :)
+case "$count" in
+ '' | *[!0-9]*) count=0 ;;
+esac
+
+[ "$count" -eq 0 ] && emit_empty
+
+text="pacdiff ${count}"
+tooltip="${count} unresolved .pacnew/.pacsave file(s) — click to merge with \`nvim -d\`"
+printf '{"text":"%s","class":"warn","tooltip":"%s"}\n' "$text" "$tooltip"
+
+prev=0
+if [ -f "$STATE" ]; then
+ prev=$(cat "$STATE" 2>/dev/null || printf 0)
+ case "$prev" in
+ '' | *[!0-9]*) prev=0 ;;
+ esac
+fi
+
+if [ "$prev" -eq 0 ] && [ "$count" -gt 0 ] &&
+ command -v notify-send >/dev/null 2>&1; then
+ notify-send \
+ --app-name=pacdiff \
+ --urgency=normal \
+ --icon=text-x-generic \
+ "Pacman config files need merging" \
+ "${count} .pacnew/.pacsave file(s). Click the bar entry to run pacdiff."
+fi
+
+printf '%s' "$count" >"$STATE"