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:
window : GLFWwindow?
- 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:
input : JsonValue?
- imgui_key_play(input: JsonValue? ): JsonValue?
def imgui_key_play (input: JsonValue?) : JsonValue?
- Arguments:
input : JsonValue?
- imgui_key_status(_input: JsonValue? ): JsonValue?
def imgui_key_status (_input: JsonValue?) : JsonValue?
- Arguments:
_input : JsonValue?
- imgui_key_stop(_input: JsonValue? ): JsonValue?
def imgui_key_stop (_input: JsonValue?) : JsonValue?
- Arguments:
_input : JsonValue?
- imgui_key_type(input: JsonValue? ): JsonValue?
def imgui_key_type (input: JsonValue?) : JsonValue?
- Arguments:
input : JsonValue?
- imgui_mouse_click_at(input: JsonValue? ): JsonValue?
def imgui_mouse_click_at (input: JsonValue?) : JsonValue?
- Arguments:
input : JsonValue?
- imgui_mouse_move_to(input: JsonValue? ): JsonValue?
def imgui_mouse_move_to (input: JsonValue?) : JsonValue?
- Arguments:
input : JsonValue?
- imgui_mouse_play(input: JsonValue? ): JsonValue?
def imgui_mouse_play (input: JsonValue?) : JsonValue?
- Arguments:
input : JsonValue?
- imgui_mouse_status(_input: JsonValue? ): JsonValue?
def imgui_mouse_status (_input: JsonValue?) : JsonValue?
- Arguments:
_input : JsonValue?
- imgui_mouse_stop(_input: JsonValue? ): JsonValue?
def imgui_mouse_stop (_input: JsonValue?) : JsonValue?
- Arguments:
_input : JsonValue?
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:
events : array< KeyEventWire>
- 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:
events : array< MouseEventWire>