enBoxer/TASKS.md
en 9d2f51685d Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams
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
2026-09-15 17:18:37 +02:00

4.0 KiB
Raw Permalink Blame History

OpenCode tickets

Product: GOALS.md. Do not invent work. Do not hyprctl dispatch on the live session.

Safety (all tickets)

  • No hyprctl dispatch that 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 by allow_layout already; auto-apply on launch only fires after the Launch button is clicked).
  • Any live Wayland / overlay / export path remains feature-gated so cargo test does 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 --stat showing 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.

T1T6 hygiene and Video FX click/passthrough tests (see git log).