aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/superpowers/specs/2026-10-29-wallpaper-engine-design.md99
1 files changed, 99 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-10-29-wallpaper-engine-design.md b/docs/superpowers/specs/2026-10-29-wallpaper-engine-design.md
new file mode 100644
index 0000000..aac3b1c
--- /dev/null
+++ b/docs/superpowers/specs/2026-10-29-wallpaper-engine-design.md
@@ -0,0 +1,99 @@
+# Wallpaper engine: wallpapers on a timer
+
+Date: 2026-10-29
+
+## Goal
+
+Change the wallpapers on a timer, from a list per screen picked with a heart
+in the wallpaper picker. Timer changes recolour the live desktop but leave the
+boot and login surfaces alone; the user's own picks keep doing everything.
+
+## Lists
+
+One plain-text file per screen, one absolute path per line:
+`~/.config/keystone/wallpapers/h.list` (DP-1) and `v.list` (DP-3). There are no
+portrait images in the gallery, so a screen's list is the user's choice, not
+derived from aspect ratio. A path whose file is missing stays in the list and
+is skipped by the timer.
+
+## Heart
+
+Back on every thumbnail in `WallpaperTab.qml`, with the glyphs it had before
+the companion was removed: outline `\u{F02D5}` on hover, filled `\u{F02D1}` in
+`Theme.red` when listed. It reads and toggles the list of the screen the picker
+targets (`Wallpapers.target`, H or V). A toggle writes the file at once. It sits
+after the pick `MouseArea`, so it takes its own click.
+
+## Engine section
+
+A section on the existing Wallpaper page, not a new page:
+
+- an on/off switch;
+- the interval, in minutes;
+- the two lists with their counts, each entry removable, a missing file dimmed;
+- a Next button that ticks now.
+
+On/off, the interval and the two home wallpapers (below) live in `Prefs`, so
+they survive a restart. A running engine is running again after a restart.
+
+## Tick
+
+A `Timer` in the `Wallpapers` singleton, repeating at the interval while the
+engine is on.
+
+- Each screen with a non-empty list takes the next path from a shuffle bag:
+ the list shuffled, drawn without repeats until empty, then reshuffled, with
+ the path just shown never first in the new round. The bag is not persisted;
+ a restart reshuffles.
+- Both screens go in one `wallp --set` call, through the same path as Apply,
+ so the burn transition plays. A screen with an empty list is left alone.
+- A tick while a `wallp` run is in progress is skipped.
+- A tick does not touch staged picks (`pendingH`, `pendingV`).
+- The call runs with `UDT_ROTATION=1` in its environment (light run, below).
+
+## Manual picks and the home wallpaper
+
+A manual Apply is always the full run, engine on or off.
+
+Each screen has a home wallpaper, kept in `Prefs`:
+
+- switching the engine on sets each home to what that screen shows;
+- a manual Apply while the engine is on sets the home of each screen it
+ applied, and restarts the timer, so the pick stays up a full interval;
+- switching the engine off sets each screen whose current wallpaper differs
+ from its home back to the home, in one full `wallp --set`. Both equal, or a
+ home whose file is gone, changes nothing.
+
+The shuffle continues where it was after a manual pick.
+
+## Light run: udt-accent
+
+In `unified-desktop-theme/bin/udt-accent`: with `UDT_ROTATION` set and
+non-empty, skip `write_grub`, `write_homepage` and `write_sddm`, and do not
+start the `udt-grub` and `udt-homepage` helpers. Everything else runs: the
+accent, Hyprland borders, hyprlock, QML palette, Sublime, colors.json,
+Firefox, conky, and the keyboard, LED strip, bulb and TV helpers. `wallp` needs
+no change: it runs `udt-accent` as a child, which inherits the variable.
+
+## Conky, separately
+
+Conky reloads `conky.conf` in place on an accent change, recreating its window,
+and the `dash-workspace` rule in hypr-theme's `sections/dashboard.lua` then
+sends the new window to `special:dash` without `silent`, which shows the
+special workspace. The rule becomes `workspace = WS .. " silent"`. To be
+confirmed by eye on the next accent change.
+
+## Checks
+
+- A runnable check for the shuffle bag, in a `.js` file beside it: no repeat
+ within a round, a refill after the last, and the last path never first in
+ the next round (a one-item list excepted).
+- A check in `udt-accent`'s selftest that the three writes and two helpers are
+ skipped with `UDT_ROTATION=1`, against temporary paths.
+- By eye: heart, engine section, a tick with the burn, switching off returning
+ home, conky staying hidden.
+
+## Out of scope
+
+Sequential order, per-screen intervals, persisting the shuffle, rotation from
+a terminal `wallp` without the desktop shell.