F15 — Popup with grab
Context menus are the acid test of a platform's secondary-surface model: positioned relative to a parent, grabbing input, dismissed by clicking outside — which requires events the popup doesn't naturally receive.
Requirements
- Right-click opens a menu-like popup (solid panel, 3 fake items, hover highlight) at the pointer; clicking an item logs it; clicking outside dismisses; Esc dismisses.
- Wayland:
xdg_popupwith anxdg_positioner(anchor rect at the click, gravity bottom-right,constraint_adjustmentslide+flip) +xdg_popup.grabwith the click serial; handlepopup_done. - X11: an override-redirect window +
XGrabPointer/XGrabKeyboard; outside-click detection via the grab; document the focus model mess (no WM involvement). - Win32: a
WS_POPUPwindow +SetCapture(or theTrackPopupMenu-style internal loop — implement the capture variant; noteTrackPopupMenuas the system escape hatch and its modal-loop implications for F03). - macOS: a borderless
NSWindow(NSWindowStyleMaskBorderless) + a local+global event monitor for outside clicks (do this variant; noteNSMenuas the escape hatch and what it does for free).
- Wayland:
- Edge correctness: open the popup near the bottom-right screen/output edge and log the final placement — who repositioned it (compositor via positioner vs app math)?
- Nested popup (submenu) one level deep — Wayland requires the parent-popup chain; others re-parent or stack; log the stacking order events.
- Log dismissal cause (
popup_done, grab-break, capture-loss, monitor event) — the asymmetry of who decides dismissal is the finding.
Instrumentation
popup_open anchor=… gravity=…, popup_placed rect=…, popup_dismiss cause=…, grab state=….
Findings to record
- Placement ownership: declarative constraints (Wayland) vs app-computed geometry (others) — what a framework positioner API must express.
- Grab semantics per platform and what breaks them (focus loss, another popup, screen edge).
- Whether the popup may exceed output bounds (Wayland: no; others: measured).
- The escape hatches (
NSMenu,TrackPopupMenu) and what using them costs in control.
Verification
Wayland: Tier A under headless weston (positioner math + grab handshake visible in the trace; synthetic pointer via weston test input where available). X11: Tier A under Xvfb + xdotool clicks. Win32 A[wine], macOS A[ssh] for open/place/dismiss-by-Esc; real outside-click feel and multi-monitor edges: Tier C.