# Desktop menu dismissal comparison

Both sides: Linux x86_64, Electron 44.10.1, Xvfb 1920x1080, app window 1600x1000 at (0,0), light theme, browser zoom 100%, right browser panel 540 pixels wide. Fresh per-checkout T3 homes; no copied database, imported history, or paid agent turns. Synthetic project: Menu dismissal demo. Synthetic local page: page-server.py on port 18888.

Base: 95cb068c10a6cf0b33eed0a0cab3b298763fe852
Head: cf3b6cb4a096051783aa577987e00e4a57b08aa7

Each checkout was installed with `vp i` and built with `vp run build:desktop`. Its web dev stack ran with `T3CODE_DEV_SEED=0 vp run dev`. Electron was launched through `headless-desktop` with `--no-sandbox --disable-gpu`, its own `T3CODE_HOME` and `T3CODE_PORT`, and `VITE_DEV_SERVER_URL` pointing at that checkout's web dev port. The base needed an isolated XDG_CONFIG_HOME to avoid the desktop instance lock. Development automatically opened host DevTools; these were closed before capture.

Create a synthetic git directory and add it through `node apps/server/src/bin.ts project add --base-dir <isolated-home> --title 'Menu dismissal demo' <synthetic-repository>`. Deselect discovered history during onboarding. Open the right panel, select Browser, navigate to http://localhost:18888/.

Raw CDP Runtime.evaluate was used on the HOST ONLY for setup and reading host menu presence. Each websocket closed after the evaluation. No connection was ever made to the guest WebContents; no CDP session was attached during physical input. The recording driver uses xdotool XTest mouse and keyboard input exclusively. No production code, focus listeners, or browser behavior was changed.

Run `record-proof.py <output-directory> before` or `after` with DISPLAY and XAUTHORITY set to the corresponding headless display. Each run creates its own timestamped directory. It records the full 1600x1000 app, captures identical pixel screenshots 500ms apart, then crops stills to the browser panel (540x600). Videos are unedited.

Sequence:
1. Click blank host area to dismiss any previous menu, reload page, open Preview menu by mouse, click page button. Counter: 0 to 1.
2. Click blank host area, click page once, open Preview menu by mouse, click page button again. Counter: 2 to 3.
3. Click blank host area, open Preview menu, Escape, Space to reopen it by keyboard, click page button. Counter: 3 to 4.

Each menu-open and after-click state is captured. On base, the menu stays open after the first post-reload page click. It closes after the prior-click and keyboard variants in this run. On head, it closes after all three, and every page click still increments the counter. The base failure repeated in two recorded runs and an initial manual run; a different earlier run dismissed the menu, confirming intermittency.

The final synthetic page displays event.isTrusted and document.hasFocus() from its own click handler. Both sides show trusted clicks and guest focus at click time. Therefore these captures prove the visible menu regression and its fix, but do not establish the specific guest-never-takes-focus condition described in the PR. macOS and Windows were not tested.
