1.2. Boost runtime — widget state structs, registry, and dispatcher

Runtime support layer for the [widget] / [container] macros: the per-kind state structs, the per-frame widget registry, the imgui_* live-command dispatcher, and the AwaitModifiers / Result framing that lets clients drive ImGui from outside the GLFW main thread. Widget state structs mix @live fields (preserved across hot-reload) and @optional fields (transient, dropped from JV when zero-valued). Common per-frame ImGui state — hex_id, bbox, hover / active / focus — lives in WidgetEntry, not the per-kind structs, so each state struct stays small.

The live-command surface (imgui_snapshot, imgui_click, imgui_set, imgui_open, imgui_close, imgui_focus, imgui_await, imgui_drag, imgui_type_text) is the wire-protocol that imgui_playwright and external test harnesses drive. Commands resolve targets via the registry’s path key (e.g. MAIN_WIN/SETTINGS_TAB/RPS) or raw 0x<hex_id>; results carry an AwaitResult whose await_* modifiers tell the client to wait for quiescence or a specific frame number before reading the response.

1.2.1. Structures

ClickState
Fields:
  • click_count : int - cumulative across reloads

  • pending_click : bool - queued by imgui_click L2; consumed next frame

  • clicked : bool - true on the frame the button fired

SliderStateFloat
Fields:
  • value : float - preserved across reload

  • bounds : tuple<float;float> - (min, max)

  • has_pending : bool - imgui_set L3 sets; render fn consumes

  • pending_value : float - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateFloat2
Fields:
  • value : float2 - preserved across reload

  • bounds : tuple<float;float> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateFloat3
Fields:
  • value : float3 - preserved across reload

  • bounds : tuple<float;float> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateFloat4
Fields:
  • value : float4 - preserved across reload

  • bounds : tuple<float;float> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateInt
Fields:
  • value : int - preserved across reload

  • bounds : tuple<int;int> - (min, max)

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateInt2
Fields:
  • value : int2 - preserved across reload

  • bounds : tuple<int;int> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateInt3
Fields:
  • value : int3 - preserved across reload

  • bounds : tuple<int;int> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

SliderStateInt4
Fields:
  • value : int4 - preserved across reload

  • bounds : tuple<int;int> - (min, max) applied to every component

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

ToggleState

Shared across Checkbox / RadioButton (bool form) / Selectable / MenuItem. pending_toggle + pending_value let imgui_set steer the next frame’s value deterministically; the renderer consumes-then-clears.

Fields:
  • value : bool - current toggle state; preserved across reload

  • pending_toggle : bool - imgui_set L3 sets; consumed next frame

  • pending_value : bool - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

RadioIntState

Backs RadioButton(int form). value is the currently-selected button id; the widget def takes the per-call v_button and writes value=v_button when the user clicks. imgui_set {“value”:N} steers the selection.

Fields:
  • value : int - currently-selected button id

  • pending_set : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame selection queued by imgui_set

  • changed : bool - true on the frame the selection changed

DragStateFloat
Fields:
  • value : float - preserved across reload

  • bounds : tuple<float;float> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateFloat2
Fields:
  • value : float2 - preserved across reload

  • bounds : tuple<float;float> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateFloat3
Fields:
  • value : float3 - preserved across reload

  • bounds : tuple<float;float> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateFloat4
Fields:
  • value : float4 - preserved across reload

  • bounds : tuple<float;float> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateInt
Fields:
  • value : int - preserved across reload

  • bounds : tuple<int;int> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateInt2
Fields:
  • value : int2 - preserved across reload

  • bounds : tuple<int;int> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateInt3
Fields:
  • value : int3 - preserved across reload

  • bounds : tuple<int;int> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateInt4
Fields:
  • value : int4 - preserved across reload

  • bounds : tuple<int;int> - (min, max); zero-init = unclamped

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

DragStateRangeFloat

value.x = current_min, value.y = current_max. Bounds clamp both. imgui_set {“value”:[lo,hi]} writes the whole range atomically.

Fields:
  • value : float2 - (current_min, current_max); preserved across reload

  • bounds : tuple<float;float> - (min, max) clamp applied to both endpoints

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float2 - next-frame range queued by imgui_set

  • changed : bool - true on the frame the range changed

DragStateRangeInt

value.x = current_min, value.y = current_max.

Fields:
  • value : int2 - (current_min, current_max); preserved across reload

  • bounds : tuple<int;int> - (min, max) clamp applied to both endpoints

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int2 - next-frame range queued by imgui_set

  • changed : bool - true on the frame the range changed

InputStateFloat
Fields:
  • value : float - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateFloat2
Fields:
  • value : float2 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateFloat3
Fields:
  • value : float3 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateFloat4
Fields:
  • value : float4 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateInt
Fields:
  • value : int - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateInt2
Fields:
  • value : int2 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int2 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateInt3
Fields:
  • value : int3 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int3 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateInt4
Fields:
  • value : int4 - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int4 - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

InputStateDouble
Fields:
  • value : double - preserved across reload

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : double - next-frame value queued by imgui_set

  • changed : bool - true on the frame the widget fired

ColorState3
Fields:
  • value : float3 - RGB in [0..1]

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float3 - next-frame RGB queued by imgui_set

  • changed : bool - true on the frame the color changed

ColorState4
Fields:
  • value : float4 - RGBA in [0..1]

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : float4 - next-frame RGBA queued by imgui_set

  • changed : bool - true on the frame the color changed

ComboState
Fields:
  • value : int = -1 - selected index, -1 = none

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame selection queued by imgui_set

  • changed : bool - true on the frame the selection changed

  • items_buf : array<uint8> - transient zero-separated buffer; rebuilt each frame

ListBoxState
Fields:
  • value : int = -1 - selected index, -1 = none

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : int - next-frame selection queued by imgui_set

  • changed : bool - true on the frame the selection changed

InputTextState
Fields:
  • value : string = “” - current text content (clone of buffer)

  • capacity : int = 256 - working buffer size in bytes (incl. trailing null)

  • has_pending : bool - imgui_set queued; consumed next frame

  • pending_value : string = “” - next-frame text queued by imgui_set

  • changed : bool - true on the frame the text changed

  • buffer : array<uint8> - working buffer; mirrors value, allocated to capacity on first frame / post-reload

TextShowState

Backs the text_show display widget (master plan §4.3a). Read-only from the user’s perspective — value is set either by an initializer at the call site (text_show(STATUS, value=”saved”)) or programmatically (STATUS.value = compute_status()). The standard serializer surfaces value for telemetry / playwright expect_value(app, STATUS, “saved”). Tests can also drive the value externally via imgui_set — the dispatcher writes state.value directly.

Fields:
  • value : string = “” - displayed text; settable via call-site initializer or imgui_set

PlotState

Backs the plot_lines / plot_histogram display widgets. The plotted values are passed per-frame as a parameter (not stored in state) — same shape as the imgui_test_engine and daslib v1 conventions. State carries last-frame’s call args for telemetry: the visible label, the (scale_min, scale_max) range, and the sample count. Read-only — no dispatcher.

Fields:
  • title : string - overlay text

  • bounds : tuple<float;float> - (scale_min, scale_max)

  • samples : int - length(values) last frame

NarrativeState

Backs every text-bearing narrative widget — text / text_unformatted / text_wrapped / text_colored / text_disabled / bullet_text / separator_text / set_tooltip / set_item_tooltip. The displayed string is per-call (the call site is the source of truth) and echoed into value every frame for telemetry. expect_value(MSG, “literal”) works uniformly across the family. Read-only — no dispatcher.

Fields:
  • value : string - per-frame echo of call-site text arg

LabelTextState

Backs the label_text display widget. ImGui’s LabelText(label, fmt) displays the label-key on the left and the value-text on the right; both strings are per-call and echoed for telemetry. Read-only — no dispatcher. (Field is key not labellabel is reserved in gen2.)

Fields:
  • key : string - per-frame echo of the left-side label string

  • value : string - per-frame echo of the right-side value string

EmptyMarkerState

Backs the stateless decoration widgets — separator, spacing, new_line, dummy, same_line, bullet. The state global exists only because [widget] auto-emit needs something to instantiate; mirrors GroupState / MenuBarState / TooltipState shape.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [widget] auto-emit

ImageState

Backs the image display widget. Texture handle is opaque (void?), so telemetry echoes only the actionable per-call args — size, uv rectangle, tint/border colors. Read-only — no dispatcher.

Fields:
  • size : float2 - per-call display size

  • uv0 : float2 - upper-left uv

  • uv1 : float2 - lower-right uv

  • tint_col : float4 - tint applied to texels

  • border_col : float4 - border color (zero alpha = no border)

ProgressBarState

Backs the progress_bar display widget. fraction is per-frame per-call (the caller drives progress); overlay is the optional center-aligned label; size is the per-call display size. Read-only — no dispatcher.

Fields:
  • fraction : float - per-frame progress in [0,1]; -1 means indeterminate

  • overlay : string - optional overlay text (e.g. “42/100”)

  • size : float2 - per-call display size; (-1, 0) defaults to full-width

WindowState

Backs the window container. open defaults to true so a closable window renders from frame 1; the X-button or imgui_close flips it false. @live carries that across reload. Everything else is per- frame observed (pos/size/collapsed/scroll) or echoed from per-call args (flags). ImGui persists window pos itself via imgui.ini, so duplicating it as @live would only fight that. imgui_open / imgui_close flow through pending_open/close; the renderer applies them at the top of the next frame. Per-call config (closable, flags) is supplied via the named-tuple at the call site — same convention as [widget].

Fields:
  • open : bool = true - window open state; preserved across reload

  • flags : ImGuiWindowFlags - per-call ImGuiWindowFlags (echoed for telemetry)

  • pos : float2 - observed window position (top-left, screen coords)

  • size : float2 - observed window size

  • collapsed : bool - observed collapsed state

  • scroll : float2 - (GetScrollX, GetScrollY) of the window

  • scroll_max : float2 - (GetScrollMaxX, GetScrollMaxY)

  • pending_open : bool - imgui_open queued; applied next frame

  • pending_close : bool - imgui_close queued; applied next frame

ChildState

Backs the child container. All fields are observed (scroll); per- call config (size, child_flags, window_flags) is supplied via the named-tuple at the call site.

Fields:
  • size : float2 - per-call child region size (echoed for telemetry)

  • child_flags : ImGuiChildFlags - per-call ImGuiChildFlags

  • window_flags : ImGuiWindowFlags - per-call ImGuiWindowFlags

  • scroll : float2 - (GetScrollX, GetScrollY)

  • scroll_max : float2 - (GetScrollMaxX, GetScrollMaxY)

GroupState

Backs the group container. Pure layout grouping — no persistent or observable state, but the [container] macro still needs a struct to hang the auto-emitted global on. The _placeholder field stays @optional so JV(state) emits {} when the group is rendered.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

MenuBarState

Backs the menu_bar container. Stateless wrapper.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

MenuState

Backs the menu container — a single drop-down inside a menu bar. enabled is per-call; opened is per-frame observed.

Fields:
  • enabled : bool - per-call enable flag (echoed for telemetry)

  • opened : bool - observed per-frame: menu is currently expanded

PopupState

Shared by popup and popup_modal. open is @live so the user-driven state survives reload. imgui_open / imgui_close route through pending_open/close; the renderer issues OpenPopup/CloseCurrentPopup on the next frame in response.

Fields:
  • open : bool - popup open state; preserved across reload

  • flags : ImGuiWindowFlags - per-call ImGuiWindowFlags

  • pending_open : bool - imgui_open queued; OpenPopup fires next frame

  • pending_close : bool - imgui_close queued; CloseCurrentPopup fires next frame

TabBarState

Backs the tab_bar container. ImGui drives active-tab selection itself; we just observe.

Fields:
TabItemState

Backs the tab_item container. open defaults to true so a closable tab renders from frame 1; the X-button or imgui_close flips it false. @live carries that across reload.

Fields:
  • open : bool = true - tab open state; preserved across reload

  • flags : ImGuiTabItemFlags - per-call ImGuiTabItemFlags

  • pending_open : bool - imgui_open queued; applied next frame

  • pending_close : bool - imgui_close queued; applied next frame

TooltipState

Backs both tooltip and item_tooltip. Tooltips don’t persist — they’re a per-frame chrome pop.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

PopupContextItemState

Backs popup_context_item. Right-click attaches to the previous item and ImGui drives open/close internally; no pending flags needed.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

PopupContextWindowState

Backs popup_context_window. Right-click anywhere in the enclosing window opens the popup; ImGui drives open/close internally.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

TextFilterState

Backs text_filter. Holds the bound C++ ImGuiTextFilter value inline — zero-init is safe (empty InputBuf, empty Filters ImVector, CountGrep = 0), so no explicit ctor call is needed. text_filter renders the inline InputText editor via the bound Draw() method; passes_filter(state, line) delegates to the

Fields:
  • value : string - hand-bound PassFilter(filter, text) standalone helper.

  • filter : ImGuiTextFilter - mirrored InputBuf text for snapshot/telemetry

DragDropSourceState

Backs drag_drop_source. Drag activation lives entirely in ImGui’s internal drag-drop state machine; body runs only on active drag.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

DragDropTargetState

Backs drag_drop_target. Body runs only when a payload-bearing drag is hovering this target — caller still calls AcceptDragDropPayload inside.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

TreeNodeState

Backs the tree_node container. ImGui owns the open/close state internally; we mirror what’s observable so snapshots reflect truth, and the dispatcher routes open/close through SetNextItemOpen.

Fields:
  • flags : ImGuiTreeNodeFlags - per-call ImGuiTreeNodeFlags

  • opened : bool - observed per-frame: TreeNode returned true

  • pending_open : bool - imgui_open queued; SetNextItemOpen(true) fires next frame

  • pending_close : bool - imgui_close queued; SetNextItemOpen(false) fires next frame

CollapsingHeaderState

Backs the collapsing_header container. Same shape as TreeNodeState plus a TabItemState-style @live open slot for the X-button form (CollapsingHeader(label, bool* p_visible, flags)). open defaults to true so a closable section renders from frame 1; the X-button or imgui_close flips it false.

Fields:
  • open : bool = true - closable form’s p_visible state; preserved across reload

  • flags : ImGuiTreeNodeFlags - per-call ImGuiTreeNodeFlags

  • opened : bool - observed per-frame: CollapsingHeader returned true

  • pending_open : bool - imgui_open queued; SetNextItemOpen(true) fires next frame

  • pending_close : bool - imgui_close queued; SetNextItemOpen(false) fires next frame

MainMenuBarState

Backs the main_menu_bar container — BeginMainMenuBar() / EndMainMenuBar(). Screen-top, persistent; ImGui owns visibility, we just register the container path. Stateless wrapper.

Fields:
  • _placeholder : bool - unused; keeps the struct non-empty for [container] auto-emit

WidgetEntry

Per-frame snapshot of one rendered widget. Common fields populated every frame; per-kind detail is materialized on demand by the serializer lambda stored in g_serializers[ident] (parallel table) and pasted into payload at imgui_snapshot time. The lambda lives outside the entry because g_registry is cleared every frame and we need the serializer (which captures & state of the per-widget global) to survive that clear.

Fields:
  • kind : string - widget kind (“button”, “slider_float”, …)

  • hex_id : uint - ImGui’s GetID() for this widget on this frame

  • bbox : float4 - packed [x0, y0, x1, y1]

  • hover : bool - IsItemHovered() this frame

  • active : bool - IsItemActive() this frame

  • focus : bool - IsItemFocused() this frame

  • payload : JsonValue? - populated by widget_entry_jv from g_serializers

WidgetMeta
Fields:
  • module_name : string - owning module; lets clear_module_widgets drop on reload

  • kind : string - widget kind (“button”, “slider_float”, …)

  • state_addr_getter : lambda<void> - resolves the live state-struct address on every invoke (stable for globals; key-checked re-resolution for indexed widgets) — used by finalize lambdas to avoid dangling captures after table rehash/erase

  • serializer : lambda<void> - captured-state serializer; invoked at imgui_snapshot time

  • last_seen_frame : int - last g_frame this path appeared in g_registry; -1 = never rendered

AwaitModifiers

Per-command await knobs. Pulled from input[“await”] by with_await; all fields optional with sensible defaults (5s, no-op).

Fields:
  • await_frames : int = -1 - min frames to advance before considering the command settled; -1 = no frame floor

  • await_until : string = “” - quiescence predicate name (empty = default is_quiescent())

  • timeout_sec : float = 5f - client-side wait ceiling (seconds)

  • fire_and_forget : bool = false - when true, client skips the await loop entirely

AwaitArgs
Fields:
  • until : string = “quiescent” - quiescence predicate name to poll

  • frame : int = -1 - when >=0, return quiescent once g_frame >= this value

AwaitResult
Fields:
  • quiescent : bool = false - true when the requested condition currently holds

  • frame : int = 0 - server’s current g_frame

  • pending_coroutines : int = 0 - length(g_coroutines) — in-flight L1 input drivers

  • active_id : uint = 0x0 - GetActiveID() — non-zero when a widget is being interacted with

DragArgs
Fields:
  • target : string = “” - widget path or 0x… hex_id where the drag starts

  • dx : float = 0f - horizontal pixel delta from start to end

  • dy : float = 0f - vertical pixel delta from start to end

  • steps : int = 4 - interpolation steps (one mouse move per frame)

  • button : int = 0 - ImGuiMouseButton index (0=Left, 1=Right, 2=Middle)

TypeTextArgs
Fields:
  • target : string = “” - informational target path (chars go to whichever widget holds focus)

  • text : string = “” - ASCII text to push one char at a time

  • per_char_frames : int = 1 - frames between consecutive chars

  • total_frames : int = 0 - when >0, overrides per_char_frames so the typing fits this frame budget

1.2.2. Per-frame registry

begin_frame()

Per-frame reset: bumps the frame counter and clears the per-frame registry, hex_id→bbox map, and container path. Call before rendering widgets; L1 coroutines advance separately via advance_coroutines.

register_widget(module_name: string; bare_ident: string; kind: string; state_addr_getter: lambda<():void>; serializer: lambda<():void> )

Module-init registration of a widget into the long-lived g_widgets table; module_name lets clear_module_widgets drop it on reload. state_addr_getter is invoked on every dispatcher/serializer call to resolve the live state-struct address — stable closure for globals, key-checked re-resolution for indexed widgets.

Arguments:
  • module_name : string

  • bare_ident : string

  • kind : string

  • state_addr_getter : lambda<void>

  • serializer : lambda<void>

1.2.3. Live commands

imgui_await(input: JsonValue? ): JsonValue?

Live-command: poll quiescence. Returns {quiescent, frame, pending_coroutines, active_id} — clients drive the wait loop client-side (the server runs on the GLFW thread).

Arguments:
imgui_click(input: JsonValue? ): JsonValue?

Live-command: dispatch a click to the widget named by input["target"]; resolves path or 0x... hex_id.

Arguments:
imgui_close(input: JsonValue? ): JsonValue?

Live-command: close the container named by input["target"] (window/popup/tree_node/collapsing_header/tab_item).

Arguments:
imgui_drag(input: JsonValue? ): JsonValue?

Live-command: spawn an L1 drag coroutine — press at target bbox center, walk (dx,dy) over steps frames, release.

Arguments:
imgui_focus(input: JsonValue? ): JsonValue?

Live-command: force keyboard focus onto input["target"]; the widget’s path must have been tagged via register_focusable.

Arguments:
imgui_open(input: JsonValue? ): JsonValue?

Live-command: open the container named by input["target"] (window/popup/tree_node/collapsing_header/tab_item).

Arguments:
imgui_set(input: JsonValue? ): JsonValue?

Live-command: steer the next-frame value of input["target"] to input["value"].

Arguments:
imgui_snapshot(input: JsonValue? ): JsonValue?

Live-command: return {frame, globals, io} — every registered widget joined with its per-frame entry when rendered.

Arguments:
imgui_type_text(input: JsonValue? ): JsonValue?

Live-command: spawn an L1 typing coroutine that pushes text to whichever widget currently holds focus.

Arguments:

1.2.4. Uncategorized

JV(value: TextFilterState ): JsonValue?

def JV (value: TextFilterState) : JsonValue?

Arguments:
serialize(arch: Archive; value: TextFilterState )

def serialize (var arch: Archive; var value: TextFilterState)

Arguments:
id_to_path(hid: uint ): string

Resolve a raw ImGui hex_id to its boost path_key, or "" when unmapped.

Arguments:
  • hid : uint

id_to_bbox(hid: uint ): float4

Per-frame hex_id → bbox lookup; returns float4(0) when the id didn’t render this frame.

Arguments:
  • hid : uint

container_path_push(widget_ident: string )

Append widget_ident to the open-container chain; emitted by the [container] macro prelude.

Arguments:
  • widget_ident : string

container_path_pop()

Pop the tail container ident off the open-container chain; idempotent on empty.

widget_path_key(widget_ident: string ): string

Build a leaf widget’s registry key: open container chain ("/"-joined) + widget_ident; bare ident when unnested.

Arguments:
  • widget_ident : string

container_path_key(): string

Registry/dispatcher key for the currently-open container’s own entry.

register_end_of_frame_hook(name: string; hook: function<():void> )

Register a per-frame painter fired by end_of_frame; re-registering the same name replaces, so live-reload doesn’t multiply hooks.

Arguments:
  • name : string

  • hook : function<void>

end_of_frame()

Per-frame painter drain — invokes every hook registered via register_end_of_frame_hook. Call after rendering all widgets.

register_post_command_hook(name: string; hook: function<(command:string;target:string):void> )

Register a hook fired after every successful imgui_* command with (command_name, resolved_target); same name-keyed idempotent semantics as register_end_of_frame_hook.

Arguments:
  • name : string

  • hook : function<(command:string;target:string):void>

advance_coroutines()

Step every active L1 input coroutine one frame; finished coroutines drop out. Must run between ImGui_ImplGlfw_NewFrame() and NewFrame() so synthetic events aren’t clobbered by the GLFW backend.

spawn_coroutine(c: Coroutine )

Schedule an L1 input coroutine (one event per frame); advance_coroutines drains it.

Arguments:
widget_prelude(widget_ident: string )

Top-of-body helper for [widget] macros: PushID(widget_ident) and apply any pending imgui_focus request.

Arguments:
  • widget_ident : string

register_focusable(widget_ident: string )

Tag this widget’s path as accepting keyboard focus; called from interactive finalize helpers so imgui_focus accepts the target.

Arguments:
  • widget_ident : string

clear_module_widgets(module_name: string )

Drop every widget tagged with this module from the long-lived registries (g_widgets / id_to_path / focusable / pending_focus); called from each module’s [init] so hot-reload re-binds cleanly.

Arguments:
  • module_name : string

widget_registered(path: string ): bool

Idempotency probe used by indexed-form wrappers — true when path is already in g_widgets.

Arguments:
  • path : string

lookup_state_addr(path: string ): void?

Resolve a widget’s current state-struct address by path — invokes the registered state_addr_getter so indexed-form widgets reinterpret the live table slot on every call instead of dereferencing a stale capture. Returns null when path is absent from g_widgets or the getter reports the slot is gone (erased indexed key). Uses ?[] safe lookup so the finalize lambdas can run from inside an imgui_snapshot iteration without tripping the locked-table guard (tab[k] is daslang’s auto-insert form).

Arguments:
  • path : string

widget_finalize(widget_ident: string; kind: string; entry: WidgetEntry; serializer: lambda<():void>; dispatcher: lambda<(action:string;payload:JsonValue?):void> )

Bottom-of-body helper for [widget] macros: capture bbox/hover/active/focus, install the per-widget serializer + dispatcher, and PopID.

Arguments:
  • widget_ident : string

  • kind : string

  • entry : WidgetEntry

  • serializer : lambda<void>

  • dispatcher : lambda<(action:string;payload: JsonValue?):void>

container_finalize(widget_ident: string; kind: string; entry: WidgetEntry; serializer: lambda<():void>; dispatcher: lambda<(action:string;payload:JsonValue?):void> )

Container counterpart of widget_finalize; install the per-container serializer + dispatcher at the cached container path key.

Arguments:
  • widget_ident : string

  • kind : string

  • entry : WidgetEntry

  • serializer : lambda<void>

  • dispatcher : lambda<(action:string;payload: JsonValue?):void>

imgui_dock(input: JsonValue? ): JsonValue?

Live-command: re-dock the dock_window named by input["target"] into the dock node id supplied in input["value"] (a uint from a DockBuilder* call). Routes through SetNextWindowDockID on the next frame.

Arguments:
imgui_undock(input: JsonValue? ): JsonValue?

Live-command: undock the dock_window named by input["target"]; the window becomes free-floating. Routes through SetNextWindowDockID(0) on the next frame.

Arguments:
imgui_dock_reset(input: JsonValue? ): JsonValue?

Live-command: reset the dockspace named by input["target"] — clears the DockBuilder node tree and flips state.has_initial_layout back to false so the user’s setup function re-runs on the next frame.

Arguments:
imgui_set_window_pos(input: JsonValue? ): JsonValue?

Live-command: reposition the dock_window named by input["target"]. value is a JSON object with required x/y and optional w/h. Routes through SetNextWindowPos / SetNextWindowSize on the next frame; useful for placing a window after imgui_undock (the floating-window default location is implementation-defined) or for scripted layouts.

Arguments:
widget_rect(target: string ): tuple<bool;float4>

Resolve a target string (path or 0x... hex_id) to its last-known bbox (x0,y0,x1,y1); returns (false, float4(0)) on miss.

Arguments:
  • target : string

active_widget_path(): string

Path of the currently active/focused boost-wrapped widget, or "" when none.

pending_value_container_finalize(widget_ident: string; kind: string; state: auto ): auto

Container-side install of the pending_value dispatcher (imgui_set); used by layout containers like split_h / dock_left.

Arguments:
  • widget_ident : string

  • kind : string

  • state : auto

pending_value_finalize(widget_ident: string; kind: string; state: auto ): auto

Generic serializer + imgui_set dispatcher install for any state struct with has_pending/pending_value/changed; covers Drag/Slider/Input-numeric/Color/Combo/ListBox.

Arguments:
  • widget_ident : string

  • kind : string

  • state : auto

state_jv(path: string; t: type<auto(T) const> ): JsonValue?

Safe serializer-side helper for [widget] finalize lambdas — resolves the live state-struct address at path and returns JV(state). Returns null when the slot is gone (erased indexed key) so the snapshot reports the widget without a payload instead of dereferencing a stale capture. Pair with with_state on the dispatcher side; together they let custom-widget finalize helpers stay free of unsafe / reinterpret.

Arguments:
  • path : string

  • t : auto(T)

with_state(path: string; t: type<auto(T) const>; blk: block<(var s:T&):void> ): auto

Safe dispatcher-side helper for [widget] finalize lambdas — resolves the live state-struct address at path and invokes blk with a mutable reference to the state. No-op when the slot is gone (erased indexed key). The block body looks like a plain state.field = ... mutation; the unsafe / reinterpret cast is hidden in this helper.

Arguments:
  • path : string

  • t : auto(T)

  • blk : block<(s:T&):void>

JV(r: $Result(type<auto(TT)>,type<auto(EE)>) ): JsonValue?

Wire format for Result<T, E>: {"ok": bool, "value"|"error": ...}; the transport contract every imgui_* handler returns.

Arguments:
  • r : typemacro