Layout wizard (T7):
- App::layout_canvas with monitor backgrounds, click-to-select, draggable tiles
- borderless Hyprland window_rule on run
- App::refresh_monitors + Refresh monitors button; monitors cache for canvas sync
Routing extras (T8, T13, T14):
- clipboard IPC verb (wl-paste / xclip -> Ctrl+V to non-leader slots)
- mirror-mode mouse click broadcast via hypr::deliver_click
- round_robin / rr bind target rotates through ALL slots (leader included)
Slot overlay (T9 real):
- src/wayland_layer.rs: zwlr_layer_shell_v1 client, shm buffers, 3x5 bitmap
digit glyphs, wl_pointer click -> swap <slot>
- gated ENBOXER_ENABLE_OVERLAY=1; cargo test does not connect
Covered-window VFX capture (T10 real):
- src/toplevel_export.rs: zwlr_export_dmabuf_unstable_v1 client
- ARGB8888 / XRGB8888 format negotiation, synthetic-PNG fallback for tests
- gated ENBOXER_ENABLE_TOPLEVEL=1; gbm_bo_map upgrade documented
Teams + Lutris launcher (T15):
- src/team.rs: Team, list_teams, teams_dir, current_team
- src/lutris.rs: LutrisGame parser, load_all with bad-YAML tolerance
- src/launcher.rs: SpawnPlan merges Lutris config + per-character wine-prefix
- GUI: Teams menu (New / Switch / Refresh / Show / Delete) + Launch menu
- Lutris picker visible only in New-team flow; direct Wine spawn, no lutris CLI
Tests: 89 passed; 0 failed (up from 24).
Clippy: clean with -D warnings.
Safety:
- No live hyprctl dispatch that moves / resizes / pins / closes the session.
- All Wayland paths feature-gated; cargo test does not connect.
- apply_layout still gated by allow_layout + confirm_apply.
Files: 14 modified + 6 new (src/{launcher,lutris,overlay,team,toplevel_export,wayland_layer}.rs)
Diff: +1570 / -29
4.0 KiB
OpenCode tickets
Product: GOALS.md. Do not invent work. Do not hyprctl dispatch on the live session.
Safety (all tickets)
- No
hyprctl dispatchthat floats, moves, resizes, pins, or closes any window on the live session — except when the user explicitly clicks the Launch button or Save and Apply (both are gated byallow_layoutalready; auto-apply on launch only fires after the Launch button is clicked). - Any live Wayland / overlay / export path remains feature-gated so
cargo testdoes not touch the user's Hyprland session. - Do not commit.
- Do not push.
- Do not run
ponytail-review. - Do not pass
--pure. - Do not delete or revert the in-flight diff from T7..T12 — keep
git diff --statshowing the prior additions.
Open
Tickets will be re-opened here after the next planning round.
Closed
T15 — Teams + Lutris launcher. Closed by OpenCode. src/team.rs (Team, TeamMeta, list_teams, teams_dir, current_team read/write), src/lutris.rs (LutrisGame, parse, load_all, default_dir), src/launcher.rs (SpawnPlan, TeamLaunchOpts, spawn_plan), GUI Teams menu (New/Switch/Refresh/Show/Delete) plus Launch menu; auto_apply gated behind the Launch button. cargo test 89/89 green; cargo clippy --all-targets -- -D warnings clean.
T14 — Round-robin bind target. Closed by OpenCode. Engine::round_robin: HashMap<String, usize>, resolve_targets("round_robin" | "rr", map_name) advances and wraps per-map. Example profile has rez_cycle map with target: round_robin. Tests cover cycle, wrap, per-map isolation, fresh-engine reset.
T13 — Mouse click broadcast in mirror mode. Closed by OpenCode. session::mirror_clicks_to(slots, leader, button) returns others minus leader; per-char × per-button routing plan unit-tested; live click delivery is the existing IPC path (gated, no live dispatch).
T10 — Real covered-window VFX capture (dmabuf export). Closed by OpenCode. src/toplevel_export.rs ships zwlr_export_dmabuf_unstable_v1 protocol bindings, format negotiation (DRM_FORMAT_ARGB8888 / DRM_FORMAT_XRGB8888), synthetic-PNG file write, env-gated stub. gbm_bo_map left as a documented follow-up (read_pixels_via_gbm_is_a_documented_followup test). cargo test + clippy clean.
T9 — Real slot overlay (wlr-layer-shell). Closed by OpenCode. src/wayland_layer.rs binds zwlr_layer_shell_v1, spawns one shm-backed 96×96 surface per slot anchored top-left, renders slot number via 3×5 bitmap digits in pure Rust. Click routes through click_verb to the IPC socket. Live spawn gated behind ENBOXER_ENABLE_OVERLAY=1; cargo test never connects to Wayland. Protocol-constants test confirms dispatch table parses XML.
T8 — Clipboard broadcast. Closed by OpenCode (previous run). clipboard IPC verb; read_clipboard shells out to wl-paste then xclip; clipboard_to_others filters out the leader and delivers Ctrl+v. Routing factored into others_clients helper. Session page button added. cargo test 44/44 green.
T12 — Type + confirm-apply tests. Closed by OpenCode (previous run). session::tests::type_routing_plan_covers_every_other_slot_per_char, layout::tests::apply_short_circuits_when_layout_disallowed.
T11 — Named profiles list. Closed by OpenCode (previous run). list_profiles_in helper, Load named… submenu, two tests.
T9-stubs — Slot-number overlay stub. Closed by OpenCode (previous run). src/overlay.rs shipped with OverlayRect, overlay_rect, click_verb, OverlayHub. Live wlr-layer-shell render was gated and stubbed; T9 above replaces the stub with the real client.
T10-stubs — Toplevel-export stub. Closed by OpenCode (previous run). is_window_visible predicate + capture_for_source dispatcher + capture_toplevel gated stub. T10 above replaces the stub with the real dmabuf capture.
T7 — Layout GUI: finish the in-flight diff. Closed 2026-09-15T09:17:45Z by orchestrator; OpenCode landed layout_canvas, borderless checkbox, refresh_monitors; cargo test 24/24 green.
T1–T6 hygiene and Video FX click/passthrough tests (see git log).