No description
  • Rust 84.8%
  • JavaScript 6.4%
  • Odin 3.8%
  • C 2.7%
  • Nushell 1.3%
  • Other 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nasonov Viktor acbbbb4d6a
All checks were successful
smoke / smoke-macos (push) Has been skipped
smoke / smoke-windows (push) Has been skipped
ci / gate (push) Successful in 2s
ci / check (push) Successful in 13m18s
ci / publish (push) Has been skipped
menus and backdrop: the accelerator bounded, a Calc ceiling, a bar's waiting switch dropped, the wallpaper's path asked on the loop where it is a call (backlog RG154)
What the alpha.44 pre-tag pass left, built the same day after the tag:

- A row's label keeps a floor (MENU_LABEL_MIN, 48 px) and the
  accelerator takes what that leaves and ellipsizes past it: in a window
  narrower than the accelerator the label shrank to nothing and the
  accelerator ran past the panel, which is what RG150 set out to stop.
- A ceiling declared as a size expression (`max_width(Bound::Calc)`) is
  resolved against the window for the label's cap, never above the
  window's own ceiling; it capped the panel alone before.
- Each menu surface notes whether its panel was built this frame
  (Submenus::built) and finish_frame drops a switch waiting on a surface
  no frame built, so a bar the app stops drawing - or hands to the
  platform - inside the 0.3 s owes no frames for good.
- ground::known_path asks for the wallpaper's file on the event loop
  where that is one call (Windows' SystemParametersInfoW, Plasma's
  config) and ground::Source::Find leaves GNOME's gsettings on the
  thread: a window with none to draw is Opaque from its first frame on
  Windows and Plasma again, as alpha.43 had it, and Tinted-then-Opaque
  on GNOME alone. Run on screen on Windows, both ways; Plasma compiled
  and read; the Linux build under WSLg's X11.
- Tests: a menu narrower than its accelerator, a window narrower than
  the menu's floor (pinning the overhang RG150 chose), a Calc ceiling,
  the pointer leaving the menu with a switch waiting, a bar the app
  stops drawing, the Lua dropdown's rows read plain, and the fallback
  read against known_path. Every code change had a red test first.
- Declined: draining the Wayland queue off a window's creation - its one
  reader drains it before reading, and a timer would wake the loop for
  a capability nobody is about to read.

The changelog's alpha.45 section opens with these.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-08 17:08:58 +03:00
.cargo The crates publish to crates.io, then to the Forgejo registry as before (the user: "let's publish kui on crates-io and add ci publishing into ci"). The workspace's kui-* dependencies drop registry = "drydock9": crates.io refuses a dependency from another registry and one manifest cannot name two, so the Forgejo copies resolve their kui-* dependencies from crates.io too, and a project keeping registry = "drydock9" builds as before. Each crate's publish is ["crates-io", "drydock9"]; homepage is the book (the repository is private), with keywords and categories, all from workspace.package. 2026-10-03 02:33:30 +03:00
.forgejo/workflows odin: the scene corpus's Odin adapter, 57 of 57 scenes byte for byte - and the polygon/polyline doors it caught reading past their arrays 2026-10-07 18:47:27 +03:00
.github/workflows npm: drop the darwin-x64 prebuild - Intel Macs build the Node addon from source 2026-10-07 03:26:29 +03:00
crates menus and backdrop: the accelerator bounded, a Calc ceiling, a bar's waiting switch dropped, the wallpaper's path asked on the loop where it is a call (backlog RG154) 2026-10-08 17:08:58 +03:00
docs menus and backdrop: the accelerator bounded, a Calc ceiling, a bar's waiting switch dropped, the wallpaper's path asked on the loop where it is a call (backlog RG154) 2026-10-08 17:08:58 +03:00
examples 0.1.0-alpha.44: the menus' ceiling and submenus, the blur's scratch, the backdrop on Windows and Linux, floats and an image's border, RG153, and the release 2026-10-08 16:19:30 +03:00
packages 0.1.0-alpha.44: the menus' ceiling and submenus, the blur's scratch, the backdrop on Windows and Linux, floats and an image's border, RG153, and the release 2026-10-08 16:19:30 +03:00
scripts npm-approve: take the version as npm spells it - @qxuken/[email protected] found no stage and said nothing was staged 2026-10-08 00:19:27 +03:00
.gitignore The C examples build where the library is, and run themselves 2026-09-09 01:12:04 +03:00
Cargo.lock 0.1.0-alpha.44: the menus' ceiling and submenus, the blur's scratch, the backdrop on Windows and Linux, floats and an image's border, RG153, and the release 2026-10-08 16:19:30 +03:00
Cargo.toml 0.1.0-alpha.44: the menus' ceiling and submenus, the blur's scratch, the backdrop on Windows and Linux, floats and an image's border, RG153, and the release 2026-10-08 16:19:30 +03:00
CHANGELOG.md menus and backdrop: the accelerator bounded, a Calc ceiling, a bar's waiting switch dropped, the wallpaper's path asked on the loop where it is a call (backlog RG154) 2026-10-08 17:08:58 +03:00
LICENSE Publish releases to the Forgejo registries with bundled Node prebuilds 2026-09-02 16:57:49 +03:00
README.md 0.1.0-alpha.44: the menus' ceiling and submenus, the blur's scratch, the backdrop on Windows and Linux, floats and an image's border, RG153, and the release 2026-10-08 16:19:30 +03:00

kui

kui is a UI library for Rust. You describe what is on screen as a tree of boxes and text; kui lays it out, draws it, and hands back what the user did as plain data. Underneath is a clay-style flat-array layout solver, on top an iced-style view / on_event loop, and text shaping is part of the core. Because a frame is data all the way down, Lua, C and Node bind to the same contract the Rust builders use.

Crates

crate role
kui-native The crate most apps use: a window (winit), the GPU renderer, the stock widgets and the App trait crates.io · docs.rs
kui-core The bindable contract: the flat per-frame tree, the flex solver, the text stack (cosmic-text + a glyph atlas), events as data, resources, the quad display list crates.io · docs.rs
kui-wgpu The wgpu backend: one instanced pipeline (rounded rects, borders, glyphs), one draw call per frame crates.io · docs.rs
kui-derive #[derive(Message)]: an enum that travels through the frame as data and comes back typed crates.io · docs.rs
kui-lua Lua extensions via mlua: scripts return table trees and receive events as tables crates.io · docs.rs
kui-ffi The C API (a cdylib, a staticlib on request, plus include/kui.h): flat builder calls, opaque KuiValue payloads, repr(C) draw data, a windowed runner via callbacks, and CExtension, a C shared library as a guest in another host's frame crates.io · docs.rs
kui-node The Node.js addon (napi-rs) behind the @qxuken/kui npm package: JSX views lowered into the IR in one call per frame, Elm-style messages as data. Ships through npm, not crates.io packages/kui

Install

cargo add kui-native

which writes the one line a project needs:

[dependencies]
kui-native = "0.1.0-alpha.44"

Every release so far is an alpha. A requirement like "0.1.0-alpha.34" is a floor that admits every later alpha; Cargo.lock keeps the version you tested, and "=0.1.0-alpha.34" pins it in the manifest.

macOS and Windows need nothing beyond a Rust toolchain. On Linux the build wants pkg-config and ALSA's headers (libasound2-dev on Debian and Ubuntu). A window loads the rest at run time: libxkbcommon (plus libxkbcommon-x11 on X11), the X11 client libraries (libX11, libXcursor, libXrandr, libXi) or libwayland-client, and libvulkan with a driver or libEGL. A missing one fails when the window opens, with the library's name in the error. File dialogs go through the XDG desktop portal; without one on the session bus, every dialog answers as if cancelled.

The first build takes a few minutes: it compiles a GPU renderer.

Hello, window

The whole of kui in one program. An app is a type with a view that declares the frame from scratch, and a launcher opens a window around it.

use kui_native::{App, TextStyle, Ui};

/// The app is any type. It holds the state; this one has none yet.
struct Hello;

impl App for Hello {
    /// Called once per frame. Everything on screen is declared here,
    /// from scratch, every time.
    fn view(&mut self, ui: &mut Ui<'_>) {
        let theme = ui.theme();
        ui.text("Hello, kui", TextStyle::new(24.0).color(theme.fg));
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    kui_native::app("Hello").size(360.0, 200.0).run(Hello)
}

Put that in src/main.rs and cargo run. From a checkout of this repository it is cargo run -p kui-native --example tutorial_01_hello.

That program is step one of the kui book: ten short chapters, each the last plus one concept (layout, messages, controls, lists, keys, floats, motion, effects, a test), and each a program under examples/rust/tutorial. Read it first.

Documentation

  • The kui book: the path in, one concept a chapter, every code block pulled from a runnable program. Its source is docs/book.
  • API reference on docs.rs: kui-native, kui-core, kui-wgpu, kui-derive, kui-lua, kui-ffi.
  • docs/howto.md: "How do I…", about twenty questions a developer arrives with, two sentences each and a pointer.
  • docs/props.md: every prop, element, event, warning, theme role and metric, with its JSX, Lua, C and Odin spelling in the same row. Generated from the schema, so it cannot drift.
  • examples/README.md: the map of every example in Rust, C, Lua, Node and Odin, what each shows and how to run it.
  • docs/guide.md: testing without a window, the devtools panel, the same app from Node, Lua and C, and the reference documents in detail.
  • docs/design.md: the design notes (one schema for every binding, events, focus, modals, transitions, text, windows, audio, the C ABI) and the layout solver pass by pass.
  • docs/performance.md: the benchmark table and what it says, editing latency, frame pacing.
  • docs/releasing.md: the registries, how a release is cut, CI, the smoke rounds and the audits.
  • docs/status.md: what v0 does not do, by area.
  • docs/adr: design records, the decisions that are hard to reverse and would look arbitrary without their context.
  • CHANGELOG.md: per release, what was added and, separately, what an app can delete.
  • packages/kui: the Node package, @qxuken/kui: JSX views, an Elm-style update, a headless createApp and the same devtools.

License

MIT, see LICENSE.