# wallp A single-script wallpaper manager for a two-screen Wayland (sway / Hyprland) setup. Sets and restores wallpapers per screen, drives a [pywal](https://github.com/dylanaraps/pywal) color theme, and remembers what you had across reboots. It replaces two older scripts — an interactive setter and a session restorer — with one flag-driven program. ## Features - **Two independent screens** — a horizontal (`H`) and a vertical (`V`) output, mapped to physical connectors in config. - **Partial updates** — change one screen without disturbing the other. Each screen's `swaybg` process is tracked by PID and only the changed one is restarted (no full-screen blank flash). - **GUI or CLI** — pick wallpapers through a [qarma](https://github.com/luebking/qarma) dialog, or pass file paths as arguments for scripted/headless use. - **Session restore** — re-applies the last wallpapers (and last theme) at login, falling back to configured defaults on first run. - **Theme persistence** — the last theme sticks until you change it; `--restore` brings it back, not the config default. - **Self-bootstrapping config** — first run writes a template config and tells you to fill it in, without touching your wallpapers. ## Requirements | Tool | Required | Purpose | |---------------|---------------------|--------------------------------------| | `bash` | yes (≥ 4.4) | the script itself | | `swaybg` | yes | paints the wallpaper on each output | | `wal` (pywal) | yes | generates/applies the color theme | | `qarma` | only for GUI `--set`| screen-choice menu + file picker | | `notify-send` | optional | desktop notification on theme change | | `bats` | dev only | running the test suite | `wallp` checks for the required binaries at startup and exits with a clear message if one is missing. ## Install `wallp` is a standalone script — put it somewhere on your `PATH`: ```bash cp wallp ~/bin/wallp chmod +x ~/bin/wallp ``` > **Note:** this is a plain copy. If you later edit the script in the repo, > re-copy it to `~/bin` for the change to take effect. ## Configuration Config lives at `~/.config/wallp/wallp.conf`. On the very first run, if it doesn't exist, `wallp` writes a template there and exits **without changing any wallpaper** — edit it, then run again. ```ini # ~/.config/wallp/wallp.conf # Optional. Defaults to sexy-splurge if omitted. THEME=sexy-splurge # Physical output names. Find yours with: # swaymsg -t get_outputs (sway) # hyprctl monitors (Hyprland) # wlr-randr OUTPUT_H=DP-1 OUTPUT_V=DP-3 # Used by --restore when there is no saved wallpaper yet. # A leading ~ is expanded to your home directory. DEFAULT_H=~/Pictures/wallpapers/SFW/horizontal.png DEFAULT_V=~/Pictures/wallpapers/SFW/vertical.png ``` Format notes: - Plain `key=value`, one per line. Blank lines and `#` comments are ignored. - The file is **not** sourced as shell — it's parsed manually, so it can't run code. - `OUTPUT_H`, `OUTPUT_V`, `DEFAULT_H`, `DEFAULT_V` are required. A missing or empty one is a hard error (named in the message). `THEME` is optional. ## Usage ``` wallp Show help wallp --help | -h Show help wallp --set Interactive selection (qarma): pick H / V / Both wallp --set H= Set the horizontal screen only wallp --set V= Set the vertical screen only wallp --set H= V= Set both screens wallp --restore Restore last session (defaults if none saved) wallp --theme Override the theme (combine with --set or --restore) ``` ### Examples ```bash # Interactive: a menu asks which screen, then a file picker opens. wallp --set # Change only the vertical monitor; the horizontal one is untouched. wallp --set V=~/Pictures/wallpapers/portrait.png # Set both at once. wallp --set H=~/pics/wide.jpg V=~/pics/tall.jpg # Restore on login (defaults on first ever run). wallp --restore # Set a wallpaper and switch theme in one go; the theme persists afterwards. wallp --set H=~/pics/wide.jpg --theme gruvbox ``` ### Theme precedence When resolving which theme to apply, `wallp` uses, in order: 1. `--theme ` on the command line, 2. the last persisted theme (`~/.config/wallp/theme`), 3. `THEME` from the config, 4. the built-in default `sexy-splurge`. The resolved theme is always saved, so it carries across `--restore`. ### GUI vs CLI `qarma` is used **only** to draw windows — the screen-choice menu, the file picker, dialogs, and the help screen when a display is present. The actual wallpaper is always set by `swaybg`, so the `H=`/`V=` argument forms work fine without any display (e.g. from a startup script). `--restore` never needs a display. If you run `wallp --set` with no arguments and no Wayland display is available, it errors and asks you to pass `H=`/`V=` instead. ## How it works State is owned entirely by `wallp`: | Path | Role | |-------------------------------|-------------------------------------------------| | `~/.config/wallp/wallp.conf` | configuration | | `~/.config/wallp/wall_h` | persisted horizontal wallpaper path | | `~/.config/wallp/wall_v` | persisted vertical wallpaper path | | `~/.config/wallp/theme` | persisted theme name | | `~/.cache/wallp/H.pid` | PID of the horizontal `swaybg` | | `~/.cache/wallp/V.pid` | PID of the vertical `swaybg` | | `~/.cache/wal/wpaper` | symlink to the current horizontal image | Setting a screen: validate the file, kill **only** that screen's old `swaybg`, launch a new one (`swaybg -o -i -m fill`), record the new PID, and save the path. Then update the `wpaper` symlink and apply the theme via `wal --backend colorz -nq --theme -o ~/bin/wal.sh`. Restoring: for each screen, use the saved path if present, otherwise the configured default; apply it; then re-apply the resolved (persisted) theme. The `~/.cache/wal/wpaper` symlink is kept because other tools (e.g. rofi themes) read it. ## Integration with sway / Hyprland Bind the interactive setter to a key and run a restore at startup. For Hyprland: ```ini # autostart exec-once = wallp --restore # keybind bind = $mainMod, Return, exec, wallp --set ``` (For sway, use `exec` / `bindsym` equivalents.) ## Development The whole program is the single `wallp` file; functions are small and isolated so they can be unit-tested. Tests use [bats](https://github.com/bats-core/bats-core): ```bash bats tests/wallp.bats ``` The suite stubs `swaybg`, `wal`, `qarma`, and `notify-send` on `PATH` and runs against a temporary `$HOME`, so it touches nothing real. Contributions should follow TDD — add a failing test first. Design notes and the implementation plan live under `docs/superpowers/`. ## License Personal tooling; use as you like.