aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 394ba292c18d1f99792145522d3ddc9c039214b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# wallp

A single-script wallpaper manager for a two-screen Wayland (sway / Hyprland)
setup. Sets and restores wallpapers per screen, refreshes the desktop accent
colour to match, 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 at login, falling back to
  configured defaults on first run.
- **Unified desktop theme** — after every change `wallp` hands the new wallpaper
  to `udt-accent`, which owns the whole palette (rofi, Hyprland, Firefox,
  quickshell, Sublime). `wallp` itself no longer runs pywal or stores a theme.
- **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  |
| `udt-accent`  | optional            | refreshes the desktop accent colour  |
| `qarma`       | only for GUI `--set`| screen-choice menu + file picker     |
| `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. `udt-accent` is looked up at run time: if it is
absent, or it fails, the wallpaper is still set and only the accent refresh is
skipped.

## Install

`wallp` is a standalone script — put it somewhere on your `PATH`:

```bash
ln -s "$PWD/wallp" ~/bin/wallp
```

A symlink keeps the installed command in step with the checkout, so edits take
effect at once. A plain `cp wallp ~/bin/wallp && chmod +x ~/bin/wallp` works too,
but then every repo edit needs a re-copy.

## 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

# 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 all required. A missing
  or empty one is a hard error (named in the message).

## Usage

```
wallp                      Show help
wallp --help | -h          Show help
wallp --set                Interactive selection (qarma): pick H / V / Both
wallp --set H=<file>       Set the horizontal screen only
wallp --set V=<file>       Set the vertical screen only
wallp --set H=<f> V=<f>    Set both screens
wallp --restore            Restore last session (defaults if none saved)
```

### 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
```

### 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               |
| `~/.cache/wallp/H.pid`        | PID of the horizontal `swaybg`                  |
| `~/.cache/wallp/V.pid`        | PID of the vertical `swaybg`                    |
| `~/.cache/udt/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 <output> -i <file> -m fill`), record the new PID,
and save the path. Then update the `~/.cache/udt/wpaper` symlink and run
`udt-accent ~/.cache/udt/wpaper` to re-derive the desktop accent colour.

Restoring: for each screen, use the saved path if present, otherwise the
configured default; apply it; then refresh the accent the same way.

The `wpaper` symlink is the hand-off point to the rest of the theme: other
tools (rofi, `udt-accent`) read it rather than `wallp`'s own state.

## 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`, `udt-accent`, `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.