Two capture bugs compounding into 'sluggish and not captured':
1. flush_motion was never called from the run loop — the GTK client's
frame-clock tick flushed pending motion every frame, and the port
lost it. Pure mouse movement only reached the host when a click/key/
scroll happened to flush it; the host cursor simply didn't follow.
Now one coalesced MouseMove per loop iteration.
2. Capture forwarded ABSOLUTE letterboxed coordinates with no pointer
confinement (GTK parity, the plan's deferred 'stage-2' item): the
visible local cursor outran the host cursor by the full e2e and
escaped the window. Capture is now real pointer lock — SDL relative
mouse mode (hidden, confined, raw deltas) with relative MouseMove on
the wire, so the host cursor is the only cursor.
Also: focus-gain re-engages after an auto-release (Alt-Tab undoes
itself; the startup focus race can no longer strand the session
uncaptured) while a chord release stays released until the user opts
back in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
punktfunk-session streams one --connect session in an SDL3 window: ash
swapchain with a transfer-only letterboxed blit of the software-decode
path (no graphics pipeline until the phase-2 dmabuf/CSC pass), the
ui_stream input-capture state machine on SDL events (scancode→VK table
cross-checked against the evdev one), gamepads via a new caller-pumped
GamepadService mode (SDL video owns the main thread here), and the
shell↔session stdout contract: {"ready":true}, per-window stats:
lines, JSON error + exit codes 0/2/3/4. Strict trust — no pin, no
connect. Design: punktfunk-planning linux-client-rearchitecture.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>