5cbd249d09
The first real run on a display surfaced three issues the headless/dev-VM build never hit: - Route each hook-using screen (hosts/pair/stream) as its own component() instead of calling it with the shared cx. Calling hooks on the parent cx changed the hook order when the screen flipped, tripping reactor's Rules-of-Hooks guard and aborting the moment you navigated to the stream page. - Mouse: replace the absolute path (which swallowed WM_MOUSEMOVE and so froze the OS cursor, snapping the host pointer back to one point) with proper pointer lock — hide + ClipCursor + recentre, shipping relative MouseMove scaled by the Contain-fit factor. Ctrl+Alt+Shift+Q now actually toggles capture: track modifier state from the hook's own event stream (GetAsyncKeyState doesn't see keys we suppress in our own LL hook), and flush held keys/buttons on release so nothing sticks on the host. - Add the stats HUD overlay (mode · fps · Mb/s · capture→client/decode latency), mirroring the Apple client. Stats live in root state and reach the stream page as a prop (a child's own async-state update is pruned when props are unchanged), fed by a small poll thread. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>