diff options
| -rw-r--r-- | docs/superpowers/specs/2026-10-29-wallpaper-engine-design.md | 99 |
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. |
