6 KiB
STEP20C nested valid-grab fixture (EXPERIMENTAL)
This source-only fixture reproduces the nested popup probe.
It does not enter the Mosaic build, production patch or package. It reuses
the unchanged pointer-daemon.c, virtual-pointer XML and three private
patches from ../step20c-valid-grab/.
Bases and dependencies
| Input | Pinned base / version | SHA-256 |
|---|---|---|
| Mosaic private patch | Mosaic cd550382b311efdbfe3ed892f4e1d281d852e754 |
d416f6413ea097a48a44d231e50ffba363914f46c8687f0ea2e4dcacd5f31fe9 |
| SceneFX private patch | SceneFX 37ccd723bef49e6891156ffafce8f549f01446cc (0.5) |
c74c515b98da8f5f637e260e6a3755c7a75bd78d1c39e54a67850f1c383e30e7 |
| Hidden-owner guard | After Mosaic private patch | 35785a8f3e863b3c1fd87932d8ff0c2949b03cb04382cc34e1126170968f802b |
| Persistent virtual pointer | Previous fixture | a00fcedc38ccb7ca4c25c982d9f38e8bde3168a3833f0c9cf2056e841d720938 |
| Virtual-pointer XML | wlr-protocols b010a03648b88d143236de193bddbfea0c08bc84 |
3ff6d540be0bc5228195bf072bde42117ea17945a5c2061add5d3cf97d6bb524 |
nested-client.c |
This fixture | 2e40c98af72a0df8b316810589a0be8f4425a763db1de448b49a7813956b6f7d |
prepare.sh |
This fixture, post-audit failed-build cleanup | 55fe81b7f17fb1cf8af7089a0034864910c49feccbe4cfe22e857c98b9db0dde |
run.py |
This fixture, post-audit socket isolation and cleanup | 72ff17d8042edf3265b3a0ff91f0bc4805001b1438c4ecadfe29ead76278c9be |
The measured machine had SwayFX 0.6, wlroots 0.20.2, SceneFX 0.5.0,
Wayland client 1.26.0 and wayland-protocols 1.49. The installed XDG Shell
XML declares version 7; the fixture binds xdg_wm_base version 3, like
the previous client. Required local tools include Git, Meson, Ninja, C17
compiler, pkg-config, wayland-scanner, kitty, swaymsg, grim, wev
and Python. prepare.sh downloads the pinned SceneFX source into a disposable
directory; it does not install anything.
Differences from the earlier fixture
nested-client.c creates three distinct surfaces and XDG roles. Popup A's
parent is the toplevel xdg_surface; popup B's parent is A's xdg_surface.
Each popup uses a separate, logged, real pointer-button serial and maps only
after its own configure/ack. The client logs all surface object IDs, events,
local pointer coordinates, popup_done and child-first destruction. It accepts
close_b and close_owner on stdin. The runner exercises three placements:
visible, b_cross and both_cross. No prior source file is modified.
Fresh replay
Run from a fresh repository checkout at or after the preserved fixture commit.
No old /tmp laboratory is needed. The script prints LAB=/tmp/... after
building a private SceneFX library, private guarded compositor, new client and
unchanged virtual-pointer daemon. Save that path for subsequent commands.
prepare_log=$(mktemp /tmp/mng-prepare-XXXXXXXX)
sh tooling/probes/step20c-nested-grab/prepare.sh | tee "$prepare_log"
LAB=$(sed -n 's/^LAB=//p' "$prepare_log")
test -d "$LAB"
python tooling/probes/step20c-nested-grab/run.py "$LAB" control visible_click visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_standard visible_click visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic visible_click visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic crossing b_cross
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic crossing both_cross
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic close_b visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic outside visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic hidden b_cross
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic hidden_click b_cross
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic owner visible
python tooling/probes/step20c-nested-grab/run.py "$LAB" private_mosaic toggle b_cross
For a full comparison, repeat crossing, close_b, outside and owner
with control and private_standard as in the report. Each case name is
single-use in a lab; use a new lab or rename an earlier case directory to
retain both iterations. run.py uses a short, new /tmp/mng-* runtime path
because Unix socket paths have a strict length limit; each case's
runtime-path records the path for audit. The script removes inherited desktop
Wayland/IPC variables, uses explicit swaymsg -s, terminates and reaps only
its own process groups, then removes its runtime directory. It never reloads
or replaces the daily compositor.
The retained historical runs used the earlier runner and preparation hashes;
the current prepare.sh removes an incomplete laboratory on failure, while
run.py adds an IPC path-length bound, clears inherited
I3SOCK, reaps child processes and removes its runtime directory. It changes
no popup protocol action, capture point or experimental compositor patch.
Each case contains client.log with WAYLAND_DEBUG=1, pointer.log,
compositor.log, wev.log, tree-*.json, outputs-*.json and both output
PNGs. Read POPUP_A/B CREATE, GRAB_REQUEST, ROLE_CONFIGURE,
XDG_CONFIGURE, MAP, POINTER_*, POPUP_DONE and DESTROY in order.
Compare screenshots and traces: a right-output pixel alone does not prove
which surface received a button, and popup_done under a legitimate grab
does not prove an invisible surface hit. The open scenario intentionally
only captures mapping; visible_click also presses B. A case returning zero
is not automatically a scientific PASS.
Cleanup
After all per-case processes have exited, check runtime-path files for any
directory left by an interrupted run and remove only those recorded /tmp/mng-*
directories, then remove the named LAB directory and prepare_log. Preserve
the laboratory while reviewing evidence. Generated
protocol files, binaries, private libraries, sockets, logs and images remain
outside Git. The source fixture and original patches stay in Git.