doc: Add project design, dev plan, coding standards, and use cases.

This commit is contained in:
2026-03-13 21:47:37 -04:00
parent 24f6635927
commit b4129eaeaf
5 changed files with 1364 additions and 0 deletions

View File

@@ -0,0 +1,145 @@
# 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.