Files
pikl/docs/use-cases/wallpaper-picker.md

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

  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

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