Next: , Previous: , Up: API  


1.23 (heks-linux wallpaper)

The Heks Linux wallpaper engine: one generated shell script that owns the background, one Rofi picker that talks to it, and the systemd units that rotate it on a schedule.

The shape of this module is deliberate. The compositor starts the engine as a startup program, the timer runs it on a calendar, the keybindings run it by hand and the picker runs it with an explicit path - one entry point, so the renderer, the state file and the Wayland connection are solved once instead of in four places.

The three things the previous rotation script got wrong, and that this one gets right, are worth naming because they look like small details:

1. It guessed that the compositor was on wayland-0, wayland-1 or wayland-2, in a chain of or-ed commands that also hid every failure. The engine reads WAYLAND_DISPLAY and then looks for the socket in XDG_RUNTIME_DIR. 2. Its systemd service was Type=simple around a program that never exits, so the unit stayed active forever and the timer could never trigger it again - the wallpaper was set once per boot. The service is now a oneshot around an engine that returns, and the renderer is detached with setsid so KillMode=process leaves it alone. 3. It derived the image from the current second, so the comment that promised a wallpaper per day was describing nothing. The engine keeps the wallpaper it applied in a state file, rotates on a daily timer and never picks the image that is already on screen.

1.23.1 Parameters

Parameter: wallpaper-backend

Default value:

auto
Parameter: wallpaper-catalog-dir

Default value:

"/root/.config/digital-art-dreams"
Parameter: wallpaper-randomized-delay

Default value:

"5m"
Parameter: wallpaper-rotation-interval

Default value:

"1h30m"
Parameter: wallpaper-scaling

Default value:

"fill"
Parameter: wallpaper-script-dir

Default value:

"/root/.local/bin"
Parameter: wallpaper-script-filename

Default value:

"heks-wallpaper"
Parameter: wallpaper-service-filename

Default value:

"heks-wallpaper.service"
Parameter: wallpaper-state-dir

Default value:

"/root/.local/state/heks-linux"
Parameter: wallpaper-systemd-dir

Default value:

"/root/.config/systemd/user"
Parameter: wallpaper-timeout

Default value:

20
Parameter: wallpaper-timer-filename

Default value:

"heks-wallpaper.timer"

1.23.2 Procedures

Procedure: install-wallpaper-config

Write the wallpaper engine and the systemd user units.

Local overrides are read from $XDG_CONFIG_HOME/heks-linux/wallpaper-settings.scm first, so a machine can pin a renderer or a rotation schedule without touching the module.

The engine is installed executable; it is what the compositor, the timer, the keybindings and the gallery all run. There is no separate picker to install any more - the gallery page is the picker - and a Rofi wall left over from an older install is deleted rather than left behind.

Restart the timer with systemctl --user restart heks-wallpaper.timer after changing the wallpaper set or the schedule.

Procedure: mk-random-wall-cmd walls

Render the Heks Linux wallpaper engine as a POSIX shell script.

walls is the wallpaper set curated for the running palette: the engine treats it as its rotation, and all-list reaches the whole collection below wallpaper-catalog-dir for everything else.

The script is the one program that touches the background. It keeps what it applied in a state file so restore can put the same image back after the compositor restarts, it retries until a Wayland socket answers because the systemd unit can start before Niri is listening, and it detaches the renderer so it can return instead of blocking the unit that started it.

(display (mk-random-wall-cmd (wallpapers)))
Procedure: mk-random-wall-systemd-service script-path

Render the systemd user service that rotates the wallpaper.

script-path is the absolute path of the generated engine, because a user unit has no shell to resolve a home directory shorthand.

The unit is a oneshot on purpose. The previous version was Type=simple around a renderer that never exits, so the unit stayed active for the whole session, systemctl start became a no-op and the timer could never change the wallpaper again. Now the engine applies one image and returns, and KillMode=process keeps the detached renderer alive when it does - the default control-group would kill swaybg the moment the script exited.

Procedure: mk-random-wall-systemd-timer

Return the systemd user timer that triggers the wallpaper rotation.

The schedule is a monotonic interval rather than a calendar entry, because what this is asked for is "every ninety minutes" and a calendar cannot say that: its minute step has to divide an hour. OnActiveSec fires the first change ninety minutes after the timer starts and OnUnitActiveSec repeats it after each run, so the wallpaper turns over while the machine is being used.

There is no Persistent any more. It makes a calendar timer catch up on a boot it missed; a monotonic one has no moment to have missed, and asking for it would only suggest the timer survives being switched off.

Procedure: wallpaper-script-command

Return the engine as a shell word, ready to embed in a Niri binding.

The result is the engine path with the home directory written as a tilde, so the binding a dotfile carries is the same on every machine. Call it where a shell will expand the tilde, such as a Niri spawn-sh.

Procedure: wallpapers

Return active wallpaper absolute file paths based on the running theme palette.


Next: (heks-linux waybar), Previous: (heks-linux user-settings), Up: API