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