3.1. Live-reload lifecycle and synthetic-IO bypass driver

Live-reload lifecycle plus the synthetic-IO bypass driver. The imgui_live half wires up GLFW window creation, ImGui context construction, and the daslang-live integration so a script can hot-reload its widget code without losing window state. The imgui_live_core half carries the synth-IO transport — mouse + keyboard timelines, imgui_mouse_play / imgui_key_play event drains, side-mod alias emission, position-prefix button ordering — so headless test recordings and playwright drivers generate input that ImGui sees as if it came from the OS.

The synth path replaces the GLFW backend’s UpdateMouseData polling once per frame via apply_synth_io_override, reasserting the synth cursor pose between Impl_NewFrame and NewFrame. Visible widgets that “don’t fire” trace to this override race; the bypass driver always wins.

3.1.1. Structures

MousePosArgs

struct MousePosArgs

MouseClickArgs

struct MouseClickArgs

MouseScrollArgs

struct MouseScrollArgs

MouseMoveToArgs

struct MouseMoveToArgs

MouseEventWire

struct MouseEventWire

MousePlayArgs

struct MousePlayArgs

MouseStatusResult

struct MouseStatusResult

KeyPressArgs

struct KeyPressArgs

KeyCharArgs

struct KeyCharArgs

KeyTypeArgs

struct KeyTypeArgs

KeyChordArgs

struct KeyChordArgs

KeyEventWire

struct KeyEventWire

KeyPlayArgs

struct KeyPlayArgs

KeyStatusResult
Fields:
  • playing : bool - true while a recorded key timeline is being replayed.

  • elapsed_ms : int - milliseconds since timeline playback began (0 when idle).

  • queue_idx : int - index of the next pending event in the timeline.

  • queue_total : int - total number of events in the active timeline.

  • held_count : int - number of synthetic keys currently held down.

  • last_keycode : int - ImGuiKey value (renamed from “key” so visual_aids can read uniformly)

  • last_codepoint : uint - most recent codepoint pushed via AddInputCharacter.

3.1.2. Lifecycle

live_imgui_init(window: GLFWwindow?; glsl_version: string = "#version 330" ): ImGuiContext?

Idempotent ImGui context create + backend init; safe across reload (reuses preserved ctx). Reads the window’s content scale, loads JetBrains Mono at 14 * scale px, applies the daslang theme, and calls ScaleAllSizes(scale) so paddings/ spacings/rounding match the display. Call from your script’s init().

Arguments:
live_imgui_shutdown()

Reload-aware ImGui shutdown — skips during reload so the ctx is reused, runs only on process exit. Call from your script’s shutdown().

3.1.3. Synth IO drivers

imgui_key_char(input: JsonValue? ): JsonValue?

def imgui_key_char (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_chord(input: JsonValue? ): JsonValue?

def imgui_key_chord (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_play(input: JsonValue? ): JsonValue?

def imgui_key_play (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_press(input: JsonValue? ): JsonValue?

def imgui_key_press (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_release(input: JsonValue? ): JsonValue?

def imgui_key_release (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_status(input: JsonValue? ): JsonValue?

def imgui_key_status (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_stop(input: JsonValue? ): JsonValue?

def imgui_key_stop (input: JsonValue?) : JsonValue?

Arguments:
imgui_key_type(input: JsonValue? ): JsonValue?

def imgui_key_type (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_click(input: JsonValue? ): JsonValue?

def imgui_mouse_click (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_move_to(input: JsonValue? ): JsonValue?

def imgui_mouse_move_to (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_play(input: JsonValue? ): JsonValue?

def imgui_mouse_play (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_pos(input: JsonValue? ): JsonValue?

def imgui_mouse_pos (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_scroll(input: JsonValue? ): JsonValue?

def imgui_mouse_scroll (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_status(input: JsonValue? ): JsonValue?

def imgui_mouse_status (input: JsonValue?) : JsonValue?

Arguments:
imgui_mouse_stop(input: JsonValue? ): JsonValue?

def imgui_mouse_stop (input: JsonValue?) : JsonValue?

Arguments:
imgui_synth_tick()

Per-frame entry point — advance synth mouse/key timelines and re-assert held state. Call between the backend’s *_NewFrame() and ImGui::NewFrame(); no-op when no synth command has fired.

synth_tick_run_count(): int

Number of times imgui_synth_tick has run this process. Zero means apply_synth_io_override() has never fired — any queued synth event will silently no-op.

synth_warned_no_override(): bool

True iff the no-override warning has been emitted this process. One-shot — only the first synth command on a process that hasn’t ticked flips this.

3.1.4. Event timelines

sort_mouse_play_events(events: array<MouseEventWire> )

Sort wire-format mouse events ascending by t_ms in place — call before feeding imgui_mouse_play so the timeline drains in chronological order.

Arguments:

3.1.5. Status / introspection

3.1.6. Uncategorized

get_synth_cursor(): tuple<bool;float;float>

Current synth cursor as (owned, x, y); owned=true means visual_aids overlays should render against this position instead of GetMousePos().

get_synth_keys(): tuple<bool;uint;float>

Current synth-key state as (active, last_codepoint, last_codepoint_t); visual_aids polls this each frame to detect newly-landed codepoints.

sort_key_play_events(events: array<KeyEventWire> )

Sort wire-format key events ascending by t_ms in place — call before feeding imgui_key_play so the timeline drains in chronological order.

Arguments:
warn_if_synth_tick_missing(cmd: string )

Emit a one-shot LOG_WARNING if cmd queued synth events before imgui_synth_tick has ever run. Called from every synth-event-queueing live_command to surface the boost_basics-style trap (tutorial author forgot apply_synth_io_override() in update()).

Arguments:
  • cmd : string

reset_synth_warning_state()

Reset the one-shot tick-counter and warned flag. Intended for tests that re-exercise the trap detector within a single process.