Skip to content

synth: frame-pace the mouse timeline so drags survive a slow/stalled frame#184

Merged
borisbat merged 1 commit into
masterfrom
bbatkin/synth-mouse-frame-pace
Jun 6, 2026
Merged

synth: frame-pace the mouse timeline so drags survive a slow/stalled frame#184
borisbat merged 1 commit into
masterfrom
bbatkin/synth-mouse-frame-pace

Conversation

@borisbat

@borisbat borisbat commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Why

advance_mouse_timeline fired every event with t_ms <= now_ms (wall-clock), so on a coarse frame — the windows CI runner, where each test also eats ~10s of host spawn — a synth drag's press and destination-move collapse into one frame: imgui sees the button go down with the cursor already at the end, so the splitter/slider activates with a zero per-frame delta and never moves.

test_layout_helpers' real-drag subtest fails exactly this way on windows-latest (value/geometry unchanged) while passing on mac/ubuntu and on a fast local box.

Keys already solved this: imgui_key_chord / imgui_key_play are frame-paced (t_ms read as a frame index, one event-group per frame — see key_frame_paced). The mouse path never got it.

What

  • imgui_live_core: mouse_frame_paced / mouse_frame_no; advance_mouse_timeline steps the threshold by frame index when paced (the existing lerp then interpolates one cursor delta per frame); MousePlayArgs.frame_paced opts in. Wall-clock callers (move_to / click_at / plain play / recordings) are byte-identical.
  • imgui_playwright: drag() emits a frame-indexed timeline with frame_paced=true, so press → sweep → release each land on their own frame regardless of dt. drag_to() inherits.
  • Also clears 4 pre-existing LINT012 surfaced by touching the file (_input on the status/stop [live_command] handlers, matching imgui_snapshot's pattern).

Validation

Reproduced locally by throttling the headless harness frame loop to 300ms/frame: test_layout_helpers drag FAIL → PASS after this change; drag_drop / io_synth_drag stay green at the same throttle; all pass un-throttled.

Proven on real windows CI via probe #183 (this fix on top of the windows-enable branch): --- PASS 'test_layout_helpers' (10.9s) on windows-latest.

Clicks and recordings (wall-clock) are untouched.

Note: the other windows-latest red, test_imgui_synth_ctrl_shortcuts, is a separate issue — the host goes unresponsive during its subtest 3 (snapshot + key_status both return null), the same family as the deferred test_docking_basic host crash. Deferred with that; not addressed here.

🤖 Generated with Claude Code

…frame

advance_mouse_timeline fired every event with t_ms <= now_ms (wall-clock), so on a
coarse frame (the windows CI runner, where each test also eats ~10s of host spawn) the
press and the destination move collapse into ONE frame: imgui sees the button go down
with the cursor already at the end, so the splitter/slider activates with a zero
per-frame delta and never moves. test_layout_helpers' real-drag subtest fails exactly
this way on windows-latest (value/geometry unchanged) while passing on mac/ubuntu and on
a fast local box.

Keys already solved this: imgui_key_chord / imgui_key_play are frame-paced (t_ms read as
a frame index, one event-group per frame). Mirror it for the mouse:

- imgui_live_core: mouse_frame_paced / mouse_frame_no; advance_mouse_timeline steps the
  threshold by frame index when paced (the existing lerp then interpolates one cursor
  delta per frame); MousePlayArgs.frame_paced opts in. Wall-clock callers (move_to /
  click_at / plain play) are byte-identical.
- imgui_playwright: drag() emits a frame-indexed timeline with frame_paced=true, so
  press -> sweep -> release each land on their own frame regardless of dt. drag_to()
  inherits via drag().

Reproduced locally by throttling the headless harness frame loop to 300ms/frame
(test_layout_helpers drag FAIL -> PASS after this change); drag_drop / io_synth_drag
stay green at the same throttle. Clicks/recordings (wall-clock) are untouched.

Also clears 4 pre-existing LINT012 surfaced by touching the file (_input on the
status/stop live_command handlers, matching imgui_snapshot's pattern).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant