Commit Graph

5 Commits

Author SHA1 Message Date
en
0ec7957224 Sweep: drop remaining T10/stub/follow-up markers
The T14 audit found more places where comments and docs claimed
T10 was a stub or follow-up after the gbm_bo_map work landed:

- src/vfx.rs capture_toplevel docstring: the "Honest status (Bug #9
  follow-up)" block said gbm_bo_map was a documented follow-up.
  Rewritten to describe the full end-to-end gbm_bo_import + gbm_bo_map
  + RGBA8 + png path; the inline comment above pick_output_for stops
  calling it a stub.

- src/toplevel_export.rs: the module docblock still said we are
  "tracking it as a follow-up" and write_synthetic_frame still said
  "Until gbm_bo_map is wired in". Rewritten as the documented
  fallback path. capture_via_export footer updated. Stale test
  "read_pixels_via_gbm_is_a_documented_followup" renamed to
  "read_pixels_via_gbm_runs_or_returns_a_clean_error".

- src/overlay.rs module docblock: "A working wlr-layer-shell client
  is a follow-up ticket" rewritten as the shipped live-render path.

- README.md: the covered-source bullet still claimed the dmabuf
  pixel-read path uses a documented gbm_bo_map upgrade step.
  Rewritten to point at the shipped runtime dlopen path
  (commit 0ba3c59).

cargo test 99+/0; clippy clean.
2026-09-16 17:16:16 +02:00
en
777256daab Drop stale T10 follow-up note in toplevel_export.rs
The T10 follow-up block (lines 561-575) said gbm_bo_map was a
documented follow-up. T10 is shipped (commit 0ba3c59, real pixel
read via runtime dlopen of libgbm.so.1); this comment block is now
stale and misleading.

Also fix the misleading "Public stub: where the gbm_bo_map read
belongs" docstring on read_pixels_via_gbm -- the function delegates
to the real implementation now, not a stub.

cargo test 98+/0; clippy clean.
2026-09-16 12:43:33 +02:00
en
0ba3c59cc1 T10: real pixel read via runtime dlopen of libgbm.so.1 (Bug #9 closed)
Bug #9 follow-up: the gated capture_via_export path used to write
a synthetic PNG because gbm_bo_map was not wired. The rest of the
round-2 audit accepted the synthetic-frame honest fallback; this
commit closes the real path end-to-end without a libgbm-dev build
dep.

Implementation:

- src/gbm_runtime.rs (new): runtime dlopen wrapper for libgbm.so.1
  via libc::dlopen + libc::dlsym. Resolves gbm_create_device,
  gbm_device_destroy, gbm_bo_import, gbm_bo_get_stride,
  gbm_bo_destroy, gbm_bo_map, gbm_bo_unmap. Stores raw fn pointers
  as usize and transmutes at call time. No lifetime gymnastics,
  no Symbol<_> vs os::unix::Symbol<_> confusion.

- src/toplevel_export.rs:
  * DmabufPlane.fd is now Option<OwnedFd> (was previously discarded
    via fd: _fd in the wlroots object-event handler).
  * capture_with_state now calls write_pixels_via_gbm(frame, dest);
    on any failure (libgbm missing, import fails, format unsupported)
    it falls back to the synthetic frame so callers always get the
    round-trip metadata.
  * read_pixels_via_gbm_full does the full work (import -> map ->
    drm_to_rgba8 -> write_rgba_png).
  * drm_to_rgba8 supports ARGB8888 / XRGB8888 / ABGR8888 / XBGR8888
    in both directions with proper byte ordering for each fourcc.
  * write_rgba_png uses the png crate to write a real RGBA8 PNG.
  * Module docblock status section now says all four steps are wired.

- Cargo.toml: added libc, png, thiserror. (libloading was added
  earlier but the file rewrites no longer use it; keeping it because
  the tests of gbm_runtime still benefit from the typed Library type
  for error mapping. Could be removed later if desired.)

- toplevel_export.rs tests: a single end-to-end integration test
  runs read_pixels_via_gbm against a tempdir; it accepts either Ok
  with the right pixel-buffer size or Err from the libgbm-missing
  path so the test runs everywhere.

cargo test 98+/0; clippy clean.
2026-09-16 12:15:43 +02:00
en
50ae7c6061 Honest docs for ENBOXER_ENABLE_TOPLEVEL gated path (Bug #9)
Bug from Grok round-1 #9 plus the round-2 caveat that the gated path
claimed 'covered source works'. In reality the implementation issues
capture_output(...) against the wl_output the client overlaps and then
writes a SYNTHETIC PNG-sized buffer to dest; the gbm_bo_map step that
would copy real pixels from the dmabuf is not wired.

Changes:

- src/vfx.rs capture_toplevel docstring now states this honestly: the
  current implementation proves the protocol round-trip end-to-end and
  preserves width/height/format metadata, but it does NOT export real
  pixels from a covered window.
- src/toplevel_export.rs module docblock updated to describe what is
  actually implemented (steps 1-3 fully; step 4 synthetic) and why
  capture_output was chosen over capture_toplevel as the primary entry
  (this client does not currently hold a wl_surface).
- capture_via_export public docstring updated similarly.
- CHANGELOG.md entry.

Real pixel read is a follow-up tracked under the gbm_bo_map work. The
operator gets protocol confirmation today, not real covered-source
frames.

cargo test 96+/0; clippy clean.
2026-09-16 08:07:37 +02:00
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