Card-composition pinned source audit
Generated by python3 tools/audit-card-composition-sources.py --flake . --output docs/research/card-composition-source-audit.md.
Resolved inputs
.#shell-compositorderivation:/nix/store/cjwd6s14flmqlrxmiqh951d9jj1n50a6-sway-unwrapped-riscv64-unknown-linux-gnu-1.12.drv.#touch-launcherderivation:/nix/store/1n8haskvgqhvhci6xxqsglwvhnakzjd0-k230-touch-launcher.drv- Sway 1.12 source from the compositor derivation’s
srcenvironment field:/nix/store/2j7grygxd5da5r214vzz3y8b54rr739k-source - Installed wlroots headers:
/nix/store/dsxkjg3whpq9xvy5kd5k7mddq927a2l6-wlroots-0.20.2/include/wlroots-0.20.
The resolved package is the same flake attribute used by the k230 NixOS
configuration. This audit does not infer an ABI from a host Sway executable.
Client/protocol boundary
nix/touch-launcher/default.nix:13-20 generates only layer-shell and
xdg-shell client protocols and links wayland-client. In
nix/touch-launcher/touch-launcher.c:68-75,765-789, the launcher binds
wl_compositor, wl_shm, wl_seat, and zwlr_layer_shell_v1, creates its
own overlay surface, and requests non-interactive keyboard focus. Its
wl_touch listener (:723-761) receives touch only after Sway has selected
that client surface. It has neither a compositor-owned wlr_surface reference
for another client nor a global pre-routing touch hook. The current client
route can therefore retain metadata/launcher controls but cannot produce live
application cards, global drag, or authoritative focus restoration.
Sway/wlroots boundary
The pinned Sway source allocates a scene_tree and content_tree per
sway_view in sway/tree/view.c:77-95, assigns the view scene descriptor at
:85, and positions content through wlr_scene_node_set_position at
:1043-1047. It destroys the scene node during view teardown at :135-139.
It already keeps a saved-surface tree and clones scene-buffer references at
:1245-1289; this is evidence of a compositor-owned lifetime boundary, not a
license to expose client buffers to another process.
Sway routes touch through seat operations: sway/input/seat.c:1577-1600
dispatches down/motion/up/cancel to the active seatop_impl, and the default
operation resolves a container then calls seat_set_focus_container and
seatop_begin_down in sway/input/seatop_default.c:242-271. Focus helpers
are in sway/input/seat.c:1255-1299; view_close dispatches the existing
view implementation at sway/tree/view.c:547-551. These are patch points for
an opt-in Sway-owned card state machine.
wlroots 0.20’s installed wlr/types/wlr_scene.h:306-351,708-715 exposes node
positioning, input hit-testing, and an XDG-surface scene subtree. It has no
transform for a whole scene subtree: wlr_scene_buffer_set_dest_size at
:535-543 scales an individual buffer only. Sway’s existing
view_save_buffer at sway/tree/view.c:1245-1289 clones scene-buffer
references and disables live content, so it is a lifetime example but not a
live-card transform. The selected probe must prove identical scale and
translated coordinates for every live content/subsurface buffer across commits,
or stop without calling cropped or static output a card.
Pinned Sway also exposes more protocols than the current launcher binds:
sway/server.c:469-476 creates foreign-toplevel managers, :502-517 creates
export-dmabuf/screencopy/image-copy managers, and :555-563 creates
foreign-toplevel image-capture sources. A request is served from a separate
view->image_capture_scene using Sway’s allocator and renderer (:230-242),
not by sharing the live scene node. A client could enumerate/activate/close and
receive copied images, but would compose copies in its overlay, would not own
Sway’s focus or pre-routing touch, and has no demonstrated frame/presentation
synchronization with copied content. That route cannot meet the coherent live
surface/global drag/focus contract at an unmeasured Pixman cost.
Its
wlr/types/wlr_presentation_time.h:64-106 says a compositor must record
sampling/texturing and send presentation feedback only when it has that
evidence. The probe must log those calls separately from a frame callback.
Result
The source evidence selects a narrow, opt-in Sway patch for the next probe because it can keep app surfaces, input, focus, close dispatch, and presentation accounting under one owner. It does not prove coherent live subtree scaling, board operation, or product card UX. Those remain strict selected-route probe gates.