4.1 KiB
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
- User presses a keybind. pikl opens as a layer-shell overlay on the focused monitor.
- A list of wallpapers appears, filterable by typing.
- Navigating the list applies each wallpaper live to the desktop behind the overlay (via hyprpaper IPC).
- Enter confirms. The wallpaper stays, overlay closes.
- 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
# 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:
# ~/.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>"
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.
find ~/Pictures/walls -type f ... | pikl ...
History: pipe wallpaper history instead of a directory scan. Same hooks, different input source.
cat ~/.local/state/wallpaper-history.jsonl \
| pikl --manifest ~/.config/pikl/wallpaper.toml \
--mode gui
Random: no pikl needed, just a shell one-liner.
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.