146 lines
4.1 KiB
Markdown
146 lines
4.1 KiB
Markdown
# Use Case: Wallpaper Picker
|
|
|
|
A keyboard-driven wallpaper picker for Hyprland that
|
|
previews wallpapers live on the desktop as you browse.
|
|
This is a first-class use case for pikl-menu: it
|
|
exercises structured I/O, lifecycle hooks, debouncing,
|
|
and the GUI overlay.
|
|
|
|
## What It Looks Like
|
|
|
|
1. User presses a keybind. pikl opens as a layer-shell
|
|
overlay on the focused monitor.
|
|
2. A list of wallpapers appears, filterable by typing.
|
|
3. Navigating the list applies each wallpaper live to
|
|
the desktop behind the overlay (via hyprpaper IPC).
|
|
4. Enter confirms. The wallpaper stays, overlay closes.
|
|
5. Escape cancels. The wallpaper reverts to whatever
|
|
was set before the picker opened.
|
|
|
|
The overlay is semi-transparent so the user sees the
|
|
real wallpaper behind it. No preview pane needed.
|
|
|
|
## How It Works With pikl
|
|
|
|
The wallpaper picker is not a standalone app. It is a
|
|
shell script (or a small wrapper) that pipes items into
|
|
pikl and uses hooks for the live preview behaviour.
|
|
|
|
### Basic Version
|
|
|
|
```sh
|
|
# List wallpapers as JSON, pipe to pikl with hooks
|
|
find ~/Pictures/walls -type f \
|
|
-name '*.jpg' -o -name '*.png' -o -name '*.webp' \
|
|
| jq -Rc '{label: (. | split("/") | last),
|
|
sublabel: (. | split("/") | .[:-1]
|
|
| join("/")), meta: {path: .}}' \
|
|
| pikl --mode gui \
|
|
--on-open 'hyprctl hyprpaper listactive
|
|
| head -1 > /tmp/pikl-wall-orig' \
|
|
--on-hover 'jq -r .meta.path
|
|
| xargs -I{} hyprctl hyprpaper
|
|
wallpaper "DP-4, {}"' \
|
|
--on-cancel 'cat /tmp/pikl-wall-orig
|
|
| cut -d: -f2 | xargs -I{}
|
|
hyprctl hyprpaper wallpaper "DP-4, {}"' \
|
|
--on-hover-debounce 100
|
|
```
|
|
|
|
### With a Manifest
|
|
|
|
For a reusable setup, use a pikl manifest file:
|
|
|
|
```toml
|
|
# ~/.config/pikl/wallpaper.toml
|
|
|
|
[hooks]
|
|
on-open = "save-current-wallpaper.sh"
|
|
on-hover = '''
|
|
jq -r .meta.path \
|
|
| xargs -I{} hyprctl hyprpaper \
|
|
wallpaper "DP-4, {}"
|
|
'''
|
|
on-cancel = "restore-wallpaper.sh"
|
|
on-hover-debounce = 100
|
|
|
|
[display]
|
|
format = "{label} <dim>{sublabel}</dim>"
|
|
```
|
|
|
|
```sh
|
|
find ~/Pictures/walls -type f \( \
|
|
-name '*.jpg' -o -name '*.png' \) \
|
|
| to-json-items \
|
|
| pikl --manifest ~/.config/pikl/wallpaper.toml \
|
|
--mode gui
|
|
```
|
|
|
|
### Modes
|
|
|
|
Different invocations cover different workflows:
|
|
|
|
**Browse:** open the picker, filter and select.
|
|
|
|
```sh
|
|
find ~/Pictures/walls -type f ... | pikl ...
|
|
```
|
|
|
|
**History:** pipe wallpaper history instead of a
|
|
directory scan. Same hooks, different input source.
|
|
|
|
```sh
|
|
cat ~/.local/state/wallpaper-history.jsonl \
|
|
| pikl --manifest ~/.config/pikl/wallpaper.toml \
|
|
--mode gui
|
|
```
|
|
|
|
**Random:** no pikl needed, just a shell one-liner.
|
|
|
|
```sh
|
|
find ~/Pictures/walls -type f ... \
|
|
| shuf -n1 \
|
|
| xargs -I{} hyprctl hyprpaper wallpaper "DP-4, {}"
|
|
```
|
|
|
|
**Restore:** read the last state file, apply it.
|
|
Also just a shell script, no pikl.
|
|
|
|
### Hyprland Keybindings
|
|
|
|
```
|
|
bind = $mod CTRL, B, exec, wallpicker browse
|
|
bind = $mod SHIFT, B, exec, wallpicker random
|
|
bind = $mod, B, exec, wallpicker copy
|
|
```
|
|
|
|
## What pikl Features This Exercises
|
|
|
|
| Feature | Phase | How It's Used |
|
|
|---|---|---|
|
|
| GUI overlay | 8 | Layer-shell on Wayland |
|
|
| Structured I/O | 3 | JSON items with metadata |
|
|
| on-hover hook | 3 | Live wallpaper preview |
|
|
| on-open hook | 3 | Save current wallpaper |
|
|
| on-cancel hook | 3 | Revert wallpaper |
|
|
| Hook debouncing | 3 | Don't flood hyprctl |
|
|
| Fuzzy filtering | 2 | Filter by filename |
|
|
| Manifest files | 3 | Reusable config |
|
|
| Watched sources | 7 | Live update on new files |
|
|
| Sessions | 6 | Remember last position |
|
|
|
|
## Open Questions
|
|
|
|
- Should pikl support image thumbnails in the item
|
|
list? Useful here but adds complexity. Could be a
|
|
GUI-only feature using the icon field.
|
|
- Debounce timing: 100ms feels right for hyprctl IPC.
|
|
Might need tuning for slower wallpaper daemons.
|
|
- Multi-monitor: the on-hover hook needs to know which
|
|
monitor to target. Could come from a CLI flag or
|
|
from hyprctl's focused monitor.
|
|
- History management: pikl sessions handle state, but
|
|
wallpaper history (which wallpapers were set when)
|
|
is the wrapper script's responsibility. Keep it
|
|
simple: append to a JSONL file.
|