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

MouseMoveToArgs

struct MouseMoveToArgs

MouseClickAtArgs

struct MouseClickAtArgs

MouseEventWire

struct MouseEventWire

MousePlayArgs

struct MousePlayArgs

MouseStatusResult

struct MouseStatusResult

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? ): ImGuiContext?

Idempotent ImGui context create + backend init; safe across reload (reuses preserved ctx). Picks content scale: --imgui-content-scale=<float> override wins; otherwise queries glfwGetWindowContentScale. Loads JetBrains Mono at 14 * scale px (crisp atlas) and applies the daslang theme. For the auto-detected path it divides out the GL backend’s framebuffer/window ratio (io.DisplayFramebufferScale, already applied at render) so the UI isn’t double-scaled on macOS retina: ScaleAllSizes gets the residual and io.FontGlobalScale compensates the oversized atlas. On Windows DPI (framebuffer == window) and under an explicit override this is a no-op. Call from your script’s init().

Arguments:
live_imgui_render()

Drain the dynamic-texture queue and replay this frame’s ImDrawData with the pure-das GL renderer (opengl_imgui_driver). Call after Render(), in place of the old C++ backend’s draw step.

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_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_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_at(input: JsonValue? ): JsonValue?

def imgui_mouse_click_at (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_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:

3.1.4. Event timelines

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:
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