diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-29 13:08:06 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-29 13:08:06 +0100 |
| commit | 66f8c77b853bb67166aac8ca9c3b31abe6468426 (patch) | |
| tree | 670dcce6dc7e3627320fde57784c36f58dc8ec4c /bin | |
| parent | 55d00cc44fcb3ae89d3ad27a236fa30f167d80a2 (diff) | |
| download | unified-desktop-theme-66f8c77b853bb67166aac8ca9c3b31abe6468426.tar.gz unified-desktop-theme-66f8c77b853bb67166aac8ca9c3b31abe6468426.zip | |
accent: UDT_ROTATION, a light run for timed wallpaper changes
The wallpaper engine changes wallpapers on a timer and runs wallp, which
runs udt-accent. Nobody sees GRUB, the homepage or SDDM mid-session, and
GRUB costs a rebuild and the homepage an scp on every change. With
UDT_ROTATION set and non-empty, write_sddm, write_grub, write_homepage
and the udt-grub and udt-homepage helpers are skipped; everything else
still runs. A manual change is a full run and brings them level.
The selftest swaps every writer and both subprocess calls for recorders
and checks the exact set of calls with the variable empty and set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/udt-accent | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/bin/udt-accent b/bin/udt-accent index aabbdec..cfca6ac 100755 --- a/bin/udt-accent +++ b/bin/udt-accent @@ -9,6 +9,9 @@ Usage: udt-accent [--no-helpers] <wallpaper-path> udt-accent --selftest udt-accent --help +With UDT_ROTATION set and non-empty (keystone's wallpaper engine), GRUB, the +homepage and SDDM are left alone, and udt-grub and udt-homepage do not start. + The extraction reads the image's pixels itself rather than running `wal -i`, because `wal -i` rewrites the whole ~/.cache/wal directory (which this no longer writes to, but pywal still would) including the terminal's ANSI colors. @@ -624,7 +627,15 @@ def write_sddm(name, image): mode=0o644, dir_mode=0o755) +# Set by keystone's wallpaper engine on its timer changes. They recolour the +# live desktop and leave the boot and login surfaces alone: nobody sees GRUB, +# the homepage or SDDM mid-session, and GRUB costs a rebuild and the homepage +# an scp on every change. A manual change is a full run and brings them level. +LIGHT_SKIPS_HELPERS = ("udt-homepage", "udt-grub") + + def main(image, helpers=True): + light = bool(os.environ.get("UDT_ROTATION")) try: color = signature_color(image) name = snap(color) if color else FALLBACK @@ -638,12 +649,14 @@ def main(image, helpers=True): write_hyprlock_border(name) write_qml(name) write_sublime(name) - write_sddm(name, image) + if not light: + write_sddm(name, image) write_colors_json(name, image) write_firefox(image) # Before the helpers below start, which build and stage these two. - write_grub(name) - write_homepage(name) + if not light: + write_grub(name) + write_homepage(name) write_conky(name) # Hyprland only rereads its config on request, and may not be running. @@ -659,6 +672,8 @@ def main(image, helpers=True): # udt-tv is a single UDP datagram to the TV launcher. # --no-helpers is install.sh's: it runs each of them as a consumer itself. for helper in ("udt-homepage", "udt-grub", "udt-keyboard", "udt-ledstrip", "udt-bulb", "udt-tv") if helpers else (): + if light and helper in LIGHT_SKIPS_HELPERS: + continue subprocess.Popen([Path(__file__).resolve().parent / helper], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True) @@ -913,6 +928,48 @@ def selftest(): finally: os.environ["HOME"] = home + # UDT_ROTATION is the wallpaper engine's light run: GRUB, the homepage and + # SDDM and their helpers are skipped, everything else still runs. Every + # writer and both process calls are swapped for recorders, so nothing on + # disk is touched and no helper starts. + every = ("write_accent", "write_border", "write_hyprlock_border", + "write_qml", "write_sublime", "write_sddm", "write_colors_json", + "write_firefox", "write_grub", "write_homepage", "write_conky") + helpers = {"udt-homepage", "udt-grub", "udt-keyboard", "udt-ledstrip", + "udt-bulb", "udt-tv"} + calls = [] + + class FakeSubprocess: + DEVNULL = None + + @staticmethod + def run(*a, **k): + pass + + @staticmethod + def Popen(cmd, **k): + calls.append(Path(cmd[0]).name) + + saved, saved_env = dict(globals()), os.environ.get("UDT_ROTATION") + try: + for fn in every: + globals()[fn] = (lambda n: lambda *a: calls.append(n))(fn) + globals()["signature_color"] = lambda image: None + globals()["subprocess"] = FakeSubprocess + skipped = {"write_sddm", "write_grub", "write_homepage", + "udt-grub", "udt-homepage"} + for env, want in (("", set(every) | helpers), + ("1", (set(every) | helpers) - skipped)): + calls.clear() + os.environ["UDT_ROTATION"] = env + main("unused.png") + assert set(calls) == want, (env, sorted(set(calls) ^ want)) + finally: + globals().update(saved) + if saved_env is None: + os.environ.pop("UDT_ROTATION", None) + else: + os.environ["UDT_ROTATION"] = saved_env print("selftest OK") |
