diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-29 11:56:14 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-29 11:56:14 +0200 |
| commit | 3bcadc0fd35cb1e077a77c847bbc044ca2fabce3 (patch) | |
| tree | 9cc8bb74806eb266b0244c40858dfa0b9e9026e2 /bin | |
| parent | ff7dcf3ef2338a0aef1856a33da06d1a92c2434c (diff) | |
| download | unified-desktop-theme-3bcadc0fd35cb1e077a77c847bbc044ca2fabce3.tar.gz unified-desktop-theme-3bcadc0fd35cb1e077a77c847bbc044ca2fabce3.zip | |
feat(steps): hand pending root steps to a quickshell window
Notification balloons carried the GRUB and homepage root commands, but a
balloon cannot stay open while its commands are pasted into a root shell.
bin/udt-steps NAME writes a consumer's pending steps to
~/.cache/udt/steps/NAME and pokes quickshell's appearance shell, which shows
one tab per file on DP-3. Empty stdin clears the tab, so producers report
on every run and a consumer that caught up drops out by itself.
udt-grub and udt-homepage now route through it. install.sh's SDDM block
checks what is installed and reports only the steps still missing, rather
than printing the full install on every run. udt-homepage remembers the
last staged pair, since udt-accent now also runs on icon switches, which
change neither file and would re-raise the finish steps for nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/udt-grub | 48 | ||||
| -rwxr-xr-x | bin/udt-homepage | 33 | ||||
| -rwxr-xr-x | bin/udt-steps | 36 |
3 files changed, 86 insertions, 31 deletions
diff --git a/bin/udt-grub b/bin/udt-grub index 20fd296..273389c 100755 --- a/bin/udt-grub +++ b/bin/udt-grub @@ -10,8 +10,8 @@ # and a scheme switch leave the copy stale. # # udt-accent starts this detached on every run; install.sh runs it in the -# foreground. A notification goes out only when an installed theme is stale: -# a machine that never installed it has nothing to refresh. +# foreground. The root steps go to the steps window through udt-steps, and +# the tab clears itself once /boot matches the build. repo="$(dirname "$(readlink -f "$0")")/.." grub_repo="$(realpath -m "$repo/../grub-theme-udt")" @@ -28,23 +28,33 @@ flock 9 theme=/boot/grub/themes/udt copy="rm -rf $theme && cp -r \"$grub_repo/dist/udt\" /boot/grub/themes/" -if diff -rq "$grub_repo/dist/udt" "$theme" >/dev/null 2>&1; then - echo "grub theme: up to date" -elif [ -d "$theme" ]; then - echo "grub theme: refresh as root" +steps() { + if diff -rq "$grub_repo/dist/udt" "$theme" >/dev/null 2>&1; then + return + elif [ -d "$theme" ]; then + echo "The GRUB theme was rebuilt. Refresh the copy in /boot as root:" + else + echo "The GRUB theme is built but not installed. As root:" + fi echo " $copy" - command -v notify-send >/dev/null 2>&1 && - notify-send -a udt "grub: theme rebuilt" "As root: -$copy" -else - echo "grub theme: run these as root to install it" - echo " $copy" -fi -grep -q "^GRUB_THEME=\"$theme/theme.txt\"" /etc/default/grub 2>/dev/null || { - echo " # once: GRUB_THEME=\"$theme/theme.txt\" in /etc/default/grub, then" - echo " grub-mkconfig -o /boot/grub/grub.cfg" + grep -q "^GRUB_THEME=\"$theme/theme.txt\"" /etc/default/grub 2>/dev/null || { + echo + echo "Once, set GRUB_THEME=\"$theme/theme.txt\" in /etc/default/grub, then:" + echo " grub-mkconfig -o /boot/grub/grub.cfg" + } + # The panel title falls back to the OS name until one is set. + [ -n "$("$repo/bin/udt-machine-name")" ] || { + echo + echo "Optional, the panel title:" + echo " \"$repo/bin/udt-machine-name\" \"My Machine\"" + } } -# The panel title falls back to the OS name until one is set. -[ -n "$("$repo/bin/udt-machine-name")" ] || - echo " # optional, the panel title: sudo \"$repo/bin/udt-machine-name\" \"My Machine\"" + +out="$(steps)" +echo "grub theme: ${out:-up to date}" +# A theme that was never installed stays out of the steps window: a wallpaper +# change would otherwise keep asking for an install nobody wanted. +if [ -d "$theme" ] || [ -z "$out" ]; then + printf '%s' "$out" | "$repo/bin/udt-steps" grub +fi exit 0 diff --git a/bin/udt-homepage b/bin/udt-homepage index 7be5d16..a814d16 100755 --- a/bin/udt-homepage +++ b/bin/udt-homepage @@ -4,13 +4,17 @@ # Licensed under the GNU General Public License v2 only. # # Staged, not installed: /opt/homepage is root-owned and this script does not -# hold root there, so it copies into ~/hp-stage/ and a notification carries -# the command that finishes the job. +# hold root there, so it copies into ~/hp-stage/ and the steps window +# (udt-steps) carries the commands that finish the job. # # udt-accent starts this detached on every run, which covers both a wallpaper # change (wallp) and a scheme switch (install.sh). Never slow and never loud # when the host is away: a laptop off that network gets a short connect -# timeout and no notification, since there is nothing for the user to do. +# timeout and no steps tab, since there is nothing for the user to do. +# +# udt-accent also runs for reasons that change neither file, an icon theme +# switch for one, so what was last staged is remembered and an identical pair +# is not staged again: the finish steps would reappear for nothing. repo="$(dirname "$(readlink -f "$0")")/.." css="$repo/templates/homepage/custom.css" @@ -31,6 +35,10 @@ case "$ext" in esac bg="background.$ext" +stamp="$HOME/.cache/udt/homepage.staged" +sum="$(cat "$css" "$real" | sha256sum)" +[ "$sum" = "$(cat "$stamp" 2>/dev/null)" ] && exit 0 + scp "${opts[@]}" "$css" homepage:hp-stage/custom.css && scp "${opts[@]}" "$real" "homepage:hp-stage/$bg" || { echo "homepage: unreachable, skipped" >&2 @@ -41,13 +49,14 @@ scp "${opts[@]}" "$css" homepage:hp-stage/custom.css && # is not the staging directory, so it is named through the ssh login user, # which ssh -G resolves from the config without connecting. stage="~$(ssh -G homepage 2>/dev/null | awk '/^user /{print $2}')/hp-stage" -finish="cp $stage/custom.css /opt/homepage/config/ -cp $stage/$bg /opt/homepage/public/images/ -sed -i 's|/images/background\.[a-z]*|/images/$bg|' /opt/homepage/config/settings.yaml -systemctl restart homepage" -echo "homepage: staged, finish as root on homepage:" -echo "$finish" -command -v notify-send >/dev/null 2>&1 && - notify-send -a udt "homepage: theme staged" "As root on homepage: -$finish" +echo "$sum" > "$stamp" +out="$( + echo "The homepage theme is staged in $stage. Finish as root on homepage:" + echo " cp $stage/custom.css /opt/homepage/config/" + echo " cp $stage/$bg /opt/homepage/public/images/" + echo " sed -i 's|/images/background\\.[a-z]*|/images/$bg|' /opt/homepage/config/settings.yaml" + echo " systemctl restart homepage" +)" +echo "$out" +printf '%s' "$out" | "$repo/bin/udt-steps" homepage exit 0 diff --git a/bin/udt-steps b/bin/udt-steps new file mode 100755 index 0000000..da4aca0 --- /dev/null +++ b/bin/udt-steps @@ -0,0 +1,36 @@ +#!/bin/bash +# udt-steps: hand a consumer's pending manual steps to the steps window. +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# Licensed under the GNU General Public License v2 only. +# +# Usage: <producer> | udt-steps NAME +# +# stdin becomes the NAME tab of quickshell's steps window, one file per +# consumer under ~/.cache/udt/steps/. Empty stdin clears the tab: a consumer +# that is up to date has nothing to ask for. Either way the running shell is +# poked over IPC, which reloads the tabs and opens the window when any remain. +# +# Format: a line indented two spaces is a command, and a run of them is one +# block with its own copy button. Everything else is prose. So the root +# commands producers already printed for a terminal read the same here. + +name="${1:?usage: udt-steps NAME}" +case "$name" in + *[!a-z0-9-]*) echo "udt-steps: bad name '$name'" >&2; exit 2 ;; +esac + +dir="$HOME/.cache/udt/steps" +mkdir -p "$dir" +text="$(cat)" +if [ -z "$text" ]; then + rm -f "$dir/$name" +else + # Atomic, so the shell never reads half a file. + printf '%s\n' "$text" > "$dir/.$name.tmp" && mv "$dir/.$name.tmp" "$dir/$name" +fi + +repo="$(dirname "$(readlink -f "$0")")/.." +qs_dir="$(realpath -m "$repo/../quickshell/appearance")" +[ -f "$qs_dir/shell.qml" ] && command -v qs >/dev/null 2>&1 && + timeout 5 qs -p "$qs_dir" ipc call appearance steps >/dev/null 2>&1 +exit 0 |
