Skip to main content

Core

Struct Core 

Source
pub struct Core {
    pub text: TextSystem,
    pub cells: CellStore,
    pub atlas: GlyphAtlas,
    pub resources: SharedResources,
    pub audio: SharedAudio,
    pub interaction: Interaction,
    pub scroll: ScrollStore,
    pub edit: EditStore,
    pub anim: AnimStore,
    pub depart: DepartStore,
    pub stats: FrameStats,
    pub env: Env,
    /* private fields */
}
Expand description

One window’s runtime: the state a runner drives frame by frame.

Construct one with Core::new (a private Session) or Core::new_in (joining a session another window shares). The public fields are the stores a runner or a binding reads directly: resources and audio for registration and playback commands, env for the host facts a driver pushes, stats for frame timing.

§One frame, in order

  1. Core::set_time with the frame clock, so transitions advance.
  2. Core::frame with the viewport (logical px) and the scale. It begins the frame and returns the Ui builder; build the tree through it.
  3. Ui::finish runs layout and emission. The draw data is now in Core::output: the DisplayList and the GlyphAtlas a renderer mirrors to a texture.
  4. Core::take_pending_events drains events the frame itself raised (a resize, a hover change under a still pointer); route them like any other.
  5. Between frames, feed input through Core::handle_input. Each call returns the UiEvents it resolved to, hit-tested against the frame that finished.
  6. Core::take_warnings for misconfigurations the core noticed, and Core::animating to decide whether to draw another frame without waiting for input.

A headless core needs no window or GPU, so a test can drive it:

use kui_core::{Color, Core, InputEvent, NodeSpec, QuadKind, Size, TextStyle, Vec2};

let mut core = Core::new();

// 1–3: a frame. `frame` begins it, `finish` lays it out and emits.
core.set_time(0.0);
let mut ui = core.frame(Size::new(400.0, 300.0), 1.0);
ui.with_keyed("toolbar", NodeSpec::row().pad(8.0).gap(8.0), |ui| {
    // A clickable node needs an accessible name, or `take_warnings`
    // reports `control-without-name`.
    let button = NodeSpec::row().size(80.0, 32.0).bg(Color::hex(0x3366cc));
    ui.leaf_keyed("save", button.on_click("save").label("Save"));
    ui.text("Untitled", TextStyle::new(14.0));
});
ui.finish();

// 4: what the frame itself raised (nothing on a first frame).
assert!(core.take_pending_events().is_empty());

// The renderer's view of the frame: quads in physical pixels.
let (list, atlas) = core.output();
assert!(list.quads.iter().any(|q| q.kind == QuadKind::Solid));
atlas.dirty = false; // after uploading `atlas.pixels`

// 5: input, hit-tested against the frame that finished.
core.handle_input(InputEvent::CursorMoved(Vec2::new(20.0, 20.0)));
core.handle_input(InputEvent::mouse_down(1));
let events = core.handle_input(InputEvent::mouse_up());
assert_eq!(events.len(), 1);
assert_eq!(events[0].payload.as_str(), Some("save"));

// 6: diagnostics, and whether another frame is owed.
assert!(core.take_warnings().is_empty());
assert!(!core.animating());

A windowed runner does the same with real time, real input and a renderer consuming Core::output; kui-native is that runner.

Fields§

§text: TextSystem

This window’s shaped-text cache and rasterizer. Not the session’s: its cache entries are stamped with atlas’s epoch, and TextId indexes its per-frame list.

§cells: CellStore

The frame’s cell grids and their glyph tables.

§atlas: GlyphAtlas

This window’s glyph atlas — the CPU side of its renderer’s texture, handed out by output.

§resources: SharedResources

The session’s resource registry. A font, image or sound registered through it is registered for every window in the session.

§audio: SharedAudio

The session’s audio store: one device for the process, so playback bookkeeping and the command queue are shared, not per window.

§interaction: Interaction§scroll: ScrollStore§edit: EditStore§anim: AnimStore

Transition tweens, keyed by node; see anim. Fed by set_time.

§depart: DepartStore

Subtrees the view stopped declaring, played out and then dropped; see depart. Empty unless something declares exit.

§stats: FrameStats

Frame timing pushed by the frame driver; see widgets::latency_graph.

§env: Env

Host facts pushed by the frame driver (refresh rate, focus).

Implementations§

Source§

impl Core

Source

pub fn set_origin(&mut self, origin: OriginId)

Tags subsequently created nodes with an origin (set by the runner before handing the frame to an extension).

Source

pub fn configure_root(&mut self, spec: NodeSpec)

Replaces the implicit root’s spec (e.g. to make the top level a row). Root sizing is resolved against the viewport regardless.

Source

pub fn root_key(&self) -> Key

The root node’s key — for hover/press queries or set_key_focus when the root itself declares the interaction (e.g. a root-level key sink).

Source

pub fn child_key(&self, label: &str) -> Key

The key a child labeled label would get — usable before creating it, e.g. to check hover state for styling.

Source

pub fn child_key_indexed(&self, i: u64) -> Key

The key the ith child gets from auto-keying — what open_indexed opens with, usable before the node exists.

Source

pub fn is_hovered(&self, key: Key) -> bool

Source

pub fn is_drop_target(&self, key: Key) -> bool

Whether files dragged in from the OS are over key.

Source

pub fn drop_target(&self) -> Option<Key>

The zone the dragged files are over, if any — what a driver answers the OS with.

Source

pub fn is_pressed(&self, key: Key) -> bool

Source

pub fn is_group_hovered(&self, group: u64) -> bool

Whether any member of hover group group (see NodeSpec::hover_group) is hovered.

Source

pub fn is_group_pressed(&self, group: u64) -> bool

Whether hover group group is pressed (press started on a member, pointer still over one).

Source

pub fn take_pending_events(&mut self) -> Vec<UiEvent>

Events raised outside handle_input: the resize a changed viewport produced at begin_frame, and on_hover enter/leave caused by a finished frame changing what sits under a still cursor. Frame drivers route these after finish_frame; they also ride along with the next handle_input result, so a driver that never calls this merely sees them a little later.

Source

pub fn modifiers(&self) -> KeyMods

Physical modifier state as of the last InputEvent::Modifiers.

Source

pub fn cursor(&self) -> Option<Vec2>

Where the pointer is, in this window’s logical viewport coordinates, as of the last CursorMoved — None once it has left the window. What a view that follows the pointer reads (the devtools’ picker outlines the node under it); a control that wants to react to the pointer declares hoverable or on_hover and lets the core do the hit test.

Source

pub fn open(&mut self, spec: NodeSpec) -> Key

Source

pub fn open_keyed(&mut self, label: &str, spec: NodeSpec) -> Key

Source

pub fn label_of(&self, key: Key) -> Option<&str>

The inverse of Self::key_of: the label key was opened under — in the frame being built so far, else in the last one — or None for an auto-keyed node or a key no frame has declared. What a reader holding a key from an event or from focus() turns back into the name the view gave it.

Source

pub fn key_of(&mut self, label: &str) -> Option<Key>

The key of the node opened under label (open_keyed; a key prop in JSX or a Lua table) in the last finished frame — or, while a frame is being built, in it so far and then in the last one. The door for a caller that holds only strings: keys are hashes of the path from the root, and that path runs through auto-keyed ancestors nothing outside the build can spell, so “focus the node I just declared” is this and not child_key. None when no node declared the label. Labels are unique among siblings, not across a tree, so two nodes may share one under different parents. A guest asking from inside its fill is answered from the nodes it opened and no one else’s — it cannot know what the host or another guest called theirs, and its env is a reading of its own view; the host, whose frame it is, from its own first and from everyone’s when it opened none. Within that, the first in tree order wins and an ambiguous-key warning says so.

Source

pub fn open_indexed(&mut self, i: u64, spec: NodeSpec) -> Key

open_keyed in the sibling-index namespace: the key auto-keying would have given the ith child. A list that builds only rows 900..930 opens each with its data index, so row 900 keeps the key it has when the whole list is built — hover, focus, edit buffers and tweens follow the row instead of the slot it happens to occupy.

Source

pub fn row_count(&mut self, n: u64)

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 built rows are all the core can see. widgets::uniform_list and widgets::list call it on their container; a list composed by hand calls it inside the container’s with. Nothing, outside any node.

Source

pub fn open_key(&mut self, key: Key, spec: NodeSpec) -> Key

Opens a node under a key the caller built; see Ui::open_key.

Source

pub fn close(&mut self)

Source

pub fn hint(&mut self, key: Key, text: impl Into<String>)

Records the hover hint of the node just opened (the top of the stack): close floats widgets::hover_hint below it while it is hovered. The one place that decides when a tooltip shows, so a binding that parsed the string cannot show it some other way.

Source

pub fn open_from(&mut self, props: PropsOut, content: Content<'_>) -> Key

Opens a node the way a parsed prop list says — under the data index, the label or the next auto key; taking keyboard focus when keyFocus asked; floating its tooltip on close while hovered — with whatever the node holds. The one door for every binding that lowers props, so the identity match, the focus edge and the hint are not re-derived per binding per element (they were, eight, five and four times). A box or a fragment is left open for its children, and its hint floats as its last child on close; a cells grid, a line, a polygon and a path are leaves, and theirs floats beside the leaf, anchored to it (PropsOut::for_leaf, backlog RG113). Returns the key.

Source

pub fn configure_root_from(&mut self, props: PropsOut)

The root the way a parsed prop list says: its title, whether it wants the window on top, its keyboard secure, its Option keys as Alt or its input method off, the windows it declares, its spec, and keyboard focus on it when asked — what a binding’s root op does, once.

Source

pub fn text_node(&mut self, content: &str, style: TextStyle)

Source

pub fn cells(&mut self, grid: &CellGrid<'_>, spec: NodeSpec)

A cell grid as one leaf node, sized cols × cell_w by rows × cell_h. spec is the node’s: an on_key makes it the terminal’s sink, an on_click / on_drag carry cell: {row, col} on their events.

Source

pub fn cells_keyed(&mut self, label: &str, grid: &CellGrid<'_>, spec: NodeSpec)

Self::cells under a declared key.

Source

pub fn cells_indexed(&mut self, i: u64, grid: &CellGrid<'_>, spec: NodeSpec)

Self::cells under a data index; see Self::open_indexed.

Source

pub fn text_edit( &mut self, label: &str, initial: &str, opts: &EditOptions, spec: NodeSpec, ) -> Key

An editable text node. State (buffer, cursor, selection) is retained by key across frames; edits arrive via handle_input and come back to the host as “changed”/“submit” events. Read with edit_text.

Source

pub fn image_node(&mut self, id: ImageId, spec: NodeSpec)

A registered image (see Resources::add_image). Fit sizing takes the image’s pixel dimensions as logical px; a Fit height against a resolved width preserves the aspect ratio. style.radius rounds the corners. Linear sampling, stretched to the box: Self::image_node_with takes the two rows that say otherwise.

Source

pub fn image_node_with(&mut self, id: ImageId, opts: ImageOpts, spec: NodeSpec)

Self::image_node with its sampling and fit rows: how texels are read between pixels, and how the pixels meet a box of another aspect. The box — its layout, hit region and access rect — is the same in every mode.

Source

pub fn fragment_node( &mut self, frag: impl Into<FragmentRef>, params: &[f32], spec: NodeSpec, ) -> Key

A box a registered WGSL function paints.

An ordinary node in every other respect: it lays out where it is declared, sizes from spec, rounds by radius, clips, fades with its subtree’s opacity, takes input like any box, and may hold children — which paint over it, so a gradient card is a fragment with a title and buttons inside it.

It has no intrinsic size: unlike an image there is nothing to measure, so a fragment with no width / height / fill is zero by zero and draws nothing. Size it.

params is up to sixteen numbers, positional, zero-padded, read by the shader as four vec4<f32>; more than sixteen are dropped with a fragment-params-truncated warning. A handle that is not live in this session draws nothing, as every resource kind does — and so does one whose image (FragmentId::with_image) is not, which is the removal order: the image goes, the fragment reading it draws the fallback, and the handle it kept is a foreign-resource miss like any other.

Source

pub fn open_fragment( &mut self, frag: impl Into<FragmentRef>, params: &[f32], spec: NodeSpec, ) -> Key

Opens a fragment as a parent: its children paint over it, which is what a gradient card with a title and buttons in it is. Balance it with Self::close, or use Ui::fragment_with.

Source

pub fn fragment_node_keyed( &mut self, label: &str, frag: impl Into<FragmentRef>, params: &[f32], spec: NodeSpec, ) -> Key

Self::fragment_node under a label key, for a fragment that transitions or exits and needs a stable identity across frames.

Source

pub fn open_fragment_keyed( &mut self, label: &str, frag: impl Into<FragmentRef>, params: &[f32], spec: NodeSpec, ) -> Key

Self::open_fragment under a label key.

Source

pub fn open_fragment_indexed( &mut self, i: u64, frag: impl Into<FragmentRef>, params: &[f32], spec: NodeSpec, ) -> Key

Self::open_fragment under a data index; see Self::open_indexed.

Source

pub fn line_node(&mut self, points: &[Vec2], stroke: Stroke, spec: NodeSpec)

A stroke through points in the parent’s box space: one round-capped segment for two points, a polyline for more, a smooth curve through them with Stroke::curve.

Never in layout. The node is a float sized to the stroke’s padded bounding box, so it takes no room in a row or column, and spec’s sizing, clamps, padding, gap and alignment are ignored. What spec carries that matters: transition (the colour eases — it rides in the bg slot — and slide, enter and exit offsets move the float), opacity, on_layout (reports the bounding box), a declared float whose anchor is kept (FloatAnchor::Viewport reads the points in viewport space), and role / label, which are honoured like any node’s; without them a line has no access row — unless it takes input, when it derives one as a box would. Input is hit by shape: a press within half the stroke’s width of any piece (at least MIN_STROKE_GRAB wide) hits it, and a press elsewhere in its box falls through to what is under it. Fewer than two points draw nothing.

Consecutive segments overlap at their round caps, which is the join: exact for an opaque stroke, and a translucent one double-blends there, the way a faded subtree shows its seams.

Source

pub fn line_node_keyed( &mut self, label: &str, points: &[Vec2], stroke: Stroke, spec: NodeSpec, )

Self::line_node under a label key, for a stroke that transitions or exits and needs a stable identity across frames.

Source

pub fn line_node_indexed( &mut self, i: u64, points: &[Vec2], stroke: Stroke, spec: NodeSpec, )

Self::line_node under a data index; see Self::open_indexed.

Source

pub fn polygon_node(&mut self, points: &[Vec2], spec: NodeSpec)

A filled polygon through points in the parent’s box space: up to eight vertices, the fill in spec’s bg, painted by the stock polygon fragment the core registers itself.

Placed exactly as a line is: never in layout, a float sized to the points’ bounding box inflated by a logical pixel for the edge ramp, so it takes no room in a row or column and spec’s sizing, clamps, padding, gap and alignment are ignored. transition eases the fill through the bg slot, and slide, enter and exit move the float; a declared float keeps its anchor; role and label are honoured, and without them a polygon has no access row unless it takes input, when it derives one as a box would (a clickable wedge is a button). Input is hit by shape: a press inside the outline hits it, one in its box but outside the outline falls through to what is under. Fewer than three points draw nothing; a ninth and later are dropped with polygon-points-truncated. The outline may be concave; a self-intersecting one fills even-odd, its overlaps unfilled.

Source

pub fn polygon_node_keyed( &mut self, label: &str, points: &[Vec2], spec: NodeSpec, )

Self::polygon_node under a label key.

Source

pub fn polygon_node_indexed(&mut self, i: u64, points: &[Vec2], spec: NodeSpec)

Self::polygon_node under a data index; see Self::open_indexed.

Source

pub fn path_node(&mut self, path: &Path, spec: NodeSpec)

A path — any outline, SVG’s d — filled with spec’s bg by the path’s rule and stroked by its stroke if it has one (docs/adr/0040-a-path-is-a-mask-in-the-atlas.md).

Placed exactly as a line is: never in layout, a float sized to the outline’s bounding box two logical pixels out (and half the stroke’s width further), so it takes no room in a row or column and spec’s sizing, clamps, padding, gap and alignment are ignored. transition eases the fill through the bg slot, and slide, enter and exit move the float; a declared float keeps its anchor; role and label are honoured, and without them a path has no access row unless it takes input, when it derives one as a box would. Input is hit by shape: a press inside the outline by the fill rule hits it, one in its box past the outline falls through to what is under. A path with no outline draws nothing.

The outline is rasterized once per shape, scale and quarter-pixel position into the glyph atlas and drawn as a glyph-mask quad; the fill bleeds half a pixel so two paths sharing an edge meet without the background showing through. A path whose ops change twice within a few frames, or whose mask is a quarter of the biggest atlas page or more, draws from a texture of its own instead.

Source

pub fn path_node_keyed(&mut self, label: &str, path: &Path, spec: NodeSpec)

Self::path_node under a label key.

Source

pub fn path_node_indexed(&mut self, i: u64, path: &Path, spec: NodeSpec)

Self::path_node under a data index; see Self::open_indexed.

Source

pub fn parse_path(&self, d: &str) -> Result<Path, PathError>

SVG path data to a crate::path::Path, through the one parser every binding’s d goes through (Path::parse, reached here as the door the C API’s kui_path_parse is). Err names the byte.

Source

pub fn path_d_node( &mut self, d: &str, rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_node from SVG path data, parsed by the one parser every binding goes through; data that does not parse raises path-malformed under the node’s key and draws nothing.

Source

pub fn path_d_node_keyed( &mut self, label: &str, d: &str, rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_d_node under a label key.

Source

pub fn path_node_d( &mut self, key: Key, d: &str, rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_d_node under a key the caller derived.

Source

pub fn path_flat_node( &mut self, floats: &[f32], rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_node from the flat op form — a code, then its operands, per op, as Path::to_floats writes it and a binding’s wire carries it. Floats that are not the form (a code that is not one, an op cut short) raise path-malformed under the node’s key and draw nothing: one answer in every binding, where it was an error in one and silence in two (RG112).

Source

pub fn path_flat_node_keyed( &mut self, label: &str, floats: &[f32], rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_flat_node under a label key.

Source

pub fn path_node_flat( &mut self, key: Key, floats: &[f32], rule: FillRule, stroke: Option<Stroke>, turn: Option<Turn>, spec: NodeSpec, )

Self::path_flat_node under a key the caller derived.

Source

pub fn rich_text_node(&mut self, spans: &[Span<'_>], base: TextStyle)

A paragraph of styled spans, shaped and wrapped as one flow.

Source§

impl Core

Source

pub fn set_frame_trace(&mut self, on: bool)

Turns the trace of why frames run on or off: who holds each owed frame (Self::owed_by) and whether each frame changed what is drawn (Self::frame_unchanged). Off by default, where neither costs anything; on, the holders are taken at the start of every frame the last one owed — a walk of what is owed and one of the last frame’s tree to name it — and the display list is hashed at the end of every frame. Self::frame_cause is kept either way.

Source

pub fn frame_trace(&self) -> bool

Whether Self::set_frame_trace turned the trace on.

Source

pub fn frame_cause(&self) -> FrameCause

Why the frame being built runs: every reason that reached the window between the start of the last frame and the start of this one. Between frames, the last frame’s — or, after Self::begin_frame_cause, the next one’s. See FrameCause.

Source

pub fn begin_frame_cause(&mut self)

Starts the next frame’s record now rather than at its begin_frame: its reasons (Self::frame_cause) and, traced, who holds it (Self::owed_by) — for a driver whose view runs before the frame it is for begins. Node’s loop runs view to a tree and only then hands the tree to a frame, so a view reading either would read the frame before; the loop calls this first, and the view reads the frame it is building. The begin_frame that follows keeps what this took, and a second call before it is nothing. What reaches the window in between — input, a note — is the frame after’s, as it is during a build.

Source

pub fn note_frame_cause(&mut self, cause: FrameCause)

Adds to the next frame’s reasons — the driver’s door, for what it saw and the core never will: a wake, a resize, a blink, a retry, an OS event it kept. The input it hands Self::handle_input is recorded without this.

Source

pub fn owed_by(&self) -> &OwedBy

Who held the frame the last one left owed, as the frame being built found them (see OwedBy) — or, after Self::begin_frame_cause, as the next one will. Empty when the trace is off.

Source

pub fn frame_unchanged(&self) -> Option<bool>

Whether the last finished frame drew exactly what the one before it drew — the same quads, clips, fragments and textures at the same size and scale — so it changed nothing on screen. None while the trace is off and for the first frame after it came on. A frame that draws a fragment is never unchanged: the shader reads the clock. What the glyph atlas holds is not compared, only where the quads sample it.

Source§

impl Core

Source

pub fn devtools_tab_declare( &mut self, name: &str, label: &str, slot: Option<&str>, ) -> bool

Declares a devtools tab this frame. A name declared already this frame warns duplicate-tab and keeps the first; returns whether this one stood. The bare door under Ui::devtools_tab / devtools_tab_with, for a binding that opens the content itself.

Source

pub fn devtools_tab_shown(&self, name: &str) -> bool

Whether the host form of tab name is shown this frame — the panel is on, docked in this (the main) window, and name is the tab on show. Read before the content is built, from the session’s state, which is in place while the host’s view runs.

Source

pub fn devtools_shown_tab(&self) -> Option<String>

The tab on show, by name, when it is a declared one — what the Node and Lua drivers read once a frame to call a tab’s function child. None for one of the panel’s own, for the panel off, popped out, or another window’s frame.

Source

pub fn devtools_tab_open(&mut self, name: &str)

Opens the host form’s content node: a float anchored to the tab’s body by key, the body’s size, clipped, keyed as the host’s own child. The caller builds inside and closes. The bare door under Ui::devtools_tab_with; it does not declare, and it does not ask whether the tab is on show.

Source§

impl Core

Source

pub fn set_devtools(&mut self, on: bool)

Turns the devtools panel on or off for this session. On, it is drawn where Self::set_devtools_dock says — beside the host’s tree in the main window by default — and its chords are live in every window. KUI_DEVTOOLS=1 in the environment is the same call made by nobody; KUI_DEVTOOLS=bottom (or left, right, window, off) also says where.

Source

pub fn devtools_from_env(&mut self) -> bool

Opens the panel if KUI_DEVTOOLS in the environment asks for it (1, true, or a placement name), and says whether it did. What the windowed runners call once, before the first frame — the door for a program that was never told about the panel — and what a headless core never reads, so a variable left exported cannot put a dock into a test’s tree.

Source

pub fn devtools(&self) -> bool

Whether the panel is on.

Source

pub fn set_devtools_dock(&mut self, dock: Dock)

Where the panel sits; Ctrl+Shift+D moves it from there.

Source

pub fn devtools_dock(&self) -> Dock

Source

pub fn set_devtools_theme( &mut self, base: Option<Appearance>, accent: Option<Color>, )

Seeds the panel’s theme override — what its T and A chords cycle from. None for either leaves the app’s own.

Source

pub fn set_devtools_key(&mut self, key: Accel)

Respells the chord that moves the keyboard into the panel and back out — and brings the panel back when it is off — from its default Ctrl+Shift+I: any Accel spelling ("f12", "mod+shift+d", "⌥⌘I"). The other chords stay Ctrl+Shift+ <letter>; this is the one an app puts in its own help, and the one whose default an app’s keymap may want for itself. A chord the app takes is the app’s for good: with F12 set, Ctrl+Shift+I reaches the app’s sinks like any other press.

Source

pub fn devtools_key(&self) -> Accel

The chord that moves the keyboard into the panel, as set or as it defaults.

Source

pub fn devtools_selected(&self) -> Option<Key>

The node the panel’s tree tab has selected: what an inspector in a declared tab reads to say which node it is about. Answered from the session, so it is right inside the host’s view and inside an extension’s fill alike.

Source

pub fn devtools_hovered(&self) -> Option<Key>

The tree row under the pointer in whichever window draws the tree — the node the main window outlines.

Source

pub fn devtools_picked(&self) -> Option<Key>

The node the picker last saw under the pointer, while picking.

Source

pub fn set_devtools_selected(&mut self, key: Option<Key>)

Selects a node in the panel’s tree tab from outside it — an inspector driving the highlight from its side — and reveals it there, as the picker does; None clears. The tab does not move: the caller is drawing in one.

Source

pub fn set_devtools_pick(&mut self, on: bool)

Raises the panel’s picker from outside it — an inspector in a declared tab asking “which node?” — or puts it away. Picking happens in the main window, over the app: the node under the pointer is devtools_picked while it is up, and the press lands it in devtools_selected. Raised while a declared tab is on show, the pick leaves that tab up; raised otherwise — a tab named through Self::set_devtools_tab but not declared yet included — it is the Ctrl+Shift+P pick, which shows the tree tab. A hidden panel comes back docked, as the chord’s does.

Source

pub fn devtools_picking(&self) -> bool

Whether the panel’s picker is up.

Source

pub fn set_devtools_tab(&mut self, name: &str) -> bool

Shows the panel’s tab named name from outside the panel — what the strip’s click and Ctrl+Shift+N do, for an app with a command that jumps to its own tab. name is one of the panel’s own (facts, events, tree, in any case — the strip labels them Facts, Events, Tree) or a declared tab’s, exactly as the app declared it. A declared name the panel does not list yet is kept and shows once a frame declares it, as a strip click on it would; the return says whether the panel lists it now (it lists a declared tab from the first frame it is on). A hidden panel comes back docked, as the picker’s does. The panel’s on is not touched: that is Self::set_devtools’s. Edge-triggered — called once a frame it would pin the strip against the user’s own clicks.

Source

pub fn devtools_current_tab(&self) -> String

The tab the panel is on, by name: one of its own (facts, events, tree) or a declared tab’s — what the strip marks, panel on or off, in any window. A declared name the panel stopped listing answers the panel’s own tab the strip falls back to. Unlike Self::devtools_shown_tab, which answers only a declared tab on show in the main window for a data binding’s function child, this is the selection itself.

Source

pub fn set_devtools_legend(&mut self, legend: &[(&str, &str)])

The key legend the facts tab shows: (keys, what they do).

Source

pub fn devtools_window(&self) -> bool

Whether this core draws the panel’s own window — a frame the host builds nothing into.

Source§

impl Core

Source

pub fn host_area(&self, window: Size) -> Size

What the dock leaves of a window window big: the viewport a frame begun at that size lays out into, which viewport() reports once the frame has begun and a resize reports when it changes. It takes the window’s size and the dock’s state and nothing of the frame, so it answers before the first frame too — what a driver’s window-size reading hands a host that sizes its model at setup (Node’s KuiWindow.size()).

Source

pub fn host_rect(&self) -> Rect

Where the current frame laid the host out, in the window’s logical px: Core::viewport with its origin — x the pane’s width under a left dock, and zero everywhere else, the whole window with the panel off, in a window of its own, or in any window but the main one. The frame’s reading, like viewport(), so it is zero before the first frame (the pre-frame answer is host_area’s size) and it is the rect the quads of output() were drawn against: scaled by scale() into their physical px, it is what separates the host’s quads from the dock’s — all but the root’s background, which devtools_configure_root gives the window as well as the app container, so it fills the whole window beneath the pane. Backlog F92: the origin reached only the Rust runner, through devtools_inset, so a Node test could size itself to the host area but not say that nothing of its own left it.

Source

pub fn devtools_inset(&self) -> Size

What a docked pane takes off the main window, in the axis it takes it: the side column’s width as (w, 0), the bottom strip’s height as (0, h), and zero with the panel off, in a window of its own, or asked of any window but the main one. The pane’s extent as the handle left it, not as the window clamps it — what a driver adds to the app’s minimum window size while the panel is docked, so the floor the app declared is a floor on the app and not on the app less the dock (the pomodoro’s report, 2026-09-12: a 620×500 minimum with a 340 px dock left the app 280 px, below the tier it was drawn to fit). Read after a frame, since the handle’s drag and the placement buttons land in one.

Source§

impl Core

Source

pub fn handle_input(&mut self, ev: InputEvent) -> Vec<UiEvent>

Feeds one input event; returns any UI events it resolved to, hit-tested against the previous frame’s layout.

Source

pub fn press(&mut self, key: KeyPress) -> Vec<UiEvent>

One whole key going down: both channels, in the order a window drives them. The press reaches whatever holds key focus, and then KeyPress::edit_event asks the core for what that key means — Escape dismisses a modal, Tab walks the ring, an arrow nudges a focused slider, a printable character reaches the focused editor.

This is what a driver with a real keyboard does, so it is what a headless test should do too. Core::handle_input with a bare KeyDown is still the way to drive one channel on purpose.

Source

pub fn release(&mut self, key: KeyPress) -> Vec<UiEvent>

The same key coming up. One channel, because only one has a second half: the editing keys act on the way down. Paired with Core::press so a held key is a press and a release, and a sink that asked for key_up hears both.

Source

pub fn holds_key(&self, key: &KeyPress) -> bool

Whether this core delivered key’s press and has not delivered its release — the one core a KeyUp for it resolves in. What a driver with more than one core asks before routing a release: a key pressed in a window and let go while a popup borrowed its keyboard was released in the popup, which never saw the press, and the owner held it until it lost focus.

Source

pub fn access_tree(&mut self) -> &AccessTree

The access tree of the last finished frame (see crate::access): derived on the first call after a frame, then reused. A driver that never asks pays nothing.

Source

pub fn release_held_keys(&mut self)

Lets go of every key the focused sink is holding, as if the user had released them: each becomes a {kind="key", phase="up"} on the sink that took the press. Called when focus moves — a keymap that armed a mode on the way down has to hear the way up, and the node it moved to never saw the press — and by drivers when the window loses the keyboard (Cmd-Tab while a key is down otherwise leaves it stuck down forever).

Source

pub fn set_focused(&mut self, focused: bool)

The driver’s report that this window gained or lost the keyboard: env.focused, plus the one rule that rides on it — a window that lost the keyboard lets go of every key its sink was holding, since the OS stops delivering key events to it and the release would never arrive. The rule lives here rather than in each driver so a Node test’s setEnv({focused: false}) and a C host’s kui_env_set do what the windowed runner does, instead of each remembering to. The synthetic ups are pending, like release_held_keys’s, and so are the releases of the buttons onButton nodes held.

Source

pub fn chord_sink(&self) -> Option<Key>

The sink a chord pressed now would reach, if any: the focused sink, the nearest one above the focused control, or the root’s with nothing focused. What a driver asks before greying a menu row that spells a chord — a sink that would hear ⌘C may do anything with it, so the row stays lit.

Source

pub fn copy_selection(&self) -> Option<String>

The window’s selected text, for clipboard integration: the selection in a selectable scope when there is one, else the focused editor’s. Only one of the two exists at a time — starting either clears the other — so this asks in that order rather than merging them.

Source

pub fn cut_selection(&mut self) -> Option<String>

Cuts the focused editor’s selection, returning the removed text. A cut is an edit like any other, so the editor’s changed is pending for the caller to route — like a resize, since the caller is not answering an input event.

Source

pub fn edit_text(&self, key: Key) -> Option<String>

Current text of an editor by key.

Source

pub fn set_edit_text(&mut self, key: Key, text: &str) -> bool

Replaces an editor’s text, leaving the caret at the end.

The key need not have an editor behind it yet: an update that opens a rename field runs a frame ahead of the view that declares it, so the text is held and seeds the editor the next frame declares under this key, over its initial. Held for that one frame — a key nothing declares on it drops its text and raises crate::diag::EDIT_TEXT_WITHOUT_EDITOR.

Returns whether the text reached an editor now. false is the held case: nothing on screen changed, and a driver that redraws on it re-lowers the tree that declares no editor, which is the frame the hold expires on — so a binding asks for a redraw only on true.

Source

pub fn set_edit_text_by_label(&mut self, label: &str, text: &str) -> bool

The same call by the name the view declares — an editor’s key prop / label — for the app that has no key to give: the hex key comes from an event the node fired, and an editor a rename opens for the first time has fired none.

A label some frame declared resolves now (Core::key_of) and this is Core::set_edit_text on that key. One nothing has declared — a first open, or a second one, since an editor closed in between was in no recent frame — is held for the next frame that declares an editor under it, and seeds it there. An editor retained while its key was off screen takes the text over its draft, which is what a set_edit_text by key cannot say.

Held for that one frame: a label nothing declares on it drops its text and raises crate::diag::EDIT_TEXT_WITHOUT_EDITOR.

Returns whether the text reached an editor now, as Core::set_edit_text does; a label held is false.

Source

pub fn cursor_shape(&self) -> CursorShape

The pointer shape for wherever the pointer is now, derived from the frame’s hit regions (see crate::cursor). Per-frame output like the window commands, but a query rather than a drain: it is a state, not a queue, so a driver reads it after each input and each frame and only touches the window when the answer changes. Headless drivers never read it, and the core stays device-free.

Source§

impl Core

Source

pub fn ime_rect(&self) -> Option<Rect>

See the ime_rect field. None when nothing with a caret is focused: neither a stock editor nor a sink holding a line that declares one.

Source

pub fn has_caret(&self) -> bool

Whether there is a caret to blink: a focused stock editor’s, or the caret a line under the focused custom editor declares — unless that line declares it caret_solid, which is a caret to anchor the IME and read to assistive technology but not one to blink. A driver arms its blink clock while this is true and leaves the caret solid otherwise.

Source

pub fn caret_stamp(&self) -> u64

Changes whenever the caret moved or focus changed — the stock editor’s caret through typing or a click, a custom editor’s through the caret row it declares — so a driver comparing it across frames re-arms the blink with the caret solid, the way a caret that just moved is never mid-blink.

Source

pub fn caret_visible(&self) -> bool

The blink phase, as the driver last set it: true draws the caret. The stock editor reads it itself; a custom editor reads it in view (Ui::caret_visible) and skips its caret node on the off phase, so the two blink in step — and a window without the keyboard, where the driver parks it hidden, shows neither. Headless it stays true.

Source

pub fn set_caret_visible(&mut self, visible: bool)

Sets the blink phase; the driver’s, on its clock. A frame is the caller’s to ask for.

Source§

impl Core

Source

pub fn begin_slot(&mut self, name: &str) -> Option<Key>

Declares a slot under its full name at the cursor and returns its key — parent.str(name), recorded for key_of — or None when it cannot be declared: outside a frame, or a second time in one frame, which is the duplicate-slot warning.

An extension may declare one too, and its key nests under the slot the extension is itself filling, like any of its nodes. Names stay frame-wide because namespaces are: there is one extension called todos however deep the thing that loaded it sat, so todos/panel is one slot and declaring it twice is the same warning wherever the two declarations came from.

Source

pub fn slot_declared(&self, name: &str) -> bool

Whether the full name name was declared this frame so far — or is the slot of a devtools tab declared this frame, which counts whether or not the panel mounted it, so a plugin whose only slot is a tab is quiet with the panel off.

Source

pub fn fill( &mut self, slot: &Slot<'_>, origin: OriginId, f: impl FnOnce(&mut Ui<'_>), )

Runs f as the fill of slot under origin: every node it opens is tagged origin, keyed as a child of slot.key (an extension’s keys depend on the slot’s full name, which the host’s namespace makes its own, and on nothing the host built around them), counted from zero, and closed for it if it returns with any open (decision 5, with the unbalanced-extension warning). The host’s origin, counter and namespace are what they were when f returns, so the host’s next child is keyed as if the fill had not happened.

Source

pub fn fill_within( &mut self, slot: &Slot<'_>, origin: OriginId, filler: Option<&mut dyn Fill>, f: impl FnOnce(&mut Ui<'_>), )

fill, with filler answering the slots the fill itself declares — what Extensions::fill_one hands in, so an extension can host extensions of its own (see crate::slot). None is plain fill: nothing answers, so a slot declared inside draws nothing.

Source§

impl Core

Source

pub fn focus_next(&mut self, forward: bool)

Moves keyboard focus to the next / previous focusable node in tree order (from the last laid-out frame; see access::focusable), wrapping around; with no current focus, enters the first (or last, going backwards). What Tab does. The landing node scrolls into view, and the focus shows (ring or focus_bg), as keyboard focus should.

Source

pub fn region(&self) -> Option<Key>

The focus region in effect: the node whose subtree Tab walks, or None for the main ring.

Source

pub fn focus_region(&mut self, key: Option<Key>)

Asks to enter a focus region at the end of the frame being built (None is the main ring): focus lands on what that region last held if the node is still there, else its ring’s initial_focus, else the ring’s first stop, and shows. Deferred like request_focus_step, and for one more reason: the caller that toggles a dock on and enters it in one update names a node the last frame did not build. A key the frame does not declare as a region raises focus-region-without-node and moves nothing.

Source

pub fn focus_region_by_label(&mut self, label: &str)

focus_region by the label the region’s node declares — the spelling a caller has for a node that does not exist yet.

Source

pub fn modal(&self) -> Option<Key>

The key of the modal in effect this frame, if any.

Source

pub fn is_focused(&self, key: Key) -> bool

Whether key holds keyboard focus — any node (see focus).

Source

pub fn focus(&self) -> Option<Key>

The node holding keyboard focus: an editor, an on_key sink, or a control Tab (or assistive technology, or set_focus) put it on.

Source

pub fn focus_visible(&self) -> bool

Whether focus got where it is by keyboard or assistive technology rather than a click — when it shows (the default ring, or the node’s focus_bg).

Source

pub fn set_focus(&mut self, key: Option<Key>)

Moves keyboard focus (None blurs) — the app’s door: Ui::focus, Node’s focus, kui_focus, Lua’s env.set_focus. Any node can be focused this way; only focusable ones (see access::focusable) are reached by Tab. A move made here is the app saying where focus goes, and it stands at the frame’s end against a closing modal’s restore, the way a keyFocus edge does: the restore is the default for an app that said nothing, and this is an app that did. The core’s own moves — a press, a Tab, an autofocus, the restore itself — go through move_focus and say nothing.

Source

pub fn request_focus_step(&mut self, forward: bool)

Asks for a Tab step (forward) / Shift-Tab step at the end of the frame being built. focus_next moves focus now, against the last finished tree — which is what a driver handling a key press between frames wants, and exactly what a view cannot use, since its own tree does not exist yet. A view asks with this instead and the step lands on the frame it is declaring.

Source

pub fn set_key_focus(&mut self, key: Option<Key>)

Declares a node focused this frame (None blurs at once). The declaration is edge-triggered: the node takes focus on the first frame it is declared and keeps being declared without effect afterwards, so a view that repeats it every frame (an app that owns its keyboard, a keyFocus prop) does not clobber the focus a Tab press or a click moved. Programmatic focus keeps the modality of the last input (it shows after keyboard use, not after a click). To move focus at any time, set_focus.

Source

pub fn key_focus(&self) -> Option<Key>

The node holding keyboard focus (the same as focus; kept from when only key sinks and editors could).

Source§

impl Core

Source

pub fn set_inspect(&mut self, on: bool)

Turns the per-frame snapshot on or off (see the module doc). Off by default; a devtool that reads Self::nodes turns it on once. The host’s ask alone: the core’s own devtools panel asks for the snapshot separately, per frame, while its tree tab shows or it is picking, and neither ask turns the other off.

Source

pub fn inspect(&self) -> bool

Whether the host asked for the snapshot.

Source

pub fn nodes(&self) -> Vec<NodeInfo>

The last finished frame’s nodes, in tree order — empty until Self::set_inspect asked for them and a frame has finished since. Rects in the host’s viewport coordinates, like every other readback (layout_of, scroll_geometry, text_hit): under a left dock the snapshot itself is kept in window px for the panel’s outlines, and this is the translated copy.

Source§

impl Core

Source

pub fn menu(&self) -> Option<&Menu>

The menu this window has open, if any.

Source

pub fn set_native_menus(&mut self, on: bool)

Tells the core that this host shows menus itself — an NSMenu, a TrackPopupMenu, whatever the platform has. The core then keeps the open menu as state and does not draw it: the host reads menu(), shows it, and reports back with Self::activate_menu_item or Self::close_menu.

Declared once by the driver, not per menu, because it is a fact about the host and not about any one menu. Off by default: a host that says nothing gets the drawn menu, which is every binding’s starting point and the only thing a headless test can see.

Source

pub fn set_lookup_available(&mut self, on: bool)

Tells the core that 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 it the core neither offers nor asks, because an item that does nothing is worse than an item that is not there.

Source

pub fn lookup_available(&self) -> bool

Whether the host said it can show a definition panel.

Source

pub fn native_menus(&self) -> bool

Whether the host said it shows menus itself.

Source

pub fn activate_menu_item(&mut self, i: usize) -> Option<Vec<UiEvent>>

The host’s menu reports that item i was chosen: the same path a press on the drawn menu’s row takes — the core performs what it can, queues what the host must do, and returns the events the app hears (one menu event on the node the menu was about).

None when nothing was taken: no menu is open, or row i cannot be chosen — a disabled row, a separator — in which case the menu stays open and nothing is posted, since a native menu never reports such a row and the drawn one has no click on it, so a door that names one (activateMenuItem(1) over a select whose second option is disabled) should be answered the way the pointer would be, rather than handing the app a choice it disabled. An index past the end closes the menu and posts nothing (Some and empty), which is what a host reporting a row this build does not know should do.

Source

pub fn activate_menu_path(&mut self, path: &[usize]) -> Option<Vec<UiEvent>>

Self::activate_menu_item for a row inside a submenu, by its path: [2, 0] is the first row of the third row’s submenu (MenuItem::at_path) — what a host whose own menu nests them (an NSMenu’s submenus) reports (backlog F128). A row that opens a submenu is refused like a disabled one: the platform opens it and never reports it chosen. A path that names no row closes the menu and posts nothing, as an index past the end does.

Source

pub fn lookup_text(&self) -> Option<String>

What the selection would be looked up as, or None when it is not something to look up.

A definition panel answers a word or a short phrase. Handed a paragraph it draws the whole thing back over the page as one enormous highlighted strip and then says “No Results Found” — seen in the field, 2026-09-09 — so a selection that spans lines, or runs past 100 characters, is neither offered nor asked about. A force click always passes: it selects one word.

Source

pub fn open_menu(&mut self, menu: Menu)

Opens one. A second replaces the first: a window has one menu, the way it has one selection and one focus.

Nothing is drawn here. The next frame draws it, because the menu is state and the frame is a function of state — which is also what makes an app that never pumps another frame after a right-click a bug the app can see rather than a menu that appears out of turn.

Source

pub fn close_menu(&mut self) -> bool

Closes it, and every submenu open in it. Returns whether one was open.

Source

pub fn menu_submenus(&self) -> &[usize]

The submenus open in the drawn context menu: the row opened at each level, outermost first — [2] is the third row’s submenu, [2, 0] that and the submenu of its first row. Empty when none is, and always while the host shows menus itself (backlog F128).

Source

pub fn take_menu_actions(&mut self) -> Vec<MenuAction>

What choosing an item left for the host: clipboard work, which is the host’s in this library. Drained like the window and audio commands, and empty on every frame of an app whose menus are all its own.

Source§

impl Core

Source

pub fn declare_menu_bar(&mut self, bar: MenuBar)

Declares the application menu for this frame.

Sticky, and diffed: declaring the same bar again costs one comparison and changes nothing, a different one bumps Self::menu_bar_revision for the driver to notice, and an empty MenuBar is how an app takes the bar away. A frame that says nothing leaves the last declaration standing — which is what lets a palette window declare no menu and leave the document window’s bar alone.

Every item’s accelerator is normalized on the way in: a portable "mod+s" becomes the platform’s own spelling ("⌘S", "Ctrl+S"), so the drawn bar and the platform’s read the same and the platform’s can bind the key. A spelling kui cannot parse is left exactly as written and drawn as written — an app’s own shortcut is the app’s.

Source

pub fn menu_bar(&self) -> Option<&MenuBar>

The declaration in force, if any frame has made one.

Source

pub fn menu_bar_revision(&self) -> u64

Bumped whenever the declaration changes. A driver keeps the number it last applied and touches the platform only when they differ — the menu-bar analogue of the title diff, and the reason re-declaring an unchanged bar every frame costs nothing.

Source

pub fn set_native_menu_bar(&mut self, on: bool)

Tells the core that the platform owns the menu bar — macOS’s, which is not in any window. The drawn bar then draws nothing, and the driver is the one that hands the declaration over and reports what was chosen.

Off by default, like Self::set_native_menus: a host that says nothing draws its own bar, which is what every headless test and every binding without a runner sees.

Source

pub fn native_menu_bar(&self) -> bool

Whether the platform said the menu bar is its.

Source

pub fn menu_bar_open(&self) -> Option<usize>

Which menu of the drawn bar is open, if any. Retained by the core because it is the one thing the widget cannot derive from the frame — and always None while the platform draws the bar, since then the open menu is the platform’s.

Source

pub fn menu_bar_submenus(&self) -> &[usize]

The submenus open in the drawn bar’s open menu, as Self::menu_submenus reads the context menu’s (backlog F128).

Source

pub fn set_menu_bar_open(&mut self, menu: Option<usize>)

Opens one of the drawn bar’s menus, closes it (None), and is what a press on a title goes through. Public because a keymap is as good a reason to open the File menu as a click is; out of range closes.

Source

pub fn activate_menu_bar_item( &mut self, menu: usize, item: usize, ) -> Vec<UiEvent>

The platform’s menu bar reports that an item was chosen: the same path a press on the drawn bar’s row takes. The core performs the standard roles it can, queues what the host must do (take_menu_actions) and returns the events the app hears.

An index past the end does nothing, which is what a host reporting a row this build does not have should do.

Source

pub fn activate_menu_bar_path( &mut self, menu: usize, path: &[usize], ) -> Vec<UiEvent>

Self::activate_menu_bar_item for a row inside a submenu of menu menu, by its path (crate::menu::MenuBar::item_at) — what a platform bar whose menus nest reports (backlog F128). A row that opens a submenu, a dead row or one under a dead row or menu, or a path that names none, does nothing.

Source§

impl Core

Source

pub fn add_fragment(&mut self, wgsl: &str) -> Option<FragmentId>

Registers a WGSL fragment function for a fragment node. The app writes one function:

fn fragment(in: FragmentIn, params: array<vec4<f32>, 4>) -> vec4<f32>

and the core wraps it in the prelude and epilogue that give it the node’s rounded box, the inherited clip, the group opacity and the blend (see crate::fragment). None when the source does not compile, with a fragment-rejected warning carrying naga’s message in the app’s own line numbers — so a bad shader is a warning at registration, in a headless test included, and never a blank box in a window.

Idempotent by source: the same text gets the same handle without validating again, so a view may call this every frame. Registering at startup is still the advice, because the backend builds a pipeline the first time it sees a handle.

Source

pub fn remove_fragment(&mut self, id: FragmentId)

Forgets a registered fragment. Nodes still naming it draw nothing, and the next frame any window draws has the backend drop the pipelines it built for it.

Source

pub fn fragment_module_source(&self, id: FragmentId) -> Option<String>

The whole WGSL module behind a fragment handle — the app’s source between the core’s prelude and epilogue — which is what a backend compiles. A host rendering the display list itself asks for this rather than assembling its own, so what it compiles is what the core validated.

Source

pub fn add_font_data(&mut self, data: Vec<u8>) -> Option<FontId>

Registers a font from its file bytes (TTF/OTF/TTC); None when the data holds no usable face — none the font database can read, or none whose glyphs can be measured (no head, hhea or hmtx). Shape with it via TextStyle::font.

Source

pub fn load_font_file(&mut self, path: impl Into<PathBuf>) -> Option<FontId>

Registers a font file (TTF/OTF/TTC) by path, memory-mapped by the font database; None when it cannot be read or holds no usable face (see add_font_data). Shape with it via TextStyle::font.

Source

pub fn load_fonts_dir(&mut self, dir: impl AsRef<Path>) -> usize

Loads every font file under dir (recursively) into the font database, so their families become available to add_system_font by name; returns how many faces were added. A face whose glyphs cannot be measured is left out and not counted. A bundled fonts/ folder next to the app is the usual case.

Source

pub fn reload_system_fonts(&mut self) -> usize

Scans the system’s fonts again and brings this session’s font database up to it: a face installed since the last scan joins it, one uninstalled leaves it. Returns how many faces came and went, 0 when nothing did.

The system’s fonts are scanned once a process, and every session starts from that scan, so a font the user installs while the app runs is not seen until something asks. The winit runner (kui-native) asks itself when macOS or Windows says the installed fonts changed; a host with its own windowing, or on Linux, where fontconfig says nothing, calls this when it has reason to think the set changed (a “fonts” pane opening, the window taking focus back). It opens every font file on the system — tens of milliseconds on a Mac’s 1300 faces — so it is not a per-frame call. Sessions made after it start from the new scan; another session that already exists keeps what it has until it calls this too.

Faces still installed keep their handles and their place in every cache; fonts the app loaded itself (add_font_data, load_font_file, load_fonts_dir) are not touched. Every window of the session shapes its text again on its next frame, since fallback can land on a new face anywhere; every one of them owes that frame (animating), and each window’s next frame reports a fonts event to the host, for an app that keeps the font list in its model. A face whose file was replaced in place, under the same path, is not read again.

Source

pub fn add_system_font(&mut self, name: &str) -> Option<FontId>

The handle for a font family by name ("Menlo", "Antonio") — installed on the system or loaded with load_fonts_dir / load_font_file; None when no face matches (see system_font_families). Idempotent: the same family gets the same handle, so views can call it every frame.

Source

pub fn set_fallback_fonts(&mut self, fonts: &[FontId])

The families asked, in order, for a character the text’s own family has no glyph for — before the platform’s fallback list, whose first choice is the system’s interface face: proportional on macOS, so a Cyrillic word in a Latin-only monospaced family was set in San Francisco. An editor names its icon face, the face it ships and a monospaced one the machine has; a family that has not got the character is passed over, and after the last the platform’s list runs as before. For every family and every kind of text in the session — plain, spans, an editor, a cell grid — and kept across reload_system_fonts. FontFamily::Mono asks them straight after its own face, ahead of the machine’s other monospaced faces, which with no list it walks first (backlog RG118). A handle that names no font is left out; an empty list is the platform’s alone.

Not a per-frame call for a list that changes: a new list builds the font system again over the same faces and every window of the session shapes its text again: each owes a frame (animating), so a driver draws the windows the call was not made through as well (backlog RG118). The same list twice is nothing.

Source

pub fn fallback_fonts(&self) -> Vec<String>

The families set_fallback_fonts named, in order.

Source

pub fn remove_font(&mut self, id: FontId)

Forgets a registered font; faces loaded from bytes leave the font database. Styles still naming it shape as sans-serif.

Source

pub fn font_family(&self, id: FontId) -> Option<&str>

The registered family name behind a font handle, if it is live. Read from this window’s mirror of the session’s fonts (see session’s module doc), which every registration refreshes and so does every frame — a font another window registered mid-frame shows up here on the next one.

Source

pub fn system_font_families(&self) -> Vec<String>

Family names of every installed font the core can see (sorted, deduplicated) — what add_system_font accepts. The names of system_fonts, which says what each is.

Source

pub fn system_fonts(&self) -> Vec<SystemFont>

Every family the core can see, installed or loaded, one per family and sorted by name — the families system_font_families names — with what its faces say they are: monospaced, the weights, an italic. Read from what the font database recorded when it scanned each face, so a fonts pane showing the monospaced ones first costs no file loaded and no glyph shaped. A face whose glyphs cannot be measured never entered the database, so a family of only such faces — macOS’s GB18030 Bitmap — is not listed.

Source

pub fn add_sound(&mut self, bytes: Vec<u8>) -> SoundId

Registers a sound from its encoded file bytes (wav/ogg/mp3/flac — the driver’s backend decodes; the core only keeps the bytes).

Source

pub fn remove_sound(&mut self, id: SoundId)

Forgets a sound; the driver drops its decoded copy. Playbacks already running keep going.

Source

pub fn play(&mut self, sound: SoundId, opts: PlayOptions) -> PlaybackId

Starts a playback; the returned id addresses it in stop / set_volume / pause / resume. With a tag in the options, the playback finishing on its own comes back as {kind="sound", phase="ended", playback, tag} on the current origin’s root — the host’s, or the extension’s during its view.

Source

pub fn stop(&mut self, playback: PlaybackId, fade_ms: f32)

Stops a playback, fading over fade_ms (0 = at once). A stopped playback never reports ended.

Source

pub fn set_volume(&mut self, playback: PlaybackId, volume: f32, tween_ms: f32)

Sets a playback’s volume (linear amplitude), tweening over tween_ms.

Source

pub fn pause(&mut self, playback: PlaybackId, fade_ms: f32)

Source

pub fn resume(&mut self, playback: PlaybackId, fade_ms: f32)

Source

pub fn set_master_volume(&mut self, volume: f32, tween_ms: f32)

Sets the master volume (linear amplitude), tweening over tween_ms.

Source

pub fn audio_node(&mut self, spec: AudioSpec) -> Key

An audio node: a playback retained by key for as long as the view keeps declaring it — present means playing (once, or looped), gone means stopped; volume / paused changes apply live, a changed src restarts. The key is auto-assigned from the tree position; see audio_node_keyed for a stable label. Draws nothing and takes no layout space. The mount is this window’s: it is reconciled against this window’s frames, and another window’s frame declaring nothing leaves it playing.

Source

pub fn audio_node_keyed(&mut self, label: &str, spec: AudioSpec) -> Key

audio_node with a label-derived key (stable across reorders).

Source

pub fn playback_of(&self, key: Key) -> Option<PlaybackId>

The playback an audio node of this window holds, if it is mounted — after the frame that declared it has finished.

Source

pub fn take_audio_commands(&mut self) -> Vec<AudioCommand>

Drains the audio commands queued since the last drain. Frame drivers apply them to a real device after each input dispatch and after each frame; headless drivers may simply never call.

Source

pub fn audio_ended(&mut self, playback: PlaybackId)

The driver reports a playback finished on its own (not stopped). A tagged playback becomes an ended event, pending like a resize (see take_pending_events).

Source

pub fn audio_truncated(&mut self, playback: PlaybackId, at: f64)

The driver reports it stopped a playback that was still running, at seconds into the sound. When that stop was a one-shot audio node going away (or changing its src) without finish, the node is named in a TRUNCATED_PLAYBACK warning; anything else — a stop that landed after the sound ended, an imperative Self::stop, a loop, a released playback — reports nothing. The driver stays key-blind, as Self::audio_ended is.

Source

pub fn audio_refused(&mut self, playback: PlaybackId)

The driver refused a play: the device’s voices are all held, or the sound failed to decode. The playback never started, so it can never report ended — a tagged one gets {kind="sound", phase="refused", playback, tag} instead, pending like an ended is, so a view waiting on the sound is unstuck and can tell the two apart. crate::diag::PLAYBACK_REFUSED is raised on the node that asked either way, behind the usual diagnostics gate, so an untagged refusal is not silent.

Source

pub fn update_image( &mut self, id: ImageId, width: u32, height: u32, rgba: Vec<u8>, ) -> bool

Replaces an image’s pixels in place; see Resources::update_image. If the image had been drawn from the atlas its slot is forgotten — one eviction, once — and from here on it is texture-backed. A foreign or removed handle warns and changes nothing, and so does a buffer that is not width × height × 4 bytes; the return says whether the pixels were taken.

Source

pub fn update_image_with( &mut self, id: ImageId, width: u32, height: u32, fill: impl FnOnce(&mut [u8]), ) -> bool

Replaces an image’s pixels by writing them into a buffer the core recycles; see Resources::update_image_with. fill gets width × height × 4 bytes holding an earlier frame’s pixels and writes every one. Where Self::update_image takes a buffer the app allocated — and frees the one it replaces — this one stops allocating after a stream’s third update, which on Windows is most of what a 1080p update cost. Render into fill’s slice rather than into a buffer of your own to skip the copy too. fill runs while the session’s resources are borrowed, so it must not reach them through another window’s Core; that panics.

Source

pub fn image_pixels(&self, id: ImageId) -> Option<(u32, u32, Arc<Vec<u8>>)>

The pixels behind an image handle — its size and a shared handle on the bytes — for a host that renders the display list itself and meets a QuadKind::Texture quad. None for a dead or foreign handle, which is also noted as a miss.

Source

pub fn remove_image(&mut self, id: ImageId)

Unregisters an image and forgets its atlas slot — every other window’s atlas forgets its own at that window’s next frame — or, for a texture-backed one, has the next display list any window builds tell the backend to drop the texture.

Source

pub fn path_texture_count(&self) -> usize

What the session removed and no display list has carried yet, onto this frame’s — a backend frees a texture or a pipeline once, on whichever window draws next, since both are the device’s and the device is shared. And this window’s own atlas slots for images the registry no longer holds, when a removal has moved the revision since this core last looked: the atlas is per window, so the removing core’s eviction reached only its own. How many path masks this core draws from textures of their own rather than the atlas — too big for a page, or animating (ADR 0040, decisions 7 and 8). For a test of which road a path took.

Source§

impl Core

Source

pub fn reveal(&mut self, key: Key)

Scrolls the nearest scrolling ancestor of key so the node is inside it — what Tab does to the control it lands on, asked for by name. Already-visible nodes stay put.

The request resolves at the next finish_frame, against the frame that one lays out — the frame being built if this is called from a view, the one after it if from an event handler (a frame is requested, so one comes). That is what lets a view reveal a row it is declaring for the first time. If that frame does not declare key, or nothing above it scrolls, it is a no-op — the request is spent, not held for the frame that might. Two reveals before one frame into the same container are contradictory, so the last one wins there; reveals into different containers — a tab strip and the pane list under it — are not, and each lands.

Traced, the ask is "reveal" at the caller’s line.

Source

pub fn reveal_label(&mut self, label: &str)

Self::reveal by the label a node declares, resolved when the frame finishes — against the frame being built, or the next one when none is — so a view may name a row it is declaring right now, or one the frame after declares. A label that frame does not declare raises label-without-node and moves nothing.

Source

pub fn set_scroll_label(&mut self, label: &str, offset: Vec2)

Self::set_scroll by label, resolved like Self::reveal_label but before layout, so the frame that resolves it lays out at the offset.

Source

pub fn scroll_offset(&self, key: Key) -> Vec2

The retained scroll offset of the container key, as the last layout clamped it (positive = content moved up / left) — the target: while a container with a transition eases to it the content is drawn short of it, where Self::scroll_geometry says. Zero for a node that never scrolled, and for one that is not a container at all — the store keeps offsets, not membership.

Source

pub fn scroll_geometry(&self, key: Key) -> Option<ScrollGeometry>

Everything the last layout resolved for the container key: its own box, its content size, and the clamped offset — None for a key no layout has ever resolved as a scroll container. While an eased leg runs the offset is where the content is drawn rather than the target, sampled at the clock the coming frame reads, so a view slices the rows that frame shows.

This is what makes a long list affordable. The core culls glyphs by viewport but builds every child a view declares, so ten thousand rows cost ten thousand rows; with the offset and the container’s height a view can declare only the rows that can be seen and two spacers, and pay for a screenful. widgets::uniform_list is that, done.

Read during a build, it describes the frame before — the tree it came from is already cleared. That is one frame of lag on the size, so the frame after a resize slices to the old height; a row or two of overscan covers it, which is what the widget does. The rect is the same one an on_layout on that node would post, without the round trip through the app’s model, and without firing every time an enclosing container scrolls the whole list past.

Source

pub fn layout_of(&self, key: Key) -> Option<Rect>

The rect the last frame laid key out at, in logical viewport px — for a node that declared on_layout, whose rect the core keeps for the event’s edge trigger anyway. The query shape of the layout event: the same numbers, read during the next build with no event, no tag and no model field. None for a key that did not declare on_layout last frame; read during a build it describes the previous frame, like Self::scroll_geometry.

Source

pub fn set_scroll(&mut self, key: Key, offset: Vec2)

Sets the container key‘s retained offset, the way the wheel would. Takes effect at the next layout, which clamps it to that frame’s overflow: Vec2::ZERO is “jump to the top”, and a large value is “jump to the end” without knowing the content height. Writing an offset for a key that never scrolls is harmless; it just never reads back. Between two frames the write asks for the frame that lands it; from inside a view it asks for nothing, because the frame being built is that frame — the positions pass reads the store after the view has run — and a view writing every frame would otherwise be a window that never idles (the devtools’ events list and widgets::list both write this way).

Source

pub fn shift_scroll(&mut self, key: Key, drawn: Vec2, target: Vec2)

Moves key’s scroll state by the content that moved under it: drawn for where the 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 is a correction to the frame about to be laid out — the rows above the window were measured and came out another height — so it belongs to that frame, whoever calls it. A variable-height list’s anchor: widgets::list from its view, the Node and Lua ports from theirs, just before the tree they return is laid out.

Source§

impl Core

Source

pub fn selection(&self) -> Option<Selection>

The window’s text selection outside an editor, if it has one.

Source

pub fn cell_selection(&self) -> Option<CellSelection>

The window’s selection when it lives in a cells grid.

Source

pub fn set_cell_selection(&mut self, sel: CellSelection)

Sets it, clearing whatever else the window had selected.

Source

pub fn cell_at(&mut self, key: Key, point: Vec2) -> Option<CellEnd>

Where point lands in the grid key drew, as an absolute line and a column — the address a cell selection’s end is. None when the node drew no grid.

Source

pub fn select_word_in_cells( &mut self, key: Key, point: Vec2, block: bool, ) -> Option<(u64, usize, usize)>

Selects the word under point in the grid key — a double click on a terminal. Answers the span it took, as an absolute line and a half-open column range, so a drag that follows can round to it.

Source

pub fn select_line_in_cells( &mut self, key: Key, point: Vec2, block: bool, ) -> Option<(u64, usize, usize)>

Selects the whole row under point — a triple click. Edge to edge, the way a line in the middle of a linewise selection runs; the copy is what trims the blanks off the end of it.

Source

pub fn begin_cell_selection( &mut self, key: Key, point: Vec2, block: bool, ) -> bool

Starts a cell selection at point in the grid key.

Source

pub fn extend_cell_selection(&mut self, point: Vec2) -> bool

Moves the live end of a cell selection to point.

Source

pub fn cell_selection_text(&self) -> Option<String>

The selected cells as text: one line per grid row it covers, each with its trailing blanks trimmed — the rule that makes a copied screen paste like text instead of like a rectangle of spaces.

Only what the grid holds: a selection whose ends reach into the scrollback copies the lines on screen, because the lines behind it were never handed to the core.

Source

pub fn set_selection(&mut self, sel: Selection)

Sets it. The scope is a node that declared selectable; the two ends are addresses inside it (a node key and a byte in that node’s own text). Ends the frame cannot resolve paint nothing rather than something else, so setting a selection against a tree that has since changed is safe.

Clears the focused editor’s own selection: there is one selection per window.

Source

pub fn clear_selection(&mut self) -> bool

Drops the selection. Returns whether there was one.

Source

pub fn select_all_in(&mut self, scope: Key) -> bool

Selects every run in scope, first byte to last — what Select All does inside one. false when the scope drew no text.

Source

pub fn selection_hit(&self, scope: Key, point: Vec2) -> Option<Endpoint>

Where point (logical viewport px) lands inside scope, as the address a selection end is made of. None when the scope drew nothing the pointer could land in — an off-screen run is part of the scope’s text but is under no pointer.

Source

pub fn selection_text(&self) -> Option<String>

The selected text, assembled across every run the selection covers — including runs the frame built but never drew, which is what makes a selection that ran past the bottom of a scroller copy what the reader dragged over.

None with no selection; an empty string when the selection is empty or its ends no longer resolve.

Source

pub fn selection_rect(&self) -> Option<Rect>

The box the window’s selection occupies, logical viewport px — what a platform panel about that selection is anchored to. The union of the drawn runs it covers, so a selection that runs off the screen is anchored by the part the reader can see.

None with no selection, an empty one, or one whose runs the frame never drew.

Source

pub fn selection_anchor(&self) -> Option<Vec2>

Where a platform panel about the selection should point: the baseline origin of its first line, logical viewport px. See TextSystem::scope_selection_anchor.

Source

pub fn selection_html(&self) -> Option<String>

The selection as HTML — the same text selection_text gives, with the bold, the italic and the span colours it was declared with. None with no text selection; a cells selection has no styling to carry and answers None too.

Meant as the second clipboard flavour, beside the plain text and never instead of it: an editor that understands HTML takes the formatting, and everything else takes the words.

Source

pub fn selection_range(&self) -> Option<(RangeEnd, RangeEnd)>

The selection’s two ends as the app’s own addresses — the data index of the virtualised row each is in, and the byte inside that row’s text — in reading order: from precedes to whichever way the drag was made, so an app answering a selectionrange ask can iterate from..=to (the clipboard examples do). None when there is no selection, or when neither end is in a virtualised row (nothing to ask about: the core has it all). The directed pair is Self::selection_ends.

Source

pub fn selection_ends(&self) -> Option<(RangeEnd, RangeEnd)>

The 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 (None outside every virtualised row) and the byte inside that node’s own text. The directed pair, unlike Self::selection_range’s: what a test or a model that mirrors the selection reads, and what says whether a Shift-press kept the anchor. None with no text selection; a grid’s is cell_selection.

Source

pub fn request_copy(&mut self) -> CopyRequest

Asks for the selection as text, and says how the answer will come.

CopyRequest::Ready is the ordinary case: everything selected is text the core shaped, so it hands it over. CopyRequest::Asked is a selection that reaches rows a virtual list never built — the core posts {kind:"selectionrange", from:{index, byte}, to:{index, byte}} on the scope and waits for Self::answer_selection_range, because the rows behind that gap are the app’s and only the app has them.

The event goes out with the frame’s pending events, so a host that calls this outside handle_input drains take_pending_events after it.

Source

pub fn answer_selection_range(&mut self, text: &str) -> bool

The app’s answer to a selectionrange ask: the text for the range it was asked about, whole. Queues it for the clipboard the way a menu’s Copy does, and is ignored when nothing asked — a stale answer cannot overwrite what somebody copied since.

Source

pub fn set_clipboard(&mut self, text: impl Into<String>, html: Option<String>)

Puts text on the system clipboard — queued as the MenuAction::SetClipboard a menu’s Copy produces, for the host to apply at its next drain (the runner’s is after every input and every frame). html is a second flavour beside the text for a host that offers one, never in place of it.

Source

pub fn set_clipboard_secret(&mut self, text: impl Into<String>)

Puts a secret on the system clipboard the way a password manager does — queued as MenuAction::SetClipboardSecret, which the runner writes marked concealed and transient, so a clipboard manager neither shows nor keeps it. What the marks are on each platform is on the action. The text alone: a secret has no second flavour to offer.

Source

pub fn request_paste(&mut self)

Asks for what is on the clipboard — queued as the MenuAction::Paste a menu’s Paste produces. The host reads the clipboard and hands the text back as InputEvent::Paste (or a bare InputEvent::Commit), which reaches a focused editor as typing and a focused sink as {kind:"text", text, tag}, with concealed: true / transient: true beside the text when the pasteboard marked it so — so the app that asked inserts it the way it inserts a committed IME string, and never sees the clipboard any other way. The read stays on the driver’s side, where the permission lives.

One ask at a time: while a paste is outstanding — queued, or taken by the driver and not yet answered — a second ask is dropped, so a view that asks on every frame until the answer lands asks once. The answer is the Paste (or Commit) the driver sends, an empty one when the clipboard held nothing, and Core::awaiting_paste reads the state.

Source

pub fn awaiting_paste(&self) -> bool

Whether a paste ask is outstanding: asked and not yet answered with a Paste or a Commit.

Source

pub fn request_files(&mut self, dialog: FileDialog) -> bool

Asks the host for a file dialog: an Open, a Save or a folder picker, which the host shows as the platform’s own. The answer is an event, {kind:"files", paths, tag} — the drop payload’s shape, paths empty when the user cancelled — delivered to whoever asked: the host from its own view or between frames, the extension from inside its fill. A host drains the ask with Core::take_file_requests and answers with InputEvent::Files; the runner does both.

One ask at a time, as for a paste: while one is outstanding — queued, or taken and not yet answered — another is dropped and this returns false, so a view that asks every frame until the answer lands asks once. Between frames it asks for the frame that hands the ask to the host.

Source

pub fn awaiting_files(&self) -> bool

Whether a file dialog asked for is still unanswered.

Source

pub fn take_file_requests(&mut self) -> Vec<FileDialog>

The file dialog asked for and not yet taken — at most one — for the host to show. Taking it keeps the ask outstanding until the answer.

Source

pub fn begin_selection(&mut self, scope: Key, point: Vec2) -> bool

Starts a selection at point inside scope — the press half of a drag-select. Both ends land together, so nothing is selected until the pointer moves.

Source

pub fn extend_selection(&mut self, point: Vec2) -> bool

Moves the live end of the selection to point — the motion half. The anchor stays where the press put it, so dragging back past it selects the other way rather than starting again.

Source

pub fn keyboard_select(&mut self, scope: Key, key: EditKey, mods: Mods) -> bool

A keyboard’s selection in a selectable scope: Shift with an arrow, Home or End on a focused node inside scope — the scope itself when it is focusable, a control inside it — moves the selection’s focus the way the stock editor’s Shift- motions move its caret: a character (a word with mods.word) left or right through the scope’s runs in order, Home and End to the scope’s first and last byte. Nothing selected yet, the anchor is placed at the scope’s start, so Shift-End from a freshly focused label selects it whole. Returns whether the selection changed. Answered from the frame that finished, like a drag; the endpoints carry their virtual rows like every other selection, so a copy past the built range asks the app for the text, as any virtualised selection does. Up and Down are not motions here: a scope has no line geometry a caret could keep a column in.

Source

pub fn select_word_at( &mut self, scope: Key, point: Vec2, ) -> Option<(Key, usize, usize)>

Selects the word under point inside scope — a double click, and (on macOS) a force click. Answers the span it took, in the node’s own bytes, so a drag that follows can round to it.

Source

pub fn select_run_at( &mut self, scope: Key, point: Vec2, ) -> Option<(Key, usize, usize)>

Selects the whole run under point — a triple click, which takes the line a label is. Answers the span, like select_word_at.

Source

pub fn select_word_under(&mut self, scope: Key, point: Vec2) -> bool

Selects the word under point in scope, whichever way the scope addresses itself — what a double click takes, and what a force click takes before it asks for a definition. false when there was no word there.

Source§

impl Core

Source

pub fn declare_window(&mut self, name: &str, config: WindowConfig)

Declares that a window named name exists this frame.

The window opens on the first frame any core declares it — that frame’s finish_frame queues a crate::WindowCommand::Open with the id the core assigned and raises {kind:"window", phase:"opened", name, id} — and closes, with a Close and a phase:"closed", on the first frame none does. Declared every frame it costs nothing after the first.

config is read on that opening edge and never again: re-declaring a live window at another size changes nothing, because the user owns its geometry once it exists. Where two declarations of one name disagree on that edge, the lowest declaring window’s first declaration wins and crate::diag::DUPLICATE_WINDOW_CONFIG says so. A window the user closed (see Self::window_closed) does not reopen while it is still declared — the declaration has to stop and start again — and keeps raising crate::diag::WINDOW_DECLARED_WHILE_CLOSED until it does. "main" names the window the launcher opened and is always live.

Source

pub fn window_name(&self) -> Rc<str>

The name of the window this core draws: "main" for WindowId::MAIN, else the name the declaration that opened env.window.id used. A driver that gave a core an id the session never opened gets the id spelled out, so the answer is never empty.

Source

pub fn windows(&self) -> Vec<(WindowId, Rc<str>)>

Every window of the session that is open right now — main first, then in the order they opened — as (id, name). What the declaration diff has asked for, not what the driver has shown: the two agree once the driver drains its commands.

Source

pub fn window_closed(&mut self, id: WindowId)

The driver reports that the OS closed window id — its close button, a keyboard shortcut, the window manager. The window is gone and stays gone while its name is still declared (the app has to stop declaring it and start again to reopen it; see Self::declare_window); its own declarations leave the union, so whatever only it declared closes too. Raises {kind:"window", phase:"closed", name, id} for the app, pending like a resize. Nothing happens for the main window (closing it ends the app) or for a window the diff already closed.

Source

pub fn dismiss_window(&mut self, id: WindowId, reason: DismissReason)

The driver reports that window id was asked to go away — a press landed outside it, or Escape reached it (see crate::window::DismissReason). Raises {kind:"dismiss", reason, name, id} on the root, pending like a resize, and closes nothing: only the app can stop declaring the window, and it does that on the frame it decides to, the way a modal closes. So an app that graduates a dropdown from a modal float to a popup window changes its declaration and keeps its handler.

Both facts behind it are the OS’s — a press outside a window lands in another surface, and a non-activating popup never holds the keyboard — so the core cannot notice either; a driver reports them the way it reports a close (Self::window_closed). Nothing happens for a window the session has not opened.

Source

pub fn push_window_command(&mut self, cmd: WindowCommand)

Queues a window command as if chrome had produced it, so apps can close/minimize/maximize from a keymap or command line. Drained by the frame driver with the rest.

Source

pub fn set_window_size(&mut self, window: WindowId, size: Size)

Asks the driver to resize window to size (logical px). Queued the way reveal and play queue theirs: a request the driver applies on its next pump — after this input dispatch if called from a handler, after this frame if called from a view — and one a headless driver never applies, since it never drains. The window answers through the ordinary resize event, with the size it actually became.

Source

pub fn focus_window(&mut self, window: WindowId)

Asks the driver to give window keyboard focus; queued like Core::set_window_size. Whether the window manager agrees shows up as env.focused on the frames that follow, not as a reply.

Source

pub fn take_window_commands(&mut self) -> Vec<WindowCommand>

Drains window intents queued since the last drain — by chrome nodes, by push_window_command, set_window_size and focus_window — in the order they were queued. Frame drivers call this after each input dispatch and each frame and apply the commands to the real window; headless drivers may simply never call.

Source

pub fn set_window_title(&mut self, title: &str)

Declares this frame’s window title. Like all frame state it’s data: the driver diffs against what’s applied and only then touches the window. Undeclared frames leave the title alone; last writer wins.

Source

pub fn window_title(&self) -> Option<&str>

The title declared this frame, if any (for the frame driver).

Source

pub fn set_always_on_top(&mut self, on_top: bool)

Declares that this frame wants the window above every other app’s: a floating palette, a picture-in-picture player, a timer. Frame state like the title, and the driver applies it the same way — set_window_level when it differs from what is applied, nothing when it does not — but it defaults to false rather than “leave as-is”, so a frame that stops declaring it lowers the window again and a pin button is a toggle on the app’s own state. Whether the platform has a level to set is env.window.always_on_top: the driver’s record of what it set, false on Wayland (where winit has no call for it) however often the app asks — and not a query, so a level the OS dropped afterwards (a fullscreen space, a tiling manager) is not reported. A popup’s level is its own whatever its owner declares.

Source

pub fn always_on_top(&self) -> bool

Whether this frame asked for the window to stay on top (for the frame driver); false for a frame that never said.

Source

pub fn set_secure_input(&mut self, on: bool)

Declares that this frame wants the keyboard to this window kept from other processes while the window has it — macOS’s Secure Keyboard Entry, what a terminal turns on at a password prompt. Frame state like always_on_top: a frame that stops declaring it turns it off, so an app asks on every frame the prompt is up and never has to remember to undo it.

The runner owns the platform call and its balance: it enables secure input only while a window whose frame asked has the keyboard, and disables it when that window loses the keyboard, closes, stops asking, or the app exits — Apple’s rule for it, since while it is on no other process can read the keyboard at all (a launcher’s hotkey, a text expander, an accessibility tool). EnableSecureEventInput is process-wide and counted, and the runner holds at most one count however many windows ask. Nothing happens on other platforms, which have no such switch.

Source

pub fn secure_input(&self) -> bool

Whether this frame asked for secure keyboard entry (for the frame driver); false for a frame that never said.

Source

pub fn set_option_as_alt(&mut self, option_as_alt: OptionAsAlt)

Declares which Option keys act as Alt in this window on macOS: a dead key under that Option — ⌥u, ⌥e, ⌥i, ⌥n, ⌥` — then arrives as the chord <A-u> rather than starting an accent the app never hears, and a key under it types nothing, as under Control. Frame state like always_on_top, default OptionAsAlt::None: a frame that stops declaring it gives the Option keys back to the layout, so an app declares it on every frame — from a setting, say — and never has to undo it.

The runner applies it to the window on change and never per frame. A popup never has the keyboard on macOS — its keys come through its owner, which stays key — so the owner’s declaration is the one a popup’s keys are read under. Nothing happens on other platforms, whose Alt composes nothing.

Source

pub fn option_as_alt(&self) -> OptionAsAlt

Which Option keys this frame asked to act as Alt (for the frame driver); None for a frame that never said.

Source

pub fn set_ime_off(&mut self, off: bool)

Declares that this window takes the keyboard as keys, with the platform’s input method off: no composition and no candidate window, and on a Mac no dead key waiting for the next one and no press-and-hold — which is an input method too, so a held letter repeats instead of opening the accent picker, whatever the user’s ApplePressAndHoldEnabled says. A key’s text is still the layout’s character; what goes is everything the OS would have composed from it. What a modal editor’s normal mode wants, where jjjj is how one moves and a Japanese IME left on eats the keymap; its insert mode stops declaring it and gets both back. Frame state like always_on_top, default off: a frame that stops declaring it gives the window its input method back, so an app declares it on every frame its mode wants it and never has to undo it.

The runner applies it to the window on change and never per frame (winit’s set_ime_allowed); a composition in progress when it turns off is ended without a commit, as an empty preedit. It is the window’s, not a node’s: a stock editor focused under it composes nothing either. A popup’s keys arrive through its owner, so the owner’s declaration is the one they are read under. On Windows and Linux the window’s IME is disabled the same way, and that is all: their dead keys are the layout’s (WM_DEADCHAR, xkb compose), winit composes them whatever the IME says, and they still compose.

Source

pub fn ime_off(&self) -> bool

Whether this frame asked for the input method off (for the frame driver); false for a frame that never said.

Source§

impl Core

Source

pub fn theme(&self) -> &Theme

This window’s palette, as of this frame. Resolved from Core::theme_source and env.system at the start of every frame, so it is already right by the time a view runs.

Frame-stable on purpose: every widget in one frame paints from the same palette, whatever the driver does to env while the view runs. A host that writes env.system directly and wants the new answer before its next frame calls Core::refresh_theme; every env setter a binding exposes already does.

Source

pub fn refresh_theme(&mut self)

Re-resolve the palette from env.system now, rather than at the start of the next frame. What an env setter calls after writing.

Source

pub fn set_system(&mut self, system: SystemEnv)

Writes what the user set in the OS and re-resolves the palette from it, so a host that pushes the appearance and reads the theme back before its next frame sees the answer. The one door for a binding’s env setter: writing env.system by hand and forgetting the refresh was a decision each of them had to remember.

Source

pub fn env_facts(&self) -> EnvFacts

The env reading’s inputs (schema::ENV_FIELDS): the stored env and the frame’s own facts — viewport, scale, focus — that ride in the same reading.

Source

pub fn has_accent(&self) -> bool

Whether anyone actually chose the accent — the OS reported one, or the app set or pinned one — as opposed to the palette falling back to kui’s own blue.

The question the accent row asks before it repaints anything: that row has always meant “the accent colour where there is one, the bg I declared where there is not”, so a view can name its own fallback and a host that knows nothing changes nothing. The theme widened where the accent comes from without widening whether there is one.

Source

pub fn theme_source(&self) -> ThemeSource

Where the palette comes from. ThemeSource::Derived by default.

Source

pub fn set_theme_source(&mut self, source: ThemeSource)

Change where the palette comes from. Takes effect on the next frame, and immediately for anything reading Core::theme after this call, so a host may set it before its first frame or in a handler and get the same answer either way.

Source

pub fn set_theme(&mut self, theme: Theme)

Pin a palette: this exact Theme, following neither the OS’s appearance nor its accent. Shorthand for ThemeSource::Pinned.

Source

pub fn set_accent(&mut self, accent: Color)

Keep following the OS’s light/dark, but paint this accent instead of the OS’s. Shorthand for ThemeSource::DerivedWithAccent, and what an app with a brand colour wants.

Source

pub fn derive_theme(&mut self)

Go back to following the OS for both — the default.

Source

pub fn metrics(&self) -> &Metrics

The sizes the stock widgets are built from — the palette’s other axis (crate::metrics). Metrics::default until the app sets one; nothing in the OS is followed.

Source

pub fn set_tokens(&mut self, tokens: Tokens)

Declare the tokens the running origin references by name: the host’s outside a fill, the filling extension’s inside one. Replaces that origin’s table whole, so an app whose lengths change with a viewport tier declares again on resize. A name a role owns is dropped with a reserved-token warning, once per name. A derived token whose source did not resolve is dropped with unknown-token, naming both.

Source

pub fn tokens_declared(&self, origin: OriginId) -> bool

Whether origin has declared a table — what an extension asks before declaring the one it was loaded with, so a per-frame view declares once.

Source

pub fn tokens(&self) -> Option<&Tokens>

The running origin’s own table, if it declared one.

Source

pub fn token_lookup(&self) -> TokenLookup<'_>

What a $name in a prop resolves to this frame: the running origin’s table over the host’s, the theme’s and metrics’ roles in front of both. What every binding lowers a reference through.

Source

pub fn warn_unknown_family(&mut self, name: &str)

A binding lowered a family that names nothing installed or loaded: raise unknown-family, once per name. The text shapes as sans, which is what the message says.

Source

pub fn warn_unknown_token(&mut self, err: &TokenError)

A binding lowered a reference that did not resolve: raise unknown-token, once per name, saying which slot asked. The slot keeps its default, which is what the message says.

Source

pub fn set_metrics(&mut self, metrics: Metrics)

Makes metrics the frame’s: every stock widget from the next node on is built from it, and ui.metrics() reads it back. Logical px, before env.scale; a density is the app’s to choose (Metrics::compact, Metrics::scaled).

Source

pub fn new() -> Self

A core with a session of its own — one window, nothing shared.

Source

pub fn new_in(session: &Session) -> Self

A core joining an existing session: it draws with the same fonts, images, sounds, shaping caches and glyph atlas as every other core constructed against session, and plays through the same audio device. Everything else — tree, focus, scroll, viewport — is this window’s alone.

Source

pub fn measure_text( &mut self, content: &str, style: &TextStyle, max_w: Option<f32>, ) -> TextMetrics

Measures content in style without adding a node: its unwrapped size, or with max_w (logical px) its size once wrapped to that width — what layout would give a text node with that content and style, wrap / max_lines / ellipsis included. Logical px at the scale of the current or last frame (1 before any frame). Shapes through the text cache, so measuring a string and then drawing it shapes once.

Source

pub fn measure_rich_text( &mut self, spans: &[Span<'_>], base: &TextStyle, max_w: Option<f32>, ) -> TextMetrics

measure_text for a rich-text paragraph.

Source

pub fn text_hit(&self, key: Key, point: Vec2) -> Option<TextHit>

Where a point lands in the text node key drew: a byte offset into its content and the visual row within that node — counted across every run the key covers by where the rows sit, so a line row of inline runs is one row and a wrapped run as many as it wrapped to; not the ordinal line node a pointer event names — or None for a key that is not a text node or was not drawn. A role="none" subtree under the key (a gutter) is not its text, as the access tree reads it. point is logical viewport px — the x/y a click or drag event carries — so a custom editor turns the event into a caret position with one call instead of measuring prefixes or assuming a cell width. Answered from the frame that finished: between frames that is the layout the pointer was over, and during a build it is the last one, since the node being declared has no layout yet. A wrapped node answers in the width it was drawn at.

Source

pub fn caret_rect(&self, key: Key, byte: usize) -> Option<Rect>

The caret rect for byte byte of the text node key drew: logical viewport px, zero wide, one line tall — where a caret, an IME candidate window or a selection edge goes. byte past the content is the end. Answered from the same frame text_hit is.

Source

pub fn announce(&mut self, text: &str, live: Live)

Says something once, with no node behind it: “Saved”, “3 results”. Queued for Self::take_announcements, the way play queues an audio command — an announcement is a consequence of an event, and the frame’s tree, which is a function of state, has no place to keep one. A region whose text changes on screen is the other half, and is the live prop instead.

Live::Off and an empty string are both no-ops — the first so a caller can gate politeness without an if, the second because every platform needs a name to say.

Source

pub fn take_announcements(&mut self) -> Vec<Announcement>

Drains the announcements queued since the last drain. Windowed runners drain every frame whether or not assistive technology is attached, and discard what they cannot deliver, so a real app never accumulates and nothing is spoken minutes late; headless drivers assert on what comes back.

Source

pub fn pending_announcements(&self) -> &[Announcement]

Announcements queued and not yet drained (what pending is for audio commands).

Source

pub fn take_warnings(&mut self) -> Vec<Warning>

Drains the warnings raised since the last drain (see crate::diag): silent misconfigurations the core noticed while finishing frames, each distinct (code, node) pair once. Windowed runners print them; headless tests assert on them.

Source

pub fn warnings_raised(&self) -> &[Warning]

Every warning this core has raised, drained or not, oldest first — for a reader that is not the driver. The runner drains Self::take_warnings after every frame and prints them, so a view that wants to show them (a development overlay) would otherwise never see one; this is the log the drain leaves behind.

Source

pub fn warn(&mut self, warning: Warning)

Raises a warning a binding built (see crate::diag::unknown_prop): a frontend sees declarations the tree walk cannot, because a prop name nothing claims never becomes part of a node. Behind the same Self::set_diagnostics gate and the same once-per-(code, key) dedup as the checks, so a binding may raise one per node per frame.

Source

pub fn set_diagnostics(&mut self, on: bool)

Turns the diagnostic checks on or off. A bare Core has them on; drivers set them for the build they are in (the runner: debug on, release off; Node loops: off under NODE_ENV=production; a standalone C context: off until asked).

Source

pub fn diagnostics(&self) -> bool

Source

pub fn lines_to_px(lines: f32) -> f32

Wheel line-deltas (e.g. winit’s LineDelta) to logical px.

Source

pub fn set_subpixel_text(&mut self, on: bool)

Rasterizes outline glyphs as LCD subpixel coverage (QuadKind::GlyphSubpixel) instead of alpha masks. Drivers set it from what their renderer can blend per channel; flipping it drops the glyph atlas so every glyph re-rasterizes in the new mode.

Source

pub fn subpixel_text(&self) -> bool

Source

pub fn set_text_cache_budget(&mut self, bytes: usize)

The byte budget for the shaped-text cache: every text a frame draws is shaped once and kept, and past this many estimated bytes the least recently drawn entries go, down to three quarters of it, at the start of the next frame. What the last frame drew is never evicted, so a budget too small for one screenful costs re-shaping nothing — it only stops keeping what scrolled away. Default DEFAULT_TEXT_CACHE_BYTES (64 MB): a terminal streaming new lines lowers it, a document viewer that wants every page it showed to stay warm raises it. The clock that empties an idle cache after 300 frames is unchanged.

Source

pub fn text_cache_budget(&self) -> usize

Source

pub fn text_cache_bytes(&self) -> usize

What the shaped-text cache holds, as the estimate the budget is charged against (a fixed floor per entry plus a per-glyph rate, calibrated against a counting allocator; see text.rs).

Source

pub fn text_cache_len(&self) -> usize

How many shaped texts the cache holds (a long line’s chunks each count).

Source

pub fn long_lines(&self) -> usize

How many long lines — no-wrap texts past LONG_LINE_BYTES, shaped in chunks — are held.

Source

pub fn set_time(&mut self, now_secs: f64)

The frame clock for transitions: monotonic seconds, any origin. Drivers set it before every frame; a driver that never does gets snapping instead of animation.

Source

pub fn animating(&self) -> bool

True when the last frame left a transition mid-flight, or a view asked for another frame — drivers schedule one without waiting for input. One bool over every source; owed is the same reading by kind.

Source

pub fn owed(&self) -> Owed

What the last frame left owed, by kind. To a driver the kinds are one — it schedules the frame either way — but a test that wants to know whether the transitions have run out under a keyframe cycle that never will reads cycle apart from the rest: Owed::beyond_cycles is that wait’s predicate.

Source

pub fn request_frame(&mut self)

Asks the driver for one more frame right after this one. A view that sets up a transition by drawing a starting state (a new split drawn collapsed so it can slide open) needs the next frame to come without waiting for input — the starting state itself snaps, so nothing is mid-flight yet to request it.

Traced (Self::set_frame_trace), the calling line is kept as the frame’s cause::FrameRequest, which is why this tracks its caller.

Source

pub fn frame(&mut self, viewport: Size, scale: f32) -> Ui<'_>

Starts a frame. Build the tree through the returned Ui (or the Core builder methods directly), then Ui::finish — the one door out of a frame, which runs the extension fills, the devtools panel and the open menu before layout. A driver holding a bare Core mid-frame finishes through Ui::wrap(core).finish().

Source

pub fn frame_with<'a>( &'a mut self, viewport: Size, scale: f32, filler: &'a mut dyn Fill, ) -> Ui<'a>

frame with something to fill the slots the view declares — the runner’s extension list ([Box<dyn Extension>] is a Fill), or a test’s stand-in. Ui::slot calls it in place, and Ui::finish lets it fill "root" and report unknown slots before layout.

Source

pub fn session(&self) -> &Session

The session this core draws from. Hand it to Core::new_in to open another window sharing its fonts, images, sounds and glyph atlas.

Source

pub fn viewport(&self) -> Size

The viewport (logical px) the current frame was begun with — the window, less the devtools’ dock while the panel is docked: what the host lays out into. Changes to it arrive as resize events (see take_pending_events), a dock coming, going or resizing among them.

Source

pub fn scale(&self) -> f32

The device pixel ratio the current frame was begun with.

Source

pub fn origin(&self) -> OriginId

The origin nodes opened right now are tagged with: OriginId::HOST in the host’s own view, the filling extension’s inside a fill (see Core::fill).

Source

pub fn output(&mut self) -> (&DisplayList, &mut GlyphAtlas)

The finished frame’s draw data: display list plus the glyph atlas the renderer mirrors (mutable so it can clear the dirty flag).

Source

pub fn begin_frame(&mut self, viewport: Size, scale: f32)

Begins a frame without handing out a Ui: what Core::frame calls first. A binding that drives the builder methods on the core directly starts here and ends with Ui::wrap(core).finish().

Trait Implementations§

Source§

impl Default for Core

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Core

§

impl !RefUnwindSafe for Core

§

impl !Send for Core

§

impl !Sync for Core

§

impl !UnwindSafe for Core

§

impl Unpin for Core

§

impl UnsafeUnpin for Core

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.