Skip to main content

Crate kui_ffi

Crate kui_ffi 

Source
Expand description

C API for kui: a cdylib plus include/kui.h, and CExtension for loading a C plugin into a Rust host.

kui splits a UI into a model that lays out and paints into a display list (kui-core), a renderer (kui-wgpu) and a windowed runner (kui-native). This crate puts the model, and optionally the runner, behind a flat C ABI: every pub extern "C" fn here is a kui_* symbol declared in include/kui.h, and the Kui* structs are the repr(C) mirrors the header declares field for field.

Two kinds of program use it:

  • A C, C++ or other-language host links the cdylib (libkui_ffi) and includes kui.h. It either hands a window to kui_run and builds its view in a callback, or owns its own event loop and renderer: it feeds input with kui_input_*, builds a frame between kui_frame_begin and kui_frame_finish, polls kui_poll_event and draws kui_draw_data.
  • A Rust host running kui-native loads a C shared library as a guest extension through CExtension: the plugin draws into a slot the host declares and gets its own events back.

The C programs under examples/c/ in the repository are working references for every call below.

§Conventions

  • Strings cross as KuiStr, a (ptr, len) pair of UTF-8 bytes that is never NUL-terminated (KUI_STR("literal") in C). Invalid UTF-8 is replaced. A string the library hands back is borrowed until the next call of the same function on that context.
  • Values. A KuiValue from a kui_value_* constructor is yours until you pass it to a function documented as consuming it (an on_click payload, the value given to kui_value_map_set); free anything else with kui_value_free. The payload on a polled event is borrowed until the next kui_poll_event.
  • Panics never cross. Every entry point catches panics and returns its failure value instead (false, 0 or NULL). A NULL context is answered the same way.
  • ABI handshake. Call kui_abi_version first and compare it for equality with the header’s KUI_ABI_VERSION (see KUI_ABI_VERSION). Structs the library writes into your memory lead with a size you set from sizeof (the KUI_*_INIT initializers do), and the library writes no further than that.
  • Coordinates are logical pixels; draw data comes back in physical pixels at the frame’s scale.

§A host’s frame loop in C

The shape without kui_run: the calls a host makes around a window and renderer of its own (the same calls work headless, which is how the C examples test themselves).

#include "kui.h"

if (kui_abi_version() != KUI_ABI_VERSION) return 1;
KuiCtx *ctx = kui_ctx_new();
long long count = 0;

for (;;) {
    /* Input from the windowing library, in logical pixels. */
    kui_input_cursor(ctx, mouse_x, mouse_y);
    if (clicked) { kui_input_mouse(ctx, true, 1); kui_input_mouse(ctx, false, 1); }

    /* What the UI emitted; a payload is borrowed until the next poll. */
    KuiEvent ev = KUI_EVENT_INIT;
    while (kui_poll_event(ctx, &ev)) {
        const KuiValue *kind = kui_value_get(ev.payload, KUI_STR("kind"));
        KuiStr s;
        if (kind && kui_value_as_str(kind, &s) && kui_str_eq(s, "inc")) count++;
    }

    /* Build the frame from scratch. */
    kui_set_time(ctx, now_seconds());
    kui_frame_begin(ctx, width, height, scale);
    KuiTheme t = KUI_THEME_INIT;
    kui_theme(ctx, &t);
    KuiSpec root = {.width = {KUI_GROW, 1}, .height = {KUI_GROW, 1},
                    .main_align = KUI_CENTER, .cross_align = KUI_CENTER, .bg = t.bg};
    kui_root(ctx, &root);
    char buf[32];
    snprintf(buf, sizeof buf, "%lld", count);
    KuiTextStyle big = {.size = 56};
    kui_text(ctx, KUI_STR(buf), &big);
    KuiValue *inc = kui_value_map();
    kui_value_map_set(inc, KUI_STR("kind"), kui_value_str(KUI_STR("inc")));
    kui_button(ctx, KUI_STR("+1"), inc); /* consumes inc */
    kui_frame_finish(ctx);

    /* Draw it: one quad list, physical pixels, plus the glyph atlas to mirror. */
    KuiDrawData dd = KUI_DRAW_DATA_INIT;
    if (kui_draw_data(ctx, &dd)) {
        if (dd.atlas_dirty) upload_atlas(dd.atlas_pixels, dd.atlas_size);
        draw_quads(dd.quads, dd.quad_count, dd.clips);
    }
    if (!kui_animating(ctx)) wait_for_input();
}
kui_ctx_free(ctx);

With the runner feature, kui_run(title, view, on_event, user) does all of this around a window of its own and calls view once per frame with a context to build into; examples/c/apps/counter.c is that program.

§A C extension in a Rust app

A plugin is a shared library exporting kui_ext_abi and kui_ext_view (and optionally kui_ext_name, kui_ext_init, kui_ext_slots, kui_ext_on_event, kui_ext_free); examples/c/features/slots/panel.c is one. The host loads it and declares where it draws:

use kui_ffi::CExtension;
use kui_native::{App, NodeSpec, Ui};

struct Host;

impl App for Host {
    fn view(&mut self, ui: &mut Ui<'_>) {
        ui.open(NodeSpec::row().fill());
        // The plugin fills this position: `todos` is the namespace the
        // host loaded it under, `panel` a slot the plugin lists.
        ui.slot("todos/panel");
        ui.close();
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // SAFETY: the plugin's code runs in this process. Loading it is
    // trusting it as much as linking it would be.
    let ext = unsafe { CExtension::open("target/debug/panel.so")? };
    kui_native::app("host").extension_as("todos", ext).run(Host)
}

§Where to look

Everything is exported flat at the crate root. By job:

§Features

  • runner (on by default): kui_run and kui_run_with, the windowed runner from kui-native. A host that owns its own window and renderer builds with --no-default-features and ships less than half the library.

The book: https://kui-book.qxuken.dev. Repository: https://github.com/qxuken/kui (design records live under docs/adr there).

Structs§

CExtension
A C shared library loaded as a guest extension of a Rust host.
KuiAccessNode
One node of the access tree (kui_access_tree): what assistive technology sees. role is KUI_ROLE_, flags KUI_ACCESS_HAS_ / FOCUSED / CHECKED bits saying which optional fields hold, actions the KUI_ACCESS_* bits the node accepts through kui_input_access. Strings are borrowed until the next kui_access_tree on the context.
KuiAccessRun
One laid-out run of an editor’s text (kui_access_runs): what a screen reader reads by character and word. text ends with "\n" (counted as a zero-width character) when the line continues into another. Character positions are relative to x. Arrays and strings are borrowed until the next kui_access_tree / kui_access_runs on the context.
KuiAnnouncement
One queued announcement (kui_take_announcements): something to say once, with no node behind it. live is KUI_LIVE_POLITE or KUI_LIVE_ASSERTIVE — never KUI_LIVE_OFF, which kui_announce drops. text borrows the context’s buffer and stays valid until the next kui_take_announcements on the same context.
KuiAudio
What a kui_audio node declares; read literally (KUI_AUDIO_INIT).
KuiAudioCommand
One audio command for a host that drives its own device (kui_take_audio_commands); kind is KUI_AUDIO_* and says which of the other fields mean anything.
KuiCaretRect
A caret rect (kui_caret_rect): logical px in viewport coordinates, zero wide, one line tall.
KuiCell
One cell of a kui_cells grid: a Unicode scalar, colours as 0xRRGGBBAA (a bg of 0 is none), KUI_CELL_* attribute bits. Travels as an array, so a change here is an ABI bump.
KuiClip
One clip a frame’s quads name, in physical pixels. Mirrors kui_core::Clip, so KuiDrawData::clips is a cast and not a copy.
KuiColorOp
One step of a derived colour token’s recipe as kui_tokens_derive reads it: the verb as one of the KUI_OP_* numbers, the number it takes, and (for KUI_OP_MIX and KUI_OP_READABLE only) the colour token or role the verb names, empty otherwise. Array-carried, so an append here is an ABI bump.
KuiColorToken
One colour token as kui_tokens_set reads it: a name and a value per base, 0xRRGGBBAA each (the same value twice for a colour that does not follow the appearance). Travels as an array, so an append here is an ABI bump.
KuiCtx
The opaque context every kui_* call takes: a core plus its pending event queue.
KuiDerivedToken
One derived colour token: a name, the colour token or theme role it derives from, and its chain of ops in order (none for an alias). Array-carried like KuiColorToken.
KuiDrawData
The finished frame’s draw list, as kui_draw_data writes it: the quads, the clips they index, the glyph atlas to mirror as a texture, and the side lists for fragments and texture-backed images.
KuiEnter
Where a node starts the first frame it is seen (KuiSpec.enter): the slots set names ease in from these values over transition_ms instead of snapping. A zeroed struct is no entrance.
KuiEvent
One event from the UI, as kui_poll_event writes it and kui_run’s on_event receives it.
KuiFileDialog
The dialog kui_request_files asks for. Zeroed, it is an Open dialog for one file of any type.
KuiFileFilter
One entry of a dialog’s file-type menu.
KuiFragmentDraw
One KUI_QUAD_FRAGMENT’s draw, addressed by that quad’s uv[0].
KuiGradient
A box’s gradient (KuiSpec.gradient, docs/adr/0042-a-gradient-is-an-image-the-core-paints.md): linear along angle — turns clockwise from east, in the box’s unit square — or radial out from (at_x, at_y), fractions of the box, to its farthest corner. stops_len stops, two or more.
KuiGradientStop
One stop of a KuiGradient: a colour and where along the gradient it sits, 0..1 — or a negative at for a stop spaced evenly between its neighbours that have one.
KuiKeyframe
One keyframe stop (KuiSpec.keyframes): a zeroed stop sets nothing. set says which fields count, so 0 stays a legal value for each.
KuiLayoutRect
The rect a node was laid out at (kui_layout_of): logical px in viewport coordinates, the layout event’s numbers without the event.
KuiLengthToken
One length token: a name and logical px, before the scale factor. Array-carried like KuiColorToken.
KuiMenu
One menu of the application menu bar (kui_menu_bar), read while the call runs; the core copies what it needs.
KuiMenuAction
What choosing a context-menu row left for the host (kui_take_menu_action): the clipboard, which is the host’s in this library. KUI_MENU_ACTION_SET_CLIPBOARD carries the text to put there; KUI_MENU_ACTION_PASTE carries nothing and asks for what is there, which the host delivers back with kui_input_paste (or kui_input_commit); KUI_MENU_ACTION_SET_CLIPBOARD_SECRET carries a secret to put there marked concealed and transient.
KuiMenuItem
One row of a menu (kui_open_menu, kui_menu_bar, kui_select), read while the call runs.
KuiMetrics
The sizes the stock widgets are built from (kui_metrics, kui_metrics_set), in logical px before the scale factor: kui_core::schema::METRIC_ROLES field for field, in that order. An append here bumps KUI_ABI_VERSION.
KuiPlay
Options for kui_play. NULL means defaults; a given struct is read literally (so volume must be set — KUI_PLAY_INIT in kui.h does).
KuiQuad
One quad of a frame’s draw list, in physical pixels: a rounded rectangle, border, shadow, glyph, image or segment, told apart by kind. A renderer draws them in order, every one with the same instanced pipeline; KuiDrawData hands out the array.
KuiReplySink
Where a kui_reply from inside kui_ext_on_event sends its value: an opaque handle the library puts on the event for the callback and takes back when it returns. Never allocate, dereference or store one.
KuiRunConfig
How kui_run_with opens its window: the options a Rust host’s Launcher has, as one struct. Read literally, so start from KUI_RUN_CONFIG_INIT (every zero) or pass NULL for exactly that: a 960x640 native window, unbounded, antialiasing chosen by the GPU, diagnostics as the build has them.
KuiScrollGeometry
What the last layout resolved for a scroll container (kui_scroll_geometry): its own box, its content size and the clamped offset, all logical px in viewport coordinates.
KuiSizing
One axis of a node’s size: a KUI_* tag and its value.
KuiSpan
One styled run of a rich-text paragraph (kui_rich_text, kui_measure_rich_text): its text and what differs from the base style. Travels as an array, so an append here is an ABI bump.
KuiSpec
Everything a box node is built from: size, layout, paint, behaviour tags and accessibility, as the kui_open* family and the stock widgets read it.
KuiStr
A borrowed string: len bytes of UTF-8 at ptr, not NUL-terminated.
KuiSystemFont
One installed or loaded font family (kui_system_fonts), as the font database read its faces. family and weights are borrowed until the next kui_system_fonts on the same context.
KuiTextHit
Where a point landed in the text a keyed node drew (kui_text_hit): a byte offset into that text, across the node’s text runs in order, and the visual (wrapped) line it is on.
KuiTextMetrics
What a piece of text measures (kui_measure_text), logical px at the scale of the current or last frame.
KuiTextStyle
How a run of text is set: size, line height, colour, family or font, wrapping and decoration. A zeroed struct is the default style at size 0, so set at least size; NULL where a style pointer is taken is the default style.
KuiTextureDraw
One KUI_QUAD_TEXTURE’s draw, addressed by that quad’s uv[0].
KuiTheme
The palette a frame paints with: one 0xRRGGBBAA per role, derived from what the host reported through kui_env_set_system unless it pinned something else. Written by kui_theme ([out], so start from KUI_THEME_INIT) and read whole by kui_theme_set ([in]).
KuiValue
An opaque dynamic value: null, bool, int, float, string, list or map.
KuiWarning
One diagnostic (kui_take_warnings): a silent misconfiguration the core noticed. code is stable (grow-weight-ignored, transition-auto-key, duplicate-key); the strings are borrowed until the next kui_take_warnings on the same context.
KuiWindowCommand
One window command (kui_take_window_command): what a chrome node asked for, or what the declared window set’s diff decided. Plain data (an Open carries no title; the window’s first frame declares one through kui_window_title), so nothing borrowed enters a host’s drain loop. An [out] struct: start from KUI_WINDOW_COMMAND_INIT.
KuiWindowConfig
What a declared window is (kui_window_declare), and what an Open command carries back out inside KuiWindowCommand. Read literally, so start from KUI_WINDOW_CONFIG_INIT (a normal, activating 640x480 window) or pass NULL for exactly that.

Constants§

KUI_ABI_VERSION
The ABI this build implements, returned by kui_abi_version.
KUI_ACCESS_CHECKED
KUI_ACCESS_CHECKED_SET
KUI_ACCESS_DISABLED
The node is disabled: inert, not a Tab stop (bit 9 is KUI_ACCESS_HAS_TEXT_SELECTION).
KUI_ACCESS_EXPANDED
KUI_ACCESS_EXPANDED_SET
The node expands, and whether it is open (see KuiSpec.expanded).
KUI_ACCESS_FOCUSED
KUI_ACCESS_HAS_MAX
KUI_ACCESS_HAS_MIN
KUI_ACCESS_HAS_NUMBER
KUI_ACCESS_HAS_POS_IN_SET
pos_in_set holds (on an item), set_size holds (on its container).
KUI_ACCESS_HAS_SCROLL
KUI_ACCESS_HAS_SELECTION
KUI_ACCESS_HAS_SET_SIZE
KUI_ACCESS_HAS_TEXT_SELECTION
KUI_ACCESS_HAS_VALUE
KUI_ACCESS_LIVE_ASSERTIVE
KUI_ACCESS_LIVE_POLITE
The node declared live (see KuiSpec.live), and which politeness. Two bits rather than a field, because KuiAccessNode is an array the host allocates and appending to it would be an ABI break.
KUI_ACCESS_MIXED
A checkbox that is neither on nor off (KuiSpec.mixed); set beside KUI_ACCESS_CHECKED_SET, whose KUI_ACCESS_CHECKED it outranks.
KUI_ACCESS_MODAL
The node is the frame’s modal surface (aria-modal): focus and input are confined to it.
KUI_ACCESS_SELECTED
KUI_ACCESS_SELECTED_SET
The node has a selected state at all, and what it is: every KUI_ROLE_TAB, and a row or link the view marked (see KuiSpec.selected).
KUI_AUDIO_MASTER_VOLUME
KUI_AUDIO_PAUSE
KUI_AUDIO_PLAY
KUI_AUDIO_*: a KuiAudioCommand.kind.
KUI_AUDIO_RESUME
KUI_AUDIO_SET_VOLUME
KUI_AUDIO_STOP
KUI_AUDIO_UNLOAD
KUI_BUTTONS_MIDDLE
KUI_BUTTONS_OTHER
KUI_BUTTONS_SECONDARY
KUI_BUTTONS_*: the buttons KuiSpec.on_button claims (KuiSpec.buttons); none set is all three.
KUI_CHROME_BORDERLESS
KUI_CHROME_BORDERLESS: no decorations and no chrome expectations.
KUI_CHROME_CUSTOM
KUI_CHROME_CUSTOM: undecorated; the view draws a kui_titlebar and the runner synthesizes edge resizing and double-click maximize.
KUI_CHROME_NATIVE
KUI_CHROME_NATIVE: the OS’s decorations.
KUI_CMD_CLOSE
KUI_CMD_FOCUS
KUI_CMD_MINIMIZE
KUI_CMD_OPEN
KUI_CMD_OPEN: the declared set gained a window; config says what.
KUI_CMD_REDRAW
KUI_CMD_REDRAW: draw window again, because another window’s input changed what it shows. A host that redraws every window on every event may ignore it.
KUI_CMD_SET_SIZE
KUI_CMD_SET_SIZE: the app asked for a size (kui_set_window_size); width/height carry it. KUI_CMD_FOCUS: it asked for focus.
KUI_CMD_START_DRAG
KUI_CMD_START_DRAG, KUI_CMD_CLOSE, KUI_CMD_MINIMIZE, KUI_CMD_TOGGLE_MAXIMIZE: the verbs chrome nodes issue.
KUI_CMD_TOGGLE_MAXIMIZE
KUI_COPY_ASKED
KUI_COPY_NOTHING
KUI_COPY_READY
KUI_COPY_*: what kui_request_copy returns.
KUI_DIAG_DEFAULT
KUI_DIAG_DEFAULT: the build’s — on in debug, off in release.
KUI_DIAG_OFF
KUI_DIAG_OFF.
KUI_DIAG_ON
KUI_DIAG_ON.
KUI_DISMISS_ESCAPE
KUI_DISMISS_OUTSIDE
KUI_DISMISS_OUTSIDE, KUI_DISMISS_ESCAPE: why a window was asked to go away (kui_window_dismissed).
KUI_EDIT_AUTOFOCUS
KUI_EDIT_KEYS
KUI_KEY_*: the editing keys kui_input_key takes, in the header’s order — which is not EditKey’s declaration order, so the table is the pin rather than a cast. edit_key_of reads it and mod abi_parity emits it.
KUI_EDIT_MULTILINE
KUI_EDIT_*: the flags kui_text_edit takes. WRAP is the wrap row declared on a field (the mode is KuiTextStyle.wrap, whose zero is KUI_WRAP_WORD, so the style alone cannot say): the field folds to its width the way a document does and keeps a field’s keyboard.
KUI_EDIT_WRAP
KUI_ENTER_BG
KUI_ENTER_HEIGHT
KUI_ENTER_OFFSET
KUI_ENTER_OPACITY
KUI_ENTER_RADIUS
KUI_ENTER_WIDTH
KUI_EXPANDED_COLLAPSED
KUI_EXPANDED_* is the position in schema::EXPANDED plus one (0 = unset: the node does not expand).
KUI_EXPANDED_EXPANDED
KUI_FILE_DIALOG_FOLDER
KUI_FILE_DIALOG_FOLDER: a folder, or several.
KUI_FILE_DIALOG_OPEN
KUI_FILE_DIALOG_OPEN: an existing file, or several.
KUI_FILE_DIALOG_SAVE
KUI_FILE_DIALOG_SAVE: a path to write.
KUI_FLOAT_NONE
Which of a KuiEnter’s fields are set (its set bits); 0 = no entrance. KuiSpec.float_mode: in flow, or which rect the float attaches to. The non-zero values are kui_core::FLOAT_PRESETS indices plus one, so zero can still mean “no float”.
KUI_FLOAT_PARENT
KUI_FLOAT_VIEWPORT
KUI_FRAGMENT_IMAGE_ATLAS
KuiFragmentDraw::image_source: the image is in the atlas.
KUI_FRAGMENT_IMAGE_NONE
KuiFragmentDraw::image_source: no image.
KUI_FRAGMENT_IMAGE_TEXTURE
KuiFragmentDraw::image_source: the image has a texture of its own.
KUI_FRAME_CAUSE_ACCESS
KUI_FRAME_CAUSE_AFTER_FRAME
KUI_FRAME_CAUSE_APPEARANCE
KUI_FRAME_CAUSE_AUDIO
KUI_FRAME_CAUSE_BUTTON
KUI_FRAME_CAUSE_CARET
KUI_FRAME_CAUSE_DEVICE
KUI_FRAME_CAUSE_ELSEWHERE
KUI_FRAME_CAUSE_FILES
KUI_FRAME_CAUSE_FILE_DRAG
KUI_FRAME_CAUSE_FIRST
KUI_FRAME_CAUSE_FOCUS
KUI_FRAME_CAUSE_HOST
KUI_FRAME_CAUSE_KEY
KUI_FRAME_CAUSE_MENU
KUI_FRAME_CAUSE_MODIFIERS
KUI_FRAME_CAUSE_OCCLUSION
KUI_FRAME_CAUSE_OVERDUE
KUI_FRAME_CAUSE_OWED
KUI_FRAME_CAUSE_POINTER_LEAVE
KUI_FRAME_CAUSE_POINTER_MOVE
KUI_FRAME_CAUSE_*: the bits of what kui_frame_cause returns and kui_note_frame_cause takes.
KUI_FRAME_CAUSE_PREEDIT
KUI_FRAME_CAUSE_RESIZE
KUI_FRAME_CAUSE_RETRY
KUI_FRAME_CAUSE_SCALE
KUI_FRAME_CAUSE_SMOKE
KUI_FRAME_CAUSE_TEXT
KUI_FRAME_CAUSE_WAKE
KUI_FRAME_CAUSE_WHEEL
KUI_GRADIENT_LINEAR
KuiGradient.kind: along a line, or out from a centre.
KUI_GRADIENT_RADIAL
KUI_KF_AT
Which of a KuiKeyframe’s fields are set (its set bits).
KUI_KF_BG
KUI_KF_HEIGHT
KUI_KF_OPACITY
KUI_KF_RADIUS
KUI_KF_WIDTH
KUI_KLAYOUT_NONLATIN
KUI_KLAYOUT_NONLATIN: the press was typed on a layout that writes no Latin, so the US key stands in for its ASCII too. Zero judges each key by itself.
KUI_KLOCK_CAPS
KUI_KLOCK_* and KUI_KLOC_*: which lock keys were on and which of a key’s twins it was, in the same word as the KUI_KMOD_* bits kui_input_key_down and its siblings take. Zero is no lock on and the standard key.
KUI_KLOCK_NUM
KUI_KLOC_LEFT
KUI_KLOC_NUMPAD
KUI_KLOC_RIGHT
KUI_KMOD_ALT
KUI_KMOD_CTRL
KUI_KMOD_SHIFT
KUI_KMOD_*: the modifier bits kui_input_key_down and its siblings take, and kui_input_modifiers reports — the core’s own KeyMods::bits, which is also what the conformance corpus’s modifiers step spells, so the header and the corpus cannot drift.
KUI_KMOD_SUPER
KUI_LIVE_ASSERTIVE
KUI_LIVE_OFF
KUI_LIVE_* is the position in schema::LIVE itself, not the position plus one: unlike a disclosure, a live region’s zero is a value — “not a live region” is what an unset field already means, so there is no unset state to reserve zero for.
KUI_LIVE_POLITE
KUI_MENU_ACTION_LOOK_UP
KUI_MENU_ACTION_PASTE
KUI_MENU_ACTION_SET_CLIPBOARD
KUI_MENU_ACTION_*: a KuiMenuAction.kind.
KUI_MENU_ACTION_SET_CLIPBOARD_SECRET
A secret for the clipboard, to write marked concealed and transient (kui_set_clipboard_secret). A host that does not know the kind drops the copy, which for a secret is the safe way to fail.
KUI_MENU_COPY
KUI_MENU_CUSTOM
KUI_MENU_*: a KuiMenuItem.role, the position in MenuRole::ALL.
KUI_MENU_CUT
KUI_MENU_ITEM_CHECKED
KUI_MENU_ITEM_ENABLED
KUI_MENU_ITEM_*: the flags kui_menu_bar_item and kui_menu_item report on a row.
KUI_MENU_ITEM_SUBMENU
KUI_MENU_ITEM_SUBMENU: the row opens rows of its own (backlog F128).
KUI_MENU_LOOK_UP
KUI_MENU_PASTE
KUI_MENU_SELECT_ALL
KUI_MENU_SEPARATOR
KUI_MIN_FIT
KuiSpec.min_w / min_h as the node’s own fit size (KUI_MIN_FIT).
KUI_MIN_NONE
KuiSpec.min_w / min_h as a declared floor of 0: no floor at all, not even the content’s that a share in an overflowing row gets for an undeclared (0) one; CSS’s min-width: 0.
KUI_MOD_DOC
KUI_MOD_SHIFT
KUI_MOD_*: the editing modifiers kui_input_key takes — extend the selection, move by word, move by document.
KUI_MOD_WORD
KUI_MOUSE_MIDDLE
KUI_MOUSE_OTHER
KUI_MOUSE_PRIMARY
KUI_MOUSE_*: kui_input_mouse_button’s button, which is MouseButton::code — the core owns the numbering, this is its name.
KUI_MOUSE_SECONDARY
KUI_OPTION_AS_ALT_BOTH
KUI_OPTION_AS_ALT_LEFT
KUI_OPTION_AS_ALT_NONE
KUI_OPTION_AS_ALT_NONE, _LEFT, _RIGHT, _BOTH: which Option keys act as Alt on macOS (kui_set_option_as_alt).
KUI_OPTION_AS_ALT_RIGHT
KUI_OP_ALPHA
KUI_OP_DARKEN
KUI_OP_LIFT
The verbs of KuiColorOp.op, numbered as kui_core::ColorOp::VERBS lists them.
KUI_OP_MIX
KUI_OP_RAISE
KUI_OP_READABLE
KUI_ORIENTATION_HORIZONTAL
KUI_ORIENTATION_* is the position in Orientation::ALL plus one (0 = unset: the node is not a composite container).
KUI_ORIENTATION_VERTICAL
KUI_OVERSCROLL_AUTO
KUI_OVERSCROLL_* is the position in schema::OVERSCROLLS plus one (0 = unset, which is auto).
KUI_OVERSCROLL_CONTAIN
KUI_OWED_AUTOSCROLL
KUI_OWED_CYCLE
KUI_OWED_DEPART
KUI_OWED_REQUESTED
KUI_OWED_SCROLL
KUI_OWED_TRANSITION
KUI_OWED_*: the bits of what kui_owed returns, kui_animating by kind.
KUI_PASTE_CONCEALED
KUI_PASTE_*: the pasteboard’s markers on a paste’s answer (kui_input_paste).
KUI_PASTE_TRANSIENT
KUI_SCROLLBAR_AUTO
KUI_SCROLLBAR_HIDDEN
KUI_SCROLLBAR_VISIBLE
KUI_SCROLLBAR_* is the position in schema::SCROLLBARS plus one (0 = unset, which is the stock visible bar).
KUI_SCROLL_AXES_BOTH
KUI_SCROLL_AXES_* is the position in schema::SCROLL_AXES plus one (0 = unset, which is both).
KUI_SCROLL_AXES_X
KUI_SCROLL_AXES_Y
KUI_SPAN_BOLD
KUI_SPAN_*: the flags on a KuiSpan.
KUI_SPAN_FAMILY
KUI_SPAN_FAMILY: KuiSpan.family names the span’s face (ABI 26).
KUI_SPAN_ITALIC
KUI_SPAN_STRIKETHROUGH
KUI_SPAN_UNDERLINE
KUI_TEXT_AA_AUTO
KUI_TEXT_AA_AUTO: LCD subpixel coverage when the GPU can blend per channel, grayscale otherwise.
KUI_TEXT_AA_GRAYSCALE
KUI_TEXT_AA_GRAYSCALE.
KUI_TEXT_AA_SUBPIXEL
KUI_TEXT_AA_SUBPIXEL.
KUI_UNDERLINE_DOTTED
KUI_UNDERLINE_SOLID
KUI_UNDERLINE_*: an underline’s shape, KuiTextStyle.underline_style and KuiSpan.underline_style.
KUI_UNDERLINE_WAVY
KUI_VALUE_ANCHOR
KUI_VALUE_CARET
KUI_VALUE_CARET_SOLID
KUI_VALUE_MAX
KUI_VALUE_MIN
KUI_VALUE_NOW
KUI_VALUE_STEP
KuiSpec.value_step holds.
KUI_WINDOW_KIND_NORMAL
KUI_WINDOW_KIND_NORMAL: a regular top-level window.
KUI_WINDOW_KIND_POPUP
KUI_WINDOW_KIND_POPUP: a borderless, taskbar-less menu surface owned by the window that declared it, placed against anchor_* in screen coordinates and closed when its owner closes.
KUI_WINDOW_NONE
KUI_WINDOW_NONE: a KuiSpec.window_role that is no chrome role.

Functions§

kui_abi_version
The ABI version this library implements (KUI_ABI_VERSION), for a host to compare for equality with the KUI_ABI_VERSION of the header it compiled against, before its first other call.
kui_access_runs
The laid-out text of editor node key as runs (see KuiAccessRun): fills out with up to cap of them and returns the total. Runs are what KuiAccessNode.anchor_run / focus_run and kui_input_access_text refer to. Borrowed until the next kui_access_tree / kui_access_runs on the context; a node with no text (or no such node) has none.
kui_access_tree
The access tree of the last finished frame, which is what assistive technology sees: fills out with up to cap nodes in tree order (the root first) and returns the total count, so a short buffer can be resized and the call repeated. Strings stay valid until the next call on this context. A host that never asks pays nothing.
kui_activate_menu_bar_item
Reports that the platform’s menu bar chose row item of menu menu: the same path a press on the drawn bar’s row takes. Out of range does nothing. Returns whether an item was performed.
kui_activate_menu_bar_path
Reports that the platform’s menu bar chose the row at path in menu menu, inside its submenus: Core::activate_menu_bar_path. Returns whether a row was performed; a row that opens a submenu, a dead one and one not there are not.
kui_activate_menu_item
Reports that the host’s menu chose row index: the same path a press on the drawn menu’s row takes. An index past the end closes the menu and posts nothing. Returns false when nothing was taken: no menu was open, or the row cannot be chosen — disabled, or a separator — in which case the menu stays open and nothing is posted.
kui_activate_menu_path
Reports that the host’s own menu chose the row at path, inside its submenus: Core::activate_menu_path. False when nothing was taken — no menu open, an empty path, a row not there, or one that cannot be chosen (dead, a separator, or one that opens a submenu, which the host opens), the menu then left open and nothing posted.
kui_always_on_top_get
Whether the frame that just finished asked for the window on top — for hosts driving their own window: diff against the level applied and set it on change only. False for a frame that never asked, and on a bad context.
kui_animating
True when the last frame left a transition mid-flight: draw another frame without waiting for input.
kui_announce
Says something once, with no node behind it: “Saved”, “3 results”. live is KUI_LIVE_POLITE or KUI_LIVE_ASSERTIVE; KUI_LIVE_OFF and an empty string are both no-ops, the first so a caller can gate politeness without a branch. A region whose message is on screen is KuiSpec.live instead.
kui_answer_selection_range
Answers a selectionrange ask with the text for the range it named, whole. False when nothing asked — a late answer cannot overwrite what has been copied since.
kui_audio
An audio node: a playback retained by key while the frame declares it (present = playing, gone = stopped; volume/paused apply live, a changed src restarts). finish changes what gone means — the playback is released to play itself out rather than stopped, except for a loop. Empty label = a key from the tree position. tag (nullable, consumed) rides the ended event, and survives a release. Returns the node key.
kui_audio_ended
A host driving its own device reports a playback finished on its own; a tagged one becomes a sound event for kui_poll_event.
kui_audio_refused
The same host reports that its device refused a play it drained: a tagged playback becomes a sound event with phase refused for kui_poll_event, and the node that asked is named in a playback-refused warning either way.
kui_audio_truncated
The same host reports that a stop it drained landed on a playback still running, at seconds in: a one-shot audio node that went away without finish is named in a truncated-playback warning (kui_take_warnings); any other stop reports nothing.
kui_awaiting_files
Whether a file dialog asked for is still unanswered.
kui_awaiting_paste
Whether a paste asked for is still unanswered: kui_request_paste queues one ask at a time, and the kui_input_commit that answers it (an empty one for an empty clipboard) is what lets the next through.
kui_button
The stock button, labelled and keyed by label: a press by the pointer, Space, Enter or assistive technology emits payload as a click event’s payload. Consumes payload (NULL for none).
kui_button_with
kui_button with the rows the stock button admits read off spec — label, description, tooltip, disabled — and every other field ignored: the look is widgets::button_spec’s, and a zeroed KuiSpec is the schema default rather than “unset”, so there is nothing to merge. A NULL spec is kui_button. Consumes payload.
kui_caret_rect
The caret rect for byte offset byte in the text the node key drew: logical viewport px, zero wide, one line tall. A byte past the text is the end. False for a key that drew no text, a bad context or a NULL out.
kui_caret_stamp
Changes whenever the caret moved or focus changed — compare across frames to re-arm the blink with the caret solid.
kui_caret_visible
The caret’s blink phase: true draws it. A custom editor reads it in its view and skips its caret node on the off phase, keeping the caret row on its KUI_ROLE_LINE either way. Under kui_run the runner’s clock sets it; a host driving its own window sets it with kui_set_caret_visible on a clock of its own, armed while kui_has_caret and re-armed solid when kui_caret_stamp changes.
kui_cell_selection
A cells grid’s selection, the window’s when it lives in one: the grid’s key, the anchor and the focus as the drag made them — each an absolute line (originLine plus the row, so a scroll does not move it) and a column — and whether it is a block rather than linewise. False when the window’s selection is not a grid’s; a text selection’s ends are kui_selection_ends. Any out pointer may be NULL.
kui_cells
A terminal’s screen as one node: rows by cols cells from cells (fewer draw as blank), shaped once per character and placed on a fixed grid. style sizes the cells (size, family / font, line_height); spec is the node’s own (an on_key makes it the key sink, an on_click / on_drag carry cell: {row, col}), the three payloads consumed as kui_open_with consumes them; label keys the node (empty for auto). cursor_shape is KUI_CELL_CURSOR_* or 0 for none, drawn at (cursor_row, cursor_col) in cursor_color. origin_line is the absolute line row 0 is, so a selection keeps its ends across a scroll; 0 says nothing.
kui_checkbox
The stock checkbox: a box drawn from spec’s checked / mixed, labelled text and keyed by it; a press posts payload (consumed). Reads checked, mixed, label, description, tooltip and disabled off spec (NULL = none of them). Its key.
kui_child_key
The key a child labeled label of the currently open container would get.
kui_clear_selection
Drops the window’s selection, whichever kind it is; true when there was one.
kui_close
Closes the node the last kui_open* opened. Every open must be closed before kui_frame_finish.
kui_close_menu
Closes whatever menu is open; true when there was one.
kui_ctx_add_extension
Loads the shared library at path as an extension of this context, under namespace — the word that makes the front of every slot name it fills (namespace/panel). An empty namespace takes the extension’s own kui_ext_name, which is what a Rust host’s Extensions::push does.
kui_ctx_backdrop
The window’s backdrop as views read it, a KUI_BACKDROP_*: env.window.backdrop, what kui_env_set_backdrop set — and in a kui_run_with view callback what the runner got for KuiRunConfig.backdrop, the answer and not the ask. Opaque on a bad context.
kui_ctx_extension_count
How many extensions this context has loaded. Their origins are 1..=n, in the order they were added; 0 is the host’s own.
kui_ctx_extension_error
Why the last kui_ctx_add_extension on this context said false. False (and out untouched) when the last one succeeded, or when none has run. Borrowed until the next call on this context, like every other string this API hands back.
kui_ctx_extension_namespace
The namespace the extension at origin was loaded under — what turns an event’s origin back into a name the host chose. False (and out untouched) for 0 (the host) or an origin nothing was loaded at. Borrowed until the next call.
kui_ctx_free
Frees a context from kui_ctx_new, its queued events, every string it lent out and every extension it loaded. NULL is a no-op.
kui_ctx_new
Creates a standalone context: a core of its own plus an event queue.
kui_ctx_window
Which window this context draws: env.window.id, as kui_env_set_window set it — KUI_WINDOW_MAIN for the launcher’s, and in a kui_run view callback the id of the window being drawn.
kui_ctx_window_name
The name of the window this context draws: “main” for the launcher’s, else the name the declaration that opened it used. Borrowed until the next call on the same context. False only on a bad context.
kui_cursor_shape
The pointer shape for where the pointer is now (KUI_CURSOR_*, never 0): the cursor the topmost node under it declared, the I-beam over text, the arrow otherwise. A query, not a queue — read it after each input and each frame and apply it to the real window when it changes. Hosts without a pointer simply never call.
kui_devtools
Whether the devtools panel is on.
kui_devtools_current_tab
The devtools tab currently selected, by name, panel on or off; borrowed until the next call. False on a bad context.
kui_devtools_dock
Where the devtools panel sits, as a word kui_set_devtools_dock takes ("right" for the side); the string is static. False on a bad context.
kui_devtools_hovered
The tree row under the pointer, as a key, or 0.
kui_devtools_key
The chord kui_set_devtools_key set, or the default, in its portable spelling ("ctrl+shift+i", "f12", "super+alt+d"); borrowed until the next call. False on a bad context.
kui_devtools_picked
The node the picker is over while picking, as a key, or 0.
kui_devtools_picking
Whether the panel’s picker is up.
kui_devtools_selected
The node the devtools tree tab has selected, as a key, or 0 for none: what an inspector in a declared tab reads.
kui_devtools_tab
Declares a devtools tab an extension fills: name is the tab’s identity, label what the strip shows, slot the full namespace/slot the extension names. While the tab is on show the panel declares that slot in the tab’s body; otherwise the extension is not asked, and no unknown-slot is raised. Call it every frame, panel on or off. False for a name already declared this frame (duplicate-tab) or outside a frame.
kui_devtools_tab_open
Declares a devtools tab the host draws itself, and opens its content node only while the tab is on show: true means the node is open, so build inside it and kui_close; false means the tab was declared and nothing opened, so skip the body and do not close. What the host builds keeps its own keys and events, painted as a layer over the panel’s tab body and clipped to it: if (kui_devtools_tab_open(ctx, KUI_STR("syntax"), KUI_STR("Tree-sitter"))) { ...; kui_close(ctx); }.
kui_draw_data
The finished frame’s draw list, into out (start from KUI_DRAW_DATA_INIT). The pointers are valid until the next kui_frame_begin on this context; the quads are the core’s own array, not a copy.
kui_drop_target
The drop zone the dragged files are over, or 0: what a driver answers the OS with after every kui_input_drag_files (a copy cursor over a zone, not-allowed elsewhere, and a release off every zone refused).
kui_edit_set_text
Replaces the text of the editor key, as if the user had typed it; the caret moves to the end. kui_edit_set_text_label does the same for an editor the host only knows by label.
kui_edit_set_text_label
kui_edit_set_text by the label the view declares the editor with, for a host that has no key yet (an editor opened for the first time has fired no event). A label some frame declared is applied at once; one nothing has declared is held for the next frame, seeding a new editor over its initial. Held for that one frame only: if no editor is declared under it, the text is dropped with an edit-text-without-editor warning.
kui_edit_text
The current text of the editor key (kui_text_edit or kui_text_input), borrowed until the next kui_edit_text on this context or kui_ctx_free. False when key is no editor.
kui_env_set
Window facts for views to read: the display’s refresh rate (refresh_hz <= 0 is unknown) and whether the window has keyboard focus.
kui_env_set_always_on_top
The window fact for views to read as env.window.always_on_top: what the host actually did about the ask, so a pin button draws the platform’s answer and not the app’s guess. Its own setter rather than an argument on kui_env_set_window because a setter is additive where an argument is an ABI break (the kui_env_set_assistive reasoning): a host that never applies a level has nothing to recompile, and reports false by never calling.
kui_env_set_assistive
Whether assistive technology is listening, for views to read: a KUI_ASSISTIVE_* (0 is unknown, which is what a host with no accessibility bridge reports by never calling this).
kui_env_set_audio
What the host’s audio output is doing, for views to read: device a KUI_AUDIO_DEVICE_* (0 is closed, which a host with no device reports by never calling this) and live the number of playbacks started or waiting on the open. A fact, not a command: nothing here closes the device. An out-of-range code is ignored.
kui_env_set_backdrop
The window fact for views to read as env.window.backdrop: a KUI_BACKDROP_*, what is actually behind the window’s transparent pixels — BLUR or TINTED for the effect the host got, TRANSPARENT for a see-through surface with none, OPAQUE (0, and what a host that never calls this reports) for neither (backlog F126). A host that makes its window translucent also clears its frames to nothing rather than to the theme’s bg. Its own setter, as kui_env_set_always_on_top is. An out-of-range code is ignored.
kui_env_set_system
The OS’s settings, for views and the theme to read: appearance is a KUI_APPEARANCE_*, motion a KUI_MOTION_* (0 is unknown for both), accent the accent colour as 0xRRGGBBAA (0 is unknown) and locale a BCP-47 tag (empty is unknown; one over 31 bytes or not ASCII reads back as unknown).
kui_env_set_window
Window facts for views to read (widgets::titlebar adapts to them). window is which window this context draws — KUI_WINDOW_MAIN, or the id an Open command carried — and is what every event it hands out will say in KuiEvent.window. controls_w/h > 0 describe the keep-out rect of controls the OS draws over the content (macOS traffic lights), anchored top-left.
kui_file_request_filter
Filter i of the dialog kui_take_file_request last handed out: its name, and its extensions joined with ; ("png;jpg", no dots). Borrowed until the next call; false for a filter that is not there.
kui_focus
Moves keyboard focus to key now (0 blurs). For focus that follows a declaration rather than a moment, kui_set_key_focus.
kui_focus_next
What Tab (forward) / Shift-Tab does: focus the next / previous focusable node in tree order, wrapping. A key sink that binds Tab itself calls this to hand the keyboard on.
kui_focus_region
Enters the focus region key names (a node declared with focus_region; 0 is the main ring) at the end of the frame being built: focus lands on what that ring last held, else its initial_focus, else its first stop.
kui_focus_visible
Whether focus got where it is by keyboard or assistive technology rather than a click — when it shows (the core’s ring, or focus_bg).
kui_focus_window
Asks the driver to give window keyboard focus; queued and drained the same way, as KUI_CMD_FOCUS. Advisory, like every focus request an app makes of a window manager: whether it was granted shows up through kui_env_set’s focused on the frames that follow, not as a reply here.
kui_focused
The node holding keyboard focus; 0 for none.
kui_font_add
Registers a font from file bytes (TTF/OTF/TTC, copied); returns its handle for KuiTextStyle.font, 0 when the data holds no usable face.
kui_font_add_system
Registers an installed font by family name; 0 when none matches.
kui_font_families
The family names kui_font_add_system can take — every face the context knows, installed or loaded, sorted and deduplicated — written into out up to cap and the total returned, so a short array can be resized and the call repeated. Strings are borrowed until the next call on this context. What Node’s systemFontFamilies() answers.
kui_font_load_dir
Loads every font file under a folder (recursively) so its families can be picked by name with kui_font_add_system; returns the face count.
kui_font_load_file
Registers a font file by path (memory-mapped); 0 when it cannot be read or holds no usable face.
kui_font_reload_system
Scans the system’s fonts again, so a font installed while the app runs is found (Core::reload_system_fonts); returns how many faces came and went, 0 when nothing did.
kui_font_remove
Forgets a registered font; text still naming it falls back to the family.
kui_font_set_fallback⚠
The families asked, in order, for a character the text’s own family has no glyph for, before the platform’s fallback list (Core::set_fallback_fonts): len font handles at ids, none (NULL or 0) for the platform’s list alone. A handle that names no font is left out. KUI_FONT_MONO text asks them straight after its own face, ahead of the machine’s other monospaced faces. A new list shapes every text again; the same list twice is nothing.
kui_fragment
A box painted by the WGSL fragment function registered as id (kui_fragment_add). It has no intrinsic size, so spec must give it one. params are count floats the function reads, NULL when count is 0; more than sixteen are dropped with a warning.
kui_fragment_add
Registers a WGSL fragment function; 0 when it does not compile, with a fragment-rejected warning carrying the message. Idempotent by source.
kui_fragment_open
kui_fragment as a parent: its children paint over it. Balance with kui_close. An empty label is the unkeyed form.
kui_fragment_open_with
kui_fragment_with as a parent: its children paint over it. Balance with kui_close.
kui_fragment_remove
Forgets a registered fragment; nodes still naming it draw nothing.
kui_fragment_source
The whole WGSL module behind a handle — the app’s source between the core’s prelude and epilogue — for a host that compiles it itself. The string is borrowed and valid until the next call; false when the handle is not live in this session.
kui_fragment_with
kui_fragment reading image through the shader’s kui_sample: an image handle from kui_image_add, or 0 for none, which is kui_fragment. label keys the node (empty for a key from the tree position); a leaf.
kui_frame_begin
Starts a frame: w by h logical pixels at device scale scale (a value of 0 or less reads as 1).
kui_frame_cause
The KUI_FRAME_CAUSE_* bits of the frame being built, or between frames the last one’s.
kui_frame_finish
Finishes the frame: lets loaded extensions fill what the view did not, lays the tree out and paints it. After it, kui_draw_data has the frame and kui_poll_event has anything the frame itself produced (a resize, a hover change under a still pointer, a layout).
kui_frame_unchanged
1 when the last finished frame drew exactly what the one before drew, 0 when not, -1 when untraced (kui_set_frame_trace) or on the first traced frame.
kui_has_caret
Whether there is a caret to blink: a focused editor’s, or the caret a line under the focused sink declares. What a host’s blink clock is armed on.
kui_host_rect
Where the last frame laid the host out in its window, in logical px: the whole window with the devtools panel off or in its own window, the pane beside the dock otherwise, and zeros before the first frame. Scaled by the frame’s scale it separates the host’s quads from the dock’s in kui_draw_data, except the root’s background, which also fills the window beneath the pane. False on a bad context, a NULL out or a short size.
kui_image
An image node. Fit sizing takes the image’s pixel size as logical px; Fit height against a resolved width keeps the aspect. radius rounds it.
kui_image_add
Registers a w×h RGBA image (pixels copied); returns its handle, 0 on failure. Draw it with kui_image; free it with kui_image_remove.
kui_image_pixels
The pixels behind an image handle, for a host that renders the draw list itself and meets a KUI_QUAD_TEXTURE quad: w, h and rgba (w×h×4 bytes) are written and true returned when the handle is live here. The bytes are borrowed and valid until the next call of this function or kui_image_update on the same handle.
kui_image_remove
Forgets a registered image; nodes still naming it draw nothing.
kui_image_update
Replaces an image’s pixels in place (copied): the handle is unchanged, so every node showing it draws the new pixels next frame; w/h may differ from the registration. From the first update on the image is drawn from a texture of its own, as a KUI_QUAD_TEXTURE quad. A dead or foreign handle warns foreign-resource and changes nothing.
kui_image_with
kui_image with its two options: sampling is KUI_SAMPLING_LINEAR (0, the default) or KUI_SAMPLING_NEAREST; fit is KUI_FIT_FILL (0, the default), KUI_FIT_CONTAIN or KUI_FIT_COVER. An index past the table reads as the default.
kui_ime_off_get
Whether the frame that just finished asked for the input method off — for hosts driving their own window. False for a frame that never asked, and on a bad context.
kui_ime_rect
Where the OS candidate window goes while a composition is under way: the focused editor’s caret, or a custom editor’s line carrying caret. False when nothing with a caret is focused. A host driving its own window reads it after each frame and hands it to the platform.
kui_input_access
A request from assistive technology on node key: one KUI_ACCESS_* action bit (the node must advertise it in KuiAccessNode.actions), with value the new text for KUI_ACCESS_SET_VALUE (empty otherwise). Resolved the way the pointer or keyboard equivalent would be: a click emits the node’s payload, focus lands on an editor, a slider nudge arrives as a {kind="access", action, tag} event.
kui_input_access_text
A text request from assistive technology on editor node key: KUI_ACCESS_SET_TEXT_SELECTION with the selection as run positions (anchor_* the end that stays, focus_* the caret), or KUI_ACCESS_REPLACE_SELECTED_TEXT / KUI_ACCESS_SET_VALUE with value. A built-in editor applies it (a changed event follows an edit); a custom editor gets it as a {kind="access", action, anchor, focus, text, tag} event to apply itself.
kui_input_commit
Text an IME committed at the end of a composition: a focused editor takes it as kui_input_text would; otherwise the focused on_key sink hears {kind:"text", text, tag}, the one committed text a key event never carries. Typing stays on kui_input_text.
kui_input_cursor
The pointer moved to (x, y) in logical pixels. Hover, drags and the cursor shape follow from it.
kui_input_cursor_left
The pointer left the window: nothing is hovered until it comes back.
kui_input_drag_cancel
The dragged files left the window, or the OS ended the drag elsewhere: the lit zone hears its leave.
kui_input_drag_files
Files dragged in from the OS are over the window at (x, y), entering and moving alike: the drop zone under the point hears {kind:"drop", phase:"enter"|"move"}, a zone it left hears leave. paths are count OS paths. The host’s answer to the OS (copy over a zone, not-allowed elsewhere) is kui_drop_target.
kui_input_drop_files
The dragged files were released at (x, y): the zone there hears {kind:"drop", phase:"drop", paths, x, y, tag} and no leave after; with no zone there, nothing but the lit zone’s leave.
kui_input_files
A file dialog’s answer: the count paths picked, none for a cancelled dialog. Whoever asked hears {kind:"files", paths, tag}; with nothing asked it is dropped.
kui_input_key
Editing key with modifier bits (1 = shift, 2 = word/alt, 4 = doc/primary).
kui_input_key_down
A raw key press for on_key sinks; most hosts want kui_input_press, which sends this and then what the key means.
kui_input_key_up
The release of a key pressed with kui_input_key_down, spelled the same way (physical included, NULL for “same as code”); the sink polls {kind="key", phase="up", ...} with a null text. A release whose press the sink never got resolves nothing, and moving focus while a key is held delivers the “up” first, so a held-key binding (WASD, press-and-hold) cannot be left stuck down.
kui_input_modifiers
Physical modifier state changed (KUI_KMOD_* bits). The host polls a {kind="modifiers", shift, ctrl, alt, super} event when it differs from the last report.
kui_input_mouse
A primary-button press (down true) or release at the last cursor position; clicks is the click count (1, or 2 for a double-click). kui_input_mouse_button carries the other buttons.
kui_input_mouse_button
kui_input_mouse for a named button (KUI_MOUSE_*, or 3 + n for a further button n).
kui_input_open
The OS asked the app to open these count documents (backlog F124): the host hears {kind:"open", paths} on the root, asked for or not; none emits nothing. A host driving its own window on macOS sends it from its app delegate’s application:openURLs:; under kui_run the runner does.
kui_input_paste
The clipboard’s answer to a paste (KUI_MENU_ACTION_PASTE), with the pasteboard’s markers as KUI_PASTE_* bits: routed as kui_input_commit is, and a focused on_key sink hears {kind:"text", text, tag} with concealed: true / transient: true for the bits that are set. A host that cannot read the markers answers with 0, or with kui_input_commit, which is the same answer.
kui_input_preedit
In-progress IME composition, shown at the focused editor’s caret, or with no editor focused delivered to the focused onKey sink as {kind:"preedit", text, cursor, tag}. Empty text clears it; the commit arrives via kui_input_commit. cursor_start/cursor_end are byte offsets into text, or UINT32_MAX for none.
kui_input_press
A whole key going down, the way a window sends it: the call a host driving kui from its own event loop wants. Spelled exactly as kui_input_key_down; it sends that raw press first, then what the key means (what kui_input_key carries on its own): Escape dismisses a modal, Tab walks the focus ring, an arrow nudges a focused slider, Space presses a focused control, a printable character reaches the focused editor.
kui_input_release
The same key coming up, spelled the way kui_input_press spells it (physical included, {NULL, 0} for “same as code”). One channel, because only one has a second half: the editing keys act on the way down, so this is kui_input_key_up under the name that pairs with kui_input_press.
kui_input_scroll
A wheel or trackpad delta in logical px (positive dy scrolls up), as a scroll gesture of its own: it goes to the innermost scroller under the pointer that can move that way.
kui_input_scroll_gesture
A wheel or trackpad delta that is part of a scroll gesture: begins on its first event, after which the rest go to the targets that one picked wherever the pointer or the content has gone. For a host whose event loop can tell one swipe from the next (kui_run begins a new gesture after a 200 ms pause).
kui_input_text
Committed text input (typing, paste); routed to the focused editor.
kui_is_drop_target
Whether files dragged in from the OS are over key, for drop-dependent layout; the colour alone is KuiSpec.drop_bg.
kui_is_focused
Whether the node key holds keyboard focus.
kui_is_hovered
Whether the pointer is over the node key, as of the last input. Only a node that is hover-tracked (a click or hover tag, hoverable, hover_bg, a tooltip or a cursor) is ever hovered.
kui_is_pressed
Whether a primary press that started on the node key is still held.
kui_key_of
The key of the node opened under label (kui_open with a label, the widgets’ label argument) in the last finished frame — or, from inside a view callback, in the frame so far and then the last one. 0 when no node declared it. The door for a host that never saw an event from the node: keys hash the path from the root, through the auto-keyed ancestors a host cannot spell, so kui_focus(ctx, kui_key_of(ctx, KUI_STR("note"))) is how “focus the editor I just declared” is said. Two nodes on one label under different parents resolve to the first in tree order and raise ambiguous-key (kui_take_warnings).
kui_latency_graph
Per-phase frame-latency bars vs the display budget. Reads the runner’s frame stats — renders empty chrome in a standalone (headless) context.
kui_latency_hud
The graph in a translucent panel floating in a viewport corner picked by KUI_START/CENTER/END attach values.
kui_layout_of
The rect the last frame laid key out at, for a node that declared on_layout: the layout event’s numbers, read back during the next build with no event. False for any other key, a bad context, a NULL out or a short size.
kui_line
A round-capped stroke from (x0, y0) to (x1, y1) in the parent’s box space, as a float sized to its bounding box. spec may be NULL. width <= 0 is 1; color 0 is the theme’s foreground, like a text style’s.
kui_measure_rich_text
kui_measure_text for a rich-text paragraph.
kui_measure_text
Measures text in style the way layout would, without adding a node: unwrapped with max_w <= 0, else wrapped to max_w logical px. Logical px at the scale of the current or last frame (1 before any frame). wrap / max_lines / ellipsis in the style apply. Returns false only for a bad context or NULL out.
kui_menu_bar
The application menu for this frame: count menus read from menus, in bar order, declared and, where the platform has no menu bar of its own, drawn into the frame right here as a row of titles that drop their menus.
kui_menu_bar_item
Reads one row of one menu: its text into label, its accelerator into accel (empty when it has none), and its role and flags through the out pointers. Both strings are borrowed until the next call on this context. False for a row that is not there.
kui_menu_bar_item_path
Reads the bar’s row at path in menu menu, spelled as kui_menu_bar_item spells one. False for a row that is not there, and for an empty path.
kui_menu_bar_menu
Reads one menu of the declaration back: its title into label and how many rows it has. Both borrowed until the next call on this context. Returns false for a menu past the end.
kui_menu_bar_menu_count
How many menus the declaration in force has, and a revision that changes only when the declaration does — a host with a native bar keeps the last number it built and rebuilds nothing until it moves. Writes the revision into revision when it is not NULL.
kui_menu_bar_submenu_count
How many rows the bar’s row at path in menu menu opens: 0 for a row with no submenu or one not there, and at a depth of 0 the menu’s own rows, as kui_menu_bar_menu counts them.
kui_menu_item
Reads row item of the open menu, spelled exactly as kui_menu_bar_item spells a bar’s row. False for a row that is not there, including when no menu is open. Answer with kui_activate_menu_item or kui_close_menu.
kui_menu_item_count
The menu this window has open, for a host that said it shows menus itself (kui_set_native_menus): how many rows it has, writing the node it is about into target and where it opened (logical viewport px) into x / y — any of the three may be NULL. Zero when none is open, which is unambiguous because a menu never opens with no rows. What Node’s menu() and Core::menu answer, so a C host is not the one binding told to read what is open and given nothing to read it with.
kui_menu_item_path
Reads the open menu’s row at path, spelled as kui_menu_item spells one; KUI_MENU_ITEM_SUBMENU in its flags when it opens rows of its own. False for a row that is not there, and for an empty path.
kui_menu_submenu_count
How many rows the open menu’s row at path opens (depth indices, outermost first): 0 for a row with no submenu or one not there, and at a depth of 0 the menu’s own rows, as kui_menu_item_count counts them.
kui_metrics
The sizes the stock widgets are built from, in logical px. KuiMetrics m = KUI_METRICS_INIT; kui_metrics(ctx, &m); then spec.radius = m.radius makes a control of your own agree with the stock ones. False for a bad context, a NULL out, or a size below the first ABI’s layout.
kui_metrics_set
Makes these the metrics every stock widget from the next node on is built from; NULL restores the stock set. Start from kui_metrics and change the fields you mean to change: a zeroed metric is zero, not “leave it”. Nothing in the OS is followed; density is the host’s call.
kui_nodes
The last finished frame’s nodes in tree order, as a list of maps, each with key, parent, depth, kind, label, rect, role, text, flags, layer, origin, children, the layout spec and events (the node’s payloads by handler name). Read it with kui_value_at and kui_value_get. Empty until kui_set_inspect(ctx, true) and a frame after it. Borrowed until the next call; NULL on a bad context.
kui_note_frame_cause
Adds KUI_FRAME_CAUSE_* bits to the next frame’s reasons: the host’s own (a wake, a resize, a blink) beside the input the kui_input_* calls record.
kui_on_teardown
Sets what the next kui_run / kui_run_with calls as its window goes for good (the close button, Quit from the menu or the dock, a KUI_CMD_CLOSE on it): once, with the user the run’s view and on_event get, before kui_run returns or the process exits.
kui_open
Opens a box node built from spec; everything until the matching kui_close is its child. Returns the node’s key, or 0 for a bad context or a NULL spec.
kui_open_draggable
kui_open_keyed for a draggable node: a press-drag emits {kind="drag", phase, x, y, dx, dy, tag} events with on_drag as the tag. on_drag and on_click (either NULL) are consumed. A drag past the click slop suppresses the click.
kui_open_indexed
kui_open under a data index rather than a name: the key auto-keying would have given the ith child, given to this node wherever it sits. A virtualising list opens each row with its own row number, so a row keeps its hover, focus, edit buffer and tweens as the built range slides over it — and agrees with a list that builds every row.
kui_open_keyed
kui_open with a stable identity: the key is derived from label under the parent, so hover, focus, scroll offsets, edit buffers and transitions follow the node while its siblings change. on_click (NULL for none) is consumed. Returns the key, or 0 on failure.
kui_open_menu
Opens a context menu at (x, y) (logical viewport px) over key, with count items read from items. The next frame draws it.
kui_open_with
The general keyed container: every event tag at once, each consumed, NULL meaning absent (so a NULL on_drag here does not make the node draggable, unlike kui_open_draggable). A non-NULL on_key makes the node a key sink: give it focus with kui_set_key_focus and presses arrive as {kind="key", phase="down", code, ctrl, alt, shift, super, text, repeat, tag}, releases too (phase="up") when the spec sets key_up. on_hover tags pointer enter and leave. Returns the key, or 0 on failure.
kui_option_as_alt_get
Which Option keys the frame that just finished asked to act as Alt — for hosts driving their own window. KUI_OPTION_AS_ALT_NONE for a frame that never asked, and on a bad context.
kui_owed
Why the last frame wants another, as KUI_OWED_* bits: kui_animating taken apart by kind. A host draws another frame for any of them; a test masks KUI_OWED_CYCLE off to wait for transitions to settle under a keyframe cycle that never will.
kui_path
A path — any outline — as count floats at ops in the flat op form (kui_path_parse makes it from SVG path data): filled with spec’s bg by fill_rule (KUI_FILL_NONZERO or KUI_FILL_EVENODD) and, when width is positive, stroked width wide in color (0 for the theme’s foreground) over the fill; turned by rotate turns about pivot (two floats in the path’s coordinates, NULL for the centre of its box) by the quad that draws it, so a path that only turns is rasterized once — 0 and NULL for no turn. dash cuts the stroke as kui_polyline’s does, NULL for none. Placed like a stroke: a float sized to its own bounding box, in the parent’s box space. label keys the node (empty for a key from the tree position). The three payloads are consumed as kui_open_with consumes them; a path with one is hit by its outline under the fill rule. A NULL spec is a path with no fill, its payloads kept; ops that are not the flat form raise path-malformed under the node’s key and draw nothing.
kui_path_d
kui_path from SVG path data instead of the flat form: d goes through the one parser every binding uses, and data that does not parse raises path-malformed under the node’s key and draws nothing — the same as <path d> in JSX and path { d = } in Lua.
kui_path_parse
Parses SVG path data (M L H V C S Q T A Z, absolute or relative) into the flat op form kui_path takes — a KUI_PATH_* code then its operands, every coordinate absolute — through the one parser every binding uses. Returns how many floats the form needs; they are written to out when cap holds them all, and not at all otherwise, so a host may call once with cap 0 to size a buffer. Returns 0 for data that does not parse.
kui_pause
Pauses a playback, fading out over fade_ms.
kui_play
Starts a playback; returns its id for kui_stop / kui_set_volume / kui_pause / kui_resume. opts may be NULL (defaults). A non-NULL tag (consumed) asks for a {kind="sound", phase="ended", playback, tag} event when the playback finishes on its own.
kui_poll_event
Pops the next pending event into out (start from KUI_EVENT_INIT); false when the queue is empty. Call it after each input and each frame until it returns false.
kui_polygon
A filled polygon through count points at xy (x0, y0, x1, y1, …), at most eight (more are dropped with a polygon-points-truncated warning, fewer than three draw nothing), filled with spec’s bg. Placed like a stroke: a float sized to its own bounding box, in the parent’s box space. label keys the node (empty for a key from the tree position). The three payloads are consumed as kui_open_with consumes them; a fill with one is hit by its outline. A NULL spec is a polygon with no fill, so nothing is drawn.
kui_polyline
A stroke through count points at xy (x0, y0, x1, y1, …): a polyline, or with curve a smooth curve through them. label keys the node (empty for a key from the tree position), for a stroke that transitions or exits. The three payloads are consumed as kui_open_with consumes them; a stroke with one is hit by its shape, not its bounding box. dash cuts the stroke into marks and gaps (backlog V2): five floats — a mark, a gap, a second mark, a second gap (the lengths seen, in logical px; repeat the pair for a plain dash) and the offset into the pattern the stroke starts at — or NULL for a solid stroke.
kui_radio
The stock radio; see kui_checkbox. Declare radios between kui_radio_group_open and kui_close.
kui_radio_group_open
Opens a radio group named label: spec’s box rows (NULL for a column), the group’s role and name, and the stock gap where spec has none. Declare its radios, then kui_close. Returns its key.
kui_region
The focus region in effect; 0 for the main ring.
kui_release_held_keys
Lets go of every key the focused sink is holding, as if the user had released them. Hosts call it when the window loses the keyboard: the OS stops delivering key events to it, so the release of anything held over an app switch would never arrive. Focus moves do this by themselves.
kui_reply
Replies to the host from inside kui_ext_on_event: ev is the event the callback was handed, reply is copied (you keep ownership) and reaches the host’s on_event with your origin and the event’s window and key. Call it as often as the event deserves. Outside the callback, or on an event that carries no sink (anything a host polled for itself), it does nothing and returns false.
kui_request_copy
Asks for the selection as text.
kui_request_files
Asks for the platform’s Open, Save or folder dialog. The answer is a {kind:"files", paths, tag} event — paths empty when the user cancelled — to whoever asked. dialog NULL is an Open dialog for one file; tag may be NULL and is consumed. False when one is already out (one dialog at a time) or the dialog is malformed.
kui_request_paste
Asks for what is on the clipboard, as a KUI_MENU_ACTION_PASTE the host drains and answers with kui_input_paste (the text and the pasteboard’s KUI_PASTE_* markers) or kui_input_commit: a focused editor takes the text as typing, a focused on_key sink hears it as {kind:"text", text, tag} — so an app that owns its text inserts a paste the way it inserts a committed IME string, and the clipboard is read on the host’s side, where the permission lives. Under kui_run the runner does both halves.
kui_resume
Resumes a paused playback, fading in over fade_ms.
kui_reveal
Scrolls whatever contains key so the node shows — what Tab does to the control it lands on, asked for by name. The request resolves at the next kui_frame_finish, against the frame it lays out (the one being built when called from a view callback, the one after it otherwise — a frame is requested, so one comes), so a row a view is about to declare for the first time reveals fine. A key that frame does not declare, or one with nothing scrollable above it, is a no-op and is not kept for a later frame; the last reveal before a frame wins.
kui_rich_text
A paragraph of span_count styled runs from spans, set in base (NULL for the default style) where a span says nothing. A NULL or empty array draws nothing.
kui_root
Configures the frame’s root node from spec: its direction, padding, gap, alignment and background. Everything else declared this frame is its child. Call it first after kui_frame_begin; a NULL spec does nothing.
kui_row_count
Declares how many indexed rows the open node’s virtual list has, built or not (rowCount): what Select All inside a selectable virtual list spans, since the rows the frame built are all the core can see. Call it inside the list’s container, after its kui_open_*. Does nothing outside any node.
kui_run
Opens a window titled title and runs it to the end: view(user, ctx) is called once per frame with a context to build into, and on_event(user, ev) once per event, on this thread. Blocks until the window closes; returns false if the event loop could not start. Same as kui_run_with(NULL, title, NULL, view, on_event, user).
kui_run_with
kui_run with a window of the host’s choosing and a context’s registrations.
kui_scroll_geometry
Everything the last layout resolved for the scroll container key: its box, its content size and the clamped offset. Returns false, leaving out untouched, for a bad context, a NULL out, or a key no layout has ever resolved as a scroll container.
kui_scroll_offset
Reads that offset back, as the last layout clamped it — the number to persist and hand to kui_set_scroll later. Writes 0,0 for a node that never scrolled; either out pointer may be NULL.
kui_secure_input_get
Whether the frame that just finished asked for secure keyboard entry — for hosts driving their own window. False for a frame that never asked, and on a bad context.
kui_select
The stock select: a field showing the choice in force that, clicked, opens the core’s own menu of count options read from items — the same rows kui_open_menu takes — under it, the currentth checked (-1 for none). The host holds no open state: the choice arrives as the {kind:"menu", role, item} event a menu row posts, on the key this returns, and drawing the field again with the new current is the whole loop; a host that shows menus itself sees the menu in kui_menu as any other.
kui_select_all_in
Selects everything in the scope key declared — every run of a selectable container, or the whole screen of a cells grid. False for a node that is not a scope, or drew nothing.
kui_selection_ends
The text selection’s two ends as the drag made them — the anchor where the press landed, the focus where the pointer is — each as the data index of the virtualised row it is in (-1 outside every virtualised row) and the byte inside that row’s own text. Directed, so a Shift-press that kept the anchor reads as one. False with no text selection; a grid’s is kui_cell_selection. Any out pointer may be NULL.
kui_selection_html
The same selection with the formatting the text declared — bold, italic, a span’s own colour — for a host offering a second clipboard flavour. False when there is no text selection or nothing to carry; never a replacement for kui_selection_text.
kui_selection_text
The window’s selected text — a selectable scope’s, a cells grid’s, or the focused editor’s, whichever the window holds. False when nothing is selected. out is borrowed until the next selection call on this context.
kui_set_always_on_top
Declares that this frame wants the window above every other app’s. Cleared each kui_frame_begin like the title, but with a default of false rather than “leave as-is”: a frame that stops calling this is what lowers the window again. The host applies it after kui_frame_finish (see kui_always_on_top_get) and reports what the platform did through kui_env_set_always_on_top.
kui_set_caret_visible
Sets the blink phase; see kui_caret_visible.
kui_set_clipboard
Puts text on the system clipboard, as a KUI_MENU_ACTION_SET_CLIPBOARD the host drains: the action a menu’s Copy queues, callable from an on_key sink that hears the raw Ctrl-c. html is a second flavour beside the text, never in place of it; an empty html is none. Under kui_run the runner applies it after every input and every frame.
kui_set_clipboard_secret
Puts a secret on the system clipboard, as a KUI_MENU_ACTION_SET_CLIPBOARD_SECRET the host drains and writes marked concealed and transient, the way a password manager does: org.nspasteboard.ConcealedType and TransientType on macOS, the exclusion formats on Windows — so no clipboard manager shows or keeps it. Under kui_run the runner writes it.
kui_set_devtools
Turns the core’s devtools panel on or off: the event stream, the runtime’s facts and the tree, drawn by the core beside the host’s tree (where kui_set_devtools_dock says). Its controls and its Ctrl+Shift+<letter> chords are handled inside the kui_input_* calls, so nothing of it reaches the host’s events. KUI_DEVTOOLS=1 in the environment makes the same call for a window kui_run opens; a headless context never reads it.
kui_set_devtools_dock
Where the devtools panel sits: "left", "right", "bottom", "window" (one of its own, named kui-devtools, opened through an ordinary KUI_CMD_OPEN that the host builds nothing into) or "off" (hidden, chords still live); "side" means the right. Returns false for any other word.
kui_set_devtools_key
Respells the chord that moves the keyboard into the devtools panel and back out (and brings a hidden panel back) from its default "ctrl+shift+i": "f12", "mod+shift+d" (mod is Command on macOS, Control elsewhere), any spelling a KuiMenuItem’s accel takes. The panel’s other chords stay Ctrl+Shift+<letter>. False for a spelling kui cannot parse, which leaves the chord as it was.
kui_set_devtools_legend
The key legend the devtools facts tab shows: count pairs, the keys in keys and what each does in what, index for index.
kui_set_devtools_pick
Raises the devtools picker from outside the panel (an inspector asking “which node?”) or puts it away. While it is up the node under the pointer is kui_devtools_picked, and a press lands it in kui_devtools_selected. Raised while a declared tab is on show the pick leaves that tab up; otherwise it shows the tree tab. A hidden panel comes back docked.
kui_set_devtools_selected
Selects a node in the devtools tree tab and reveals it there, as the picker does; 0 clears.
kui_set_devtools_tab
Shows the devtools tab named name: one of the panel’s own (facts, events, tree) or a declared tab’s. A declared name the panel does not list yet is kept and shows once a frame declares it; the return says whether the panel lists it now (false on a bad context too). A hidden panel comes back docked; kui_set_devtools is still the host’s to call. Call it once, not every frame, or it pins the strip against the user’s own clicks.
kui_set_devtools_theme
Seeds the devtools panel’s theme override, which its T and A chords cycle from: base is "light", "dark" or empty for the app’s own; accent a 0xRRGGBBAA colour, or 0 for none. False for any other base word.
kui_set_diagnostics
Turns the diagnostic checks behind kui_take_warnings on or off. Off by default for a standalone context; a development build opts in.
kui_set_frame_trace
Turns the trace of why frames run on or off: the digest kui_frame_unchanged compares. kui_frame_cause is kept either way.
kui_set_icon
Sets the icon every window of the next kui_run / kui_run_with is created with.
kui_set_ime_off
Declares that this window takes the keyboard as keys, with the platform’s input method off — no composition, and on a Mac no dead keys and no press-and-hold, so a held letter repeats. Cleared each kui_frame_begin like kui_set_always_on_top: a frame that stops calling this gives the window its input method back. Under kui_run the runner applies it on change; a host driving its own window reads kui_ime_off_get and does.
kui_set_inspect
Turns the per-frame node snapshot behind kui_nodes on or off. Off by default: the copy costs a pass over every node each frame.
kui_set_key_focus
Declares key focused this frame (0 blurs at once). Edge-triggered: the node takes focus on the first frame it is declared, and a declaration repeated every frame does not clobber a Tab press or a click. Any focusable node (an editor, an on_key sink, a control, a focusable box). To move focus at any time, kui_focus.
kui_set_lookup_available
Tells the core this host can show the platform’s definition panel (macOS’s Look Up). The standard Look Up row is then offered where it means something, and a force click over text asks for one; without this the core neither offers nor asks, because a row that does nothing is worse than a row that is not there.
kui_set_master_volume
Sets the master volume every playback is scaled by (0..1), easing to it over tween_ms.
kui_set_native_menu_bar
Tells the core that the platform owns the menu bar, so kui_menu_bar draws nothing and the host is the one that hands the declaration over (kui_menu_bar_menu_count / kui_menu_bar_item read it back) and reports what was chosen with kui_activate_menu_bar_item.
kui_set_native_menus
Tells the core that this host shows menus itself — the platform’s own, however it draws them. The core then keeps the open menu as state and draws none of it: read it with kui_menu_items, show it, and report back with kui_activate_menu_item or kui_close_menu.
kui_set_option_as_alt
Declares which Option keys act as Alt in this window on macOS (KUI_OPTION_AS_ALT_*), so a dead key like Option-U arrives as a key with Alt rather than composing an accent. Cleared each kui_frame_begin like kui_set_always_on_top: a frame that stops calling this gives the Option keys back to the layout. A number past KUI_OPTION_AS_ALT_BOTH — a header from a later kui — is KUI_OPTION_AS_ALT_NONE, the Mac’s own behaviour. Under kui_run the runner applies it on change; a host driving its own window reads kui_option_as_alt_get and does.
kui_set_scroll
Sets a scroll container’s retained offset, the way the wheel would (positive = content moved up / left). Takes effect on the next frame, whose layout clamps it to that frame’s overflow: 0,0 is “jump to the top” and a huge value is “jump to the end” without knowing the content height. An offset written for a key that never scrolls is harmless.
kui_set_secure_input
Declares that this frame wants secure keyboard entry while the window has the keyboard, as at a password prompt. Cleared each kui_frame_begin like kui_set_always_on_top: a frame that stops calling this is what turns it off. Under kui_run the runner makes the platform call and keeps it balanced; a host driving its own window reads kui_secure_input_get and does.
kui_set_subpixel_text
Rasterizes outline glyphs as LCD subpixel coverage (KUI_QUAD_GLYPH_SUBPIXEL quads, the atlas’s RGB being per-channel coverage) instead of alpha masks. Only for a renderer that blends per channel (dual-source blending); flipping it re-rasterizes every glyph.
kui_set_text_cache_budget
Byte budget for the shaped-text cache: past it the least recently drawn entries are evicted at the start of the next frame, never what the last frame drew. Default 64 MB (DEFAULT_TEXT_CACHE_BYTES).
kui_set_time
The frame clock for transitions, in monotonic seconds from any origin. Set it before each kui_frame_begin; a host that never does sees transitions snap to their targets.
kui_set_volume
Sets a playback’s volume (linear amplitude, 0..1), easing to it over tween_ms.
kui_set_window_size
Asks the driver to resize window to wxh logical px. A request and not a declaration: kui_window_declare’s config is read on the opening edge only, because the user owns a window’s size once it exists, so this is the only way an app moves a live window’s size. It is queued the way kui_reveal queues a scroll and comes back out of the host’s own kui_take_window_command as KUI_CMD_SET_SIZE, carrying window and the size in width/height, for the host to apply; a headless host that never drains ignores it. window is the id events carry (KuiEvent.window), KUI_WINDOW_MAIN for the launcher’s. The size the window actually becomes arrives as the ordinary resize event.
kui_shift_scroll
Moves a scroll container by the content that moved under it, on y: drawn for where its content is drawn (and an eased leg’s start), target for the retained offset. No ease is asked or ended and no frame is asked for — it corrects the frame being built. What a variable-height list does when the rows it measured came out another height than the estimate they stood at, so the row under the pointer stays put. Call it from the view, before kui_frame_finish.
kui_size_clamp
target held between lo and hi, lo winning over hi as CSS’s clamp() has it; KUI_FIT when one is not a size.
kui_size_max
The largest of n sizings; KUI_FIT when one is not a size.
kui_size_min
The smallest of n sizings (each a length, a percentage or a calc); KUI_FIT when one is anything else.
kui_size_parse
A sizing’s spelling — "fit", "grow", "120", "50%", "clamp(400px, 80%, 1000px)" — into *out; false (and *out untouched) for one that is not.
kui_size_pct
percent percent of the room (80 for 80%): KUI_PERCENT.
kui_size_px
px logical pixels: KUI_FIXED.
kui_slider
The stock slider, named and keyed by label. Reads the value fields (value_now / value_min / value_max / value_step by their KUI_VALUE_* bits, value_text), on_change, width / min_w / max_w where set, label (a name other than the key), description, tooltip and disabled off spec; every other field is its look’s. With on_change the core proposes values as {kind:"change", value, phase, tag}. Its key.
kui_slot
Declares a slot named name at the cursor, with params (may be NULL) for whatever fills it, and fills it then and there with the extension the name’s namespace belongs to. name is the full namespace/slot: the namespace this context loaded the extension under with kui_ctx_add_extension, and the slot in the extension’s own vocabulary.
kui_slot_name
Which slot this context is a fill of; false (and out untouched) on a context that is not an extension’s — a standalone one, or a C host’s view callback. Borrowed for the duration of kui_ext_view.
kui_slot_namespace
The namespace the host loaded this extension under — what makes the slot’s full name, and what tells one instance of a plugin loaded twice from the other. False (and out untouched) on a context that is not an extension’s. Borrowed for the duration of kui_ext_view.
kui_slot_params
The parameters the host declared the slot with, or NULL when it passed none (or this is not an extension’s context). Borrowed for the duration of kui_ext_view; read it with kui_value_get and friends.
kui_sound_add
Registers a sound from its encoded file bytes (wav/ogg/mp3/flac, copied); returns its handle for KuiSpec.click_sound / kui_audio / kui_play, 0 when empty.
kui_sound_remove
Forgets a registered sound and stops its playbacks.
kui_spec_float_preset
Fills a spec’s float_* fields from a preset name — the same four names ("parent", "viewport", "below", "above") the JSX and Lua float props take, resolved by the same core function. Returns false and leaves the spec alone for an unknown name.
kui_stop
Stops a playback from kui_play, fading out over fade_ms (0 for at once).
kui_switch
The stock switch; see kui_checkbox.
kui_system_fonts
Every family kui_font_families names, one per family and in its order, with what its faces say they are (monospaced, the weights, an italic), written into out up to cap and the total returned, as kui_font_families does. Read from what the font database recorded when it scanned each face: nothing is loaded or shaped. The names and weight arrays are borrowed until the next call on this context. What Node’s systemFonts() answers.
kui_take_announcements
Drains queued announcements into out (up to cap; the rest are dropped, so size it generously) and returns the count. The strings stay valid until the next call on this context.
kui_take_audio_commands
Drains queued audio commands into out (up to cap; the rest are dropped, so size it generously); returns the count. Only for hosts driving their own audio device — kui_run plays them itself.
kui_take_file_request
Drains the dialog asked for, for a host that shows it itself (under kui_run the runner does): its KUI_FILE_DIALOG_* mode, whether it picks several, its title, folder and suggested name (empty for none), and how many filters it offers — read each with kui_file_request_filter. Any out pointer may be NULL; the strings are borrowed until the next call on this context. False when nothing is asked. Answer with kui_input_files.
kui_take_menu_action
Drains what choosing a menu row left for the host: the clipboard, which is the host’s in this library. KUI_MENU_ACTION_SET_CLIPBOARD carries the text to put there — the core worked out what, which is the half only it can do — and KUI_MENU_ACTION_PASTE asks for what is there, which a host delivers back with kui_input_commit (an editor takes it as typing; a sink hears it as {kind:"text"}).
kui_take_warnings
Drains the warnings the core raised since the last call (silent misconfigurations it noticed while finishing frames, each once) into out, up to cap (the rest wait for the next call), and returns the count. The strings stay valid until the next call on this context. A standalone context starts with the checks off (kui_set_diagnostics turns them on); kui_run prints them to stderr itself in debug builds.
kui_take_window_command
Pops the next window command into out: what chrome nodes asked for since the last drain, and the KUI_CMD_OPEN / KUI_CMD_CLOSE the declared window set’s diff decided at the last kui_frame_finish. Returns false, writing nothing, when there is none — or when out’s size is below the layout this library knows (start from KUI_WINDOW_COMMAND_INIT), in which case the command stays queued. Call after each input dispatch and each frame until it returns false, and apply each to the real window it names.
kui_text
A paragraph of plain text in one style (NULL for the default style). A text has no box of its own; wrap it in a kui_open for padding, a background or a click.
kui_text_cache_bytes
What the shaped-text cache holds, in the estimated bytes the budget is charged against.
kui_text_edit
An editable text node keyed by label, seeded with initial the first time it is seen; the core keeps its buffer, caret and undo history across frames. flags are KUI_EDIT_MULTILINE, KUI_EDIT_AUTOFOCUS and KUI_EDIT_WRAP; spec (required) is the box around it. Read the text with kui_edit_text; changed and submit events carry the key. Returns the key, or 0 on failure.
kui_text_hit
Where a point (logical viewport px, as a click or drag event carries it) lands in the text the node key drew: a byte offset into that text — across the node’s text runs in order, the way the access tree reads a line — and the visual line. False for a key that drew no text, a bad context or a NULL out. Answered from the frame that finished.
kui_text_input
Single-line input with chrome (background, focus ring). Returns the node key; read it with kui_edit_text, “changed”/“submit” events carry it.
kui_theme
This window’s palette as of the current or last frame: one 0xRRGGBBAA per role, derived from what kui_env_set_system reported unless the host pinned something with kui_theme_set_accent or kui_theme_set.
kui_theme_set
Pins the whole palette to exactly these colours, following neither the OS’s appearance nor its accent; NULL goes back to deriving both.
kui_theme_set_accent
Keeps following the OS’s light or dark base but paints accent (0xRRGGBBAA) instead of the OS’s accent; zero goes back to the OS’s.
kui_titlebar
Adaptive titlebar: drag strip + standard title + window buttons, all driven by the env facts (kui_env_set_window).
kui_titlebar_with
Titlebar hosting custom content (tabs, search): body builds it between the OS-controls inset and the window buttons.
kui_token_color
A colour token by name, resolved for this frame’s appearance, as 0xRRGGBBAA through out. The calling origin’s table is tried first, then the host’s; a theme role’s name (surface) answers with the role. False for a name nothing declared or one that is a length, which also raises unknown-token once per name.
kui_token_length
A length token by name, in logical px; a metrics role’s name (radius) answers with the metric. False and unknown-token as for kui_token_color.
kui_tokens_derive
Adds derived colour tokens to the calling origin’s table, after kui_tokens_set: each a name, the colour token or theme role it derives from, and a chain of ops applied in order.
kui_tokens_set
Declares the named colours and lengths of the calling origin: the host’s outside a plugin’s view, the plugin’s own inside kui_ext_view.
kui_tooltip
A hint floated below the enclosing node. Gate it on kui_is_hovered of a hoverable parent.
kui_tooltip_with
Tooltip chrome around content built by body.
kui_value_as_bool
A payload’s boolean - a key event’s shift / ctrl / alt / super / repeat, a modifiers event’s four. False - and *out untouched - for anything that is not one; a bool is never coerced from a number.
kui_value_as_float
The number a payload carries, as a double: a float as it is, an integer widened. The reader for everything geometry-shaped an event carries - a drag’s x/dx, a layout’s rect, a resize’s scale - which kui_value_as_int would truncate. False for anything else.
kui_value_as_int
The integer a value holds; false for anything that is not an integer (a float is not coerced; see kui_value_as_float).
kui_value_as_str
Borrowed string view; valid as long as the value.
kui_value_at
Borrowed entry i of a list value (preedit’s cursor, the two ends an access request carries); NULL past the end or on anything but a list. Valid as long as the list.
kui_value_bool
A new boolean value, owned by the caller.
kui_value_entry
A map’s ith entry, for walking one whose keys you do not know: the key into *key and the borrowed value returned, NULL past the end or on anything but a map. Entries keep the order they were set in.
kui_value_float
A new float value, owned by the caller.
kui_value_free
Frees a value the caller owns. Never call it on a borrowed value (an event’s payload, a kui_value_get result); NULL is a no-op.
kui_value_get
Borrowed lookup on a map value; NULL if absent. Valid as long as the map.
kui_value_int
A new integer value, owned by the caller.
kui_value_is_null
Whether the value is the null one: what a key event’s text is on a release, and a missing tag. A NULL pointer answers true too, so a kui_value_get miss reads the same as an explicit null.
kui_value_len
How many entries a list or map holds; 0 for anything else, which a scalar reader tells apart from an empty one.
kui_value_list
A new empty list, owned by the caller; fill it with kui_value_list_push.
kui_value_list_push
Appends to a list value. Consumes val; on anything but a list it is dropped and nothing changes.
kui_value_map
A new empty map, owned by the caller; fill it with kui_value_map_set. The usual shape of a tag is a map with a kind string.
kui_value_map_set
Sets key on a map value, replacing an existing entry. Consumes val; on anything but a map it is dropped and nothing changes.
kui_value_null
A new null value, owned by the caller. Where a tag is taken it asks for the events without a tag.
kui_value_str
A new string value holding a copy of s, owned by the caller.
kui_window_buttons
The minimize/maximize/close cluster; draws nothing when the OS provides controls, so it is always safe to call.
kui_window_closed
A host reports that the OS closed window id — its close button, the window manager. The window stays closed while its name is still declared (see kui_window_declare), whatever only it declared closes with it, and the app gets {kind:"window", phase:"closed", name, id} from kui_poll_event. Nothing happens for KUI_WINDOW_MAIN or for a window already closed by the diff.
kui_window_declare
Declares that a window named name exists this frame: it opens on the first frame any window’s frame declares it — cfg is read then and never again, NULL meaning KUI_WINDOW_CONFIG_INIT — and closes on the first frame none does. The Open / Close arrive through kui_take_window_command; the app sees {kind:"window", phase:"opened"|"closed", name, id} events. A window the user closed (kui_window_closed) stays closed while still declared: stop declaring it, then declare it again. Call between kui_frame_begin and kui_frame_finish.
kui_window_dismissed
A host reports that window id was asked to go away: a press landed outside it (KUI_DISMISS_OUTSIDE), or Escape reached it (KUI_DISMISS_ESCAPE). The app gets {kind:"dismiss", reason, name, id} from kui_poll_event and nothing closes — exactly what a modal node’s dismissal does, one level up: only the app can stop declaring the window, and it does that on the frame it decides to. So a dropdown that graduates from a modal float to a popup window changes its declaration and keeps its handler.
kui_window_title
Declares this frame’s window title (cleared each kui_frame_begin).
kui_window_title_get
The title declared this frame, if any — for hosts driving their own window: diff and apply after kui_frame_finish. The view is valid until the next kui_frame_begin.