7874a5f7c6
Add configurable key bindings (TOML), modifier-aware dispatch, mouse-driven pattern placement with preview and rotation, cell grid storage/rendering, and fractional/integer HiDPI scaling. Archive the input-and-placement change and sync its specs to main specs. Tests: Hashtable, Config, Grid, Pattern (4/4 pass).
80 lines
4.5 KiB
Markdown
80 lines
4.5 KiB
Markdown
# Design
|
|
|
|
## Context
|
|
|
|
Current application (`wlgol.c`) renders an animated stripe pattern into a fixed 400x400 shm buffer, handles only Escape, and ignores configure size and output scale. Input modules (`tkeyboard`, `tpointer`) exist but pointer motion/buttons are unimplemented and keyboard callbacks do not carry modifiers. HiDPI is unsupported. See `proposal.md` for motivation.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
- Configurable, modifier-aware key bindings with TOML merge over defaults.
|
|
- Interactive pattern placement with preview, rotation, click placement, cancellation.
|
|
- HiDPI-correct rendering (fractional and integer).
|
|
- Cell grid storage/rendering with resize preservation and wall boundaries.
|
|
|
|
**Non-Goals:**
|
|
- Game of Life simulation rules (future change).
|
|
- Text rendering/HUD (status via stdout).
|
|
- Persistent grid save/load.
|
|
- Fractional scaling on compositors lacking the protocol beyond integer fallback.
|
|
|
|
## Decisions
|
|
|
|
### D1: TOML config via vendored `tomlc99`
|
|
- **Choice:** Vendor `tomlc99` (single .c/.h) for parsing `~/.config/wlgol/keys.conf`.
|
|
- **Rationale:** User requested TOML; no system TOML library available; vendoring avoids new system dependency.
|
|
- **Alternative:** Hand-rolled subset parser (less code, but TOML edge cases and maintenance burden).
|
|
|
|
### D2: Binding representation
|
|
- **Choice:** Store bindings as array of `{mods_mask, keysym, action}`. Lookup by exact modifier mask (ignoring lock mods) and keysym on key press.
|
|
- **Rationale:** Simple, fast enough for single-threaded event loop.
|
|
- **Alternative:** Hash table keyed by (mods, keysym) — premature; linear scan over ~20 bindings is trivial.
|
|
|
|
### D3: Keyboard callback carries modifiers
|
|
- **Choice:** Extend `keyboard_key_handler_t` to `(..., uint32_t mods, void *user_data)`, computed in `tkeyboard.c` from xkb state.
|
|
- **Rationale:** Binding matching needs modifier state; centralizes xkb modifier queries.
|
|
|
|
### D4: HiDPI via fractional scale + viewporter
|
|
- **Choice:** Prefer `wp_fractional_scale_v1`; render physical buffer = ceil(logical * scale); set buffer_scale=1 and `wp_viewport` destination = logical size. Fallback to `wl_output.scale` integer (treat as scale value).
|
|
- **Rationale:** Exact fractional scaling; unifies rendering path through viewporter.
|
|
- **Alternative:** Integer-only scaling (simpler but blurry/wrong at 125%/150%).
|
|
|
|
### D5: Logical canvas and grid
|
|
- **Choice:** Logical surface size from xdg configure (default 400x400). Grid dimensions = logical / 8. Cell size in logical pixels fixed at 8.
|
|
- **Rationale:** Consistent interaction across scales; HiDPI keeps physical cell size proportional.
|
|
|
|
### D6: Grid storage and resize
|
|
- **Choice:** `struct grid { int cols, rows; unsigned char *cells; }` (0/1). On resize, allocate new buffer, copy overlapping region, free old.
|
|
- **Rationale:** Preserves user work on window resize; simple.
|
|
|
|
### D7: Pattern definitions and rotation
|
|
- **Choice:** Each pattern stores base cell offsets and a rotation (0..3). Transform offsets at use time; bounding box computed from transformed offsets. Anchor = top-left of bounding box at cursor cell.
|
|
- **Rationale:** Avoids duplicating 4 variants per pattern; rotation stays consistent.
|
|
|
|
### D8: Placement state machine
|
|
- **Choice:** States `IDLE` and `ARMED`. Key select → ARMED; motion updates preview cell; rotate increments rotation; left click places if in-bounds (stays ARMED); Escape → IDLE.
|
|
- **Rationale:** Matches requested UX; tool remains active for repeated placement.
|
|
|
|
### D9: Protocols generation
|
|
- **Choice:** Vendor/copy `viewporter.xml` and `fractional-scale-v1.xml` into repo (from system wayland-protocols) and generate headers/sources via wayland-scanner in CMake, mirroring xdg-shell.
|
|
- **Rationale:** Reproducible builds without depending on system protocol paths.
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- [Fractional scaling complexity] → Mitigation: isolate in `scale.c`; integer fallback ensures basic functionality.
|
|
- [Resize resets grid partially] → Mitigation: preserve overlapping region; document behavior.
|
|
- [tomlc99 vendoring licensing] → Mitigation: verify license (MIT) before commit.
|
|
- [No font rendering] → Status via stdout; acceptable for this change.
|
|
- [Placement near edges] → Mitigation: reject invalid placement; preview indicates invalid state (e.g., red tint).
|
|
|
|
## Migration Plan
|
|
|
|
1. Add generated protocol files and CMake changes.
|
|
2. Vendor tomlc99.
|
|
3. Implement modules and integrate into wlgol.c.
|
|
4. Update tests (hashtable unchanged; add config/grid unit tests if feasible).
|
|
5. Run ctest and build.
|
|
|
|
## Open Questions
|
|
|
|
None — all blocking decisions resolved during exploration. |