oxiui 0.2.1

OxiUI — Pure-Rust GUI facade (egui + wgpu, no GTK/Qt/SDL)
Documentation

oxiui — The COOLJAPAN Pure-Rust GUI facade

Crates.io License

oxiui is the top-level façade crate for OxiUI — the COOLJAPAN Pure-Rust UI layer with no GTK (C), no Qt (C++), no SDL (C), no system widgets, and no raw AppKit / Win32 / Cocoa bindings. It wraps the immediate-mode widget API from oxiui-core, selects a render + framework backend through Cargo features, and re-exports everything an application needs behind one builder: App. By default it boots an egui application rendered via wgpu; alternative backends (iced, Dioxus, software) are opt-in. The wasm32 / browser entry point is the separate unpublished oxiui-web copy-template, not a facade feature. (A Slint adapter exists as the standalone oxiui-slint crate — it is a KNOWN-NON-PURE, direct-opt-in dependency, not a facade feature; see 0.2.0 removal notice.)

The facade is the only crate most applications depend on. It owns the application life-cycle: window configuration (AppConfig), the event loop (App::run), headless rendering for CI (App::run_headless_once, App::screenshot), and cross-cutting features — plugins (Plugin), global hotkeys (HotkeyRegistry), a fuzzy-searchable command palette (CommandPalette), and a toast NotificationQueue. GPU drivers (Vulkan/Metal/DX12/WebGPU) are OS-provided at runtime and do not appear in cargo tree --edges normal, keeping the build Pure Rust.

Default-features note (GOVERNANCE §6): default = ["gpu", "egui"]. A zero-feature facade build must select at least one Pure adapter (ADAPTER_PATTERN §3 rule 4), mirroring precedents such as oxicrypto's default = ["pure"] and oxitls's default = ["pure", "webpki-roots"]. For a strictly minimal / ffi-audit build use --no-default-features --features software.

Installation

[dependencies]
# Default: egui + wgpu native app
oxiui = "0.2.1"

# Headless / ffi-audit: CPU softbuffer framebuffer, no GPU stack at build time
oxiui = { version = "0.2.1", default-features = false, features = ["software"] }

# iced retained-mode backend
oxiui = { version = "0.2.1", features = ["iced"] }

# Everything: tables, accessibility, plus the iced backend
oxiui = { version = "0.2.1", features = ["iced", "table", "a11y"] }

Quick Start

egui backend (default)

use oxiui::{App, AppConfig};

App::new(AppConfig::new().title("Hello OxiUI"))
    .theme(oxiui::theme::cooljapan_default())
    .content(|ui| {
        ui.heading("Hello, world!");
        if ui.button("Quit").clicked { /* exit logic */ }
    })
    .run()
    .expect("UI error");

iced backend

use oxiui::{App, AppConfig, Backend};

App::new(AppConfig::new().title("Hello OxiUI (iced)"))
    .theme(oxiui::theme::cooljapan_default())
    .backend(Backend::Iced)
    .content(|ui| {
        ui.heading("Hello from iced!");
        if ui.button("Quit").clicked { std::process::exit(0); }
    })
    .run()
    .expect("UI error");

Headless (CI-friendly, no display)

use oxiui::{App, AppConfig};

let exit = App::new(AppConfig::new().title("smoke"))
    .content(|ui| { ui.heading("h"); })
    .run_headless_once()?;
assert_eq!(exit, oxiui::AppExit::Ok);
# Ok::<(), oxiui::UiError>(())

Backend Selection

The active backend is chosen with App::backend and the Backend enum. The default is Backend::Egui. Each non-default variant is gated behind its own Cargo feature; the variant is only present when its feature is enabled.

Backend variant Feature Framework / mode Status
Egui (default) egui egui + eframe, immediate-mode, rendered via wgpu Live native window; drives the real eframe::run_native event loop via EguiRunner.
Iced iced iced, retained-mode (Elm-style update/view) Live native window; drives the real iced::application event loop via IcedRunner, honouring AppConfig's configured window size and waiting for on_close hooks to run before the window actually closes. Button clicks carry one-frame latency (inherent to the retained↔immediate bridge).
Dioxus dioxus Dioxus reactive framework (minimal Pure-Rust feature set) M5: headless collection mode. Native rendering via dioxus-native deferred to M6.

There is no Backend::Slint variant — the slint feature was removed from the facade in 0.2.0 because oxiui-slint is a KNOWN-NON-PURE adapter (pulls in a C fontconfig binding on Linux via slintparley/fontique). Use the standalone oxiui-slint crate directly instead.

The egui-on-wasm32 path is not driven through App::run (which returns UiError::Unsupported on wasm32); instead use oxiui_web::mount from the unpublished oxiui-web copy-template in a browser binary.

API Overview

Application builder

Item Kind Description
App struct The application builder and runner. Lazy: no GPU device, window, or event loop is created until run().
AppConfig struct Window configuration (title, size, min/max size, decorations, transparency, always-on-top, icon, position, extra fonts). Builder methods + Default.
AppExit enum Exit status: Ok, Error(String), RequestedByUser, Programmatic(String).
Backend enum Backend selector (see table above).

App builder methods

Method Description
App::new(config) Create an app from an AppConfig (theme defaults to cooljapan_default).
.theme(Box<dyn Theme>) Set the UI theme.
.content(F) Set the per-frame content closure (FnMut(&mut dyn UiCtx) + Send).
.with_state(state, F) Set a stateful content closure; state is owned and passed by &mut each frame.
.backend(Backend) Select the GUI backend.
.min_size / .max_size / .decorations / .transparent / .always_on_top / .icon / .position Window-config passthroughs.
.with_font(family, bytes) Register an extra font family (egui path; iced stores bytes, registration deferred).
.with_frame_skip(bool) egui: defer repaint by 1 s when no input events occurred (CPU-saving dirty flag).
.with_egui_ctx(F) egui escape hatch — per-frame callback receiving the raw egui::Context (requires egui).
.table(source) Render an oxiui_table::RowSource as the app content (requires table).
.with_persistent_state(initial, path, F) Stateful content closure (FnMut(&mut dyn UiCtx, &mut State)) whose state is decoded from path via oxicode at startup and re-encoded to path from the on_close hook (requires persist). Decode/encode failures are non-fatal (fall back to initial; warn to stderr).
.on_init / .on_frame / .on_close / .on_resize / .on_focus Register lifecycle hooks (called in registration order).
.plugin(P) Register a Plugin; plugins are sorted by ascending priority().
.notify(title, body, urgency) Enqueue a toast (urgency 0=low/3 s, 1=normal/5 s, 2=critical/10 s).
.try_hotkey(mods, key, action) Register a global hotkey; Err(HotkeyConflict) on duplicate (mods, key).
.register_command(name, shortcut) Add a command to the palette.
.command_matches(query) -> Vec<String> Fuzzy-search command labels (subsequence match).
.with_design_tokens(tokens) / .with_typography(scale) / .design_tokens() / .typography() Set/read oxiui_theme::DesignTokens / TypographyScale beyond the theme's Palette, for backends and layout engines that need the spacing scale at frame time.
.open_window(WindowConfig) -> WindowId / .close_window(id) / .secondary_windows() / .window_channel() Multi-window registry (oxiui::multiwindow). Descriptors are queued for backends to open as OS windows (egui show_viewport_deferred / iced multi_window dispatch is planned for M7); WindowChannel carries cross-window messages today.
.menu_bar(F) / .with_menu_bar(MenuBar) / .get_menu_bar() Build or attach a cross-platform menu bar (oxiui::menu). Pure data model — backend translation (egui egui-menu / iced widget::menu) is planned for M7.
.file_dialog(...) / .file_save_dialog(...) / .message_dialog(...) / .confirm_dialog(...) / .prompt_dialog(...) / .poll_dialog(id) / .respond_dialog(id, resp) / .dialog_queue() Pure in-process dialog request/response queue (oxiui::dialog::DialogQueue) — headless-testable, no OS dialog. Needs no feature flag.
.file_dialog_native(...) / .message_dialog_native(...) Blocking native OS file-picker / message-box dialogs via rfd (requires dialogs; no-op fallback without it).
.soft_renderer() -> SoftRenderer Construct an off-screen oxiui_render_soft::SoftRenderer for custom rendering/compositing (requires software).
.notifications() / .hotkeys() / .extra_fonts() Read-only accessors for testing.
.run() -> Result<AppExit, UiError> Launch the native window + event loop (dispatches by backend).
.run_headless_once() -> Result<AppExit, UiError> Run one synthetic frame against a no-op UiCtx (no window; fires init/frame hooks + plugins, including on_close — so .with_persistent_state persists deterministically in headless runs too).
.run_with_return(F) -> Result<T, UiError> Run content once headlessly and forward its return value.
.screenshot() -> Result<Vec<u8>, UiError> Render a headless frame to PNG bytes (requires software; else UiError::Unsupported).
.build_a11y_snapshot(window_id) -> A11yTree Record content through RecordingUiCtx into an accessibility tree (requires a11y).

Cross-cutting feature types

Item Kind Description
Plugin trait Life-cycle plugin: init, update, and priority (lower = earlier).
HotkeyRegistry struct Registry enforcing unique (Modifiers, Key) bindings; register, conflict_check, len, is_empty.
HotkeyBinding struct A single registered hotkey (id, modifiers, key, action).
HotkeyConflict struct Error when two hotkeys share a (Modifiers, Key) pair (Display + Error).
Command struct A named, searchable command (id, label, shortcut, action).
CommandPalette struct Fuzzy (subsequence, case-insensitive) command registry; register, register_with_shortcut, search, len, is_empty.
Notification struct A pending toast (title, body, duration_ms, urgency, created_at).
NotificationQueue struct FIFO toast queue; push, enqueue, pop_due, len, is_empty.

Pluggable runner infrastructure (oxiui::runner)

Item Kind Description
BackendRunner trait Object-safe trait decoupling backend selection from App::run; run(self, config, content, lifecycle).
LifecycleConfig struct on_close / on_resize / on_focus hook vectors passed to a runner.
ContentFn type alias Box<dyn FnMut(&mut dyn UiCtx) + Send>.
EguiRunner struct Live egui runner — owns the eframe::run_native loop (requires egui).
IcedRunner struct Live iced runner — owns the iced::application loop (requires iced).

EguiRunner / IcedRunner own the live event loops: App::run() moves its theme, hooks, and plugins into the matching runner and delegates via BackendRunner::run. A runner::LifecycleTracker deduplicates window size/focus/close snapshots so on_resize / on_focus fire only on real changes and on_close fires at most once.

Re-exported modules

Module Gate Contents
oxiui::prelude The common set: App, AppConfig, AppExit, Backend, HotkeyConflict, Notification, Plugin; from oxiui-core: ButtonResponse, Color, UiCtx, UiError, Point/Rect/Size, AlignContent/FlexWrap/RichTextSpan, reactive (Signal, Computed, ReactiveRuntime, ReactiveError); from oxiui-theme: CooljapanTheme.
oxiui::core Glob re-export of all of oxiui-core.
oxiui::theme cooljapan_default, dark, light.
oxiui::theme_picker theme_picker, by_name (re-exported as theme_by_name), BUILTIN_THEMES.
oxiui::text FontSpec, FontStyle, FontFeature.
oxiui::solver Constraint solver: Constraint, Expression, RelOp, Solver, SolverError, Strength, Term, Variable.
oxiui::reactive Signal, Computed, ReactiveRuntime, ReactiveError.
oxiui::render software Framebuffer, RgbaBuffer, render_headless_once, render_headless_scene.
oxiui::table table Glob re-export of oxiui-table.
oxiui::accessibility a11y A11yTree, A11yNode, WidgetRole.
oxiui::recording a11y RecordingUiCtx, RecordingEntry.
oxiui::multiwindow WindowRegistry, SecondaryWindow; backs App::open_window/close_window.
oxiui::dialog Pure in-process DialogQueue, DialogKind, DialogResponse, DialogId; backs App::file_dialog and friends.
oxiui::menu MenuBar, MenuBarBuilder, Menu, MenuItem — closure-based menu-bar DSL; backs App::menu_bar.
oxiui::native_dialog dialogs open_file_dialog, save_file_dialog, message_dialog, confirm_dialog — blocking rfd-backed native dialogs; backs App::*_dialog_native.
oxiui::logging tracing init_logging, LogLevel — installs a tracing-subscriber fmt subscriber respecting RUST_LOG.

Crate-root re-exports

From oxiui-core at the crate root: ButtonResponse, Color, FontSpec, Palette, Theme, UiCtx, UiError. From runner: BackendRunner, LifecycleConfig (always), plus EguiRunner (egui) and IcedRunner (iced). From theme_picker: theme_by_name, theme_picker, BUILTIN_THEMES. From multiwindow: SecondaryWindow. From dialog: DialogId, DialogKind, DialogQueue, DialogResponse. From menu: Menu, MenuBar, MenuBarBuilder, MenuItem. From native_dialog: DialogResult, MessageLevel.

Web (wasm32) entry point

The facade itself does not mount a browser canvas. On wasm32, App::run returns Err(UiError::Unsupported) directing you to oxiui_web::mount(canvas_id). That entry point lives in the unpublished oxiui-web crate (publish = false), which is provided as a copy-template for your own wasm app rather than a crates.io dependency. See its README for the browser API and build steps.

Feature Flags

Features fall into two groups: render backends (how pixels reach the screen) and framework backends (which widget framework drives the frame), plus optional capability modules.

Render backends

Feature Pulls in Description
gpu oxiui-render-wgpu wgpu GPU rendering (Metal/Vulkan/DX12/WebGPU drivers OS-provided at runtime). Part of default.
software oxiui-render-soft Pure-CPU softbuffer framebuffer; enables oxiui::render::* and App::screenshot. No GPU stack at build time.

Framework backends

Feature Pulls in Description
egui oxiui-egui, oxiui-render-wgpu, egui, eframe, png egui + eframe immediate-mode backend (default). Enables the with_egui_ctx escape hatch and Backend::Egui.
iced oxiui-iced, iced iced retained-mode backend; enables Backend::Iced and IcedRunner.
dioxus oxiui-dioxus (+ its dioxus) Dioxus reactive adapter (minimal Pure-Rust set); enables Backend::Dioxus.

No slint feature. The facade's slint feature was removed in 0.2.0 — oxiui-slint pulls in a C fontconfig binding (yeslogic-fontconfig-sys) on Linux with no pure opt-out, so it can no longer be aggregated into the facade's Pure Rust closure. Use the standalone oxiui-slint crate directly instead.

Capability modules

Feature Pulls in Description
table oxiui-table Table widget; enables oxiui::table::* and App::table.
a11y oxiui-accessibility, accesskit Accessibility tree builder; enables oxiui::accessibility, oxiui::recording, and App::build_a11y_snapshot.
persist oxicode Enables App::with_persistent_state, which loads/saves app state to disk via oxicode (see below).
dialogs rfd Enables oxiui::native_dialog and the App::*_dialog_native methods — blocking native OS file-picker / message-box dialogs. The built-in in-process oxiui::dialog::DialogQueue (App::file_dialog, App::message_dialog, …) needs no feature and works headlessly.
tracing tracing, tracing-subscriber Enables oxiui::logging::init_logging, installing a tracing-subscriber fmt subscriber for OxiUI's frame/layout/paint/event spans.
default gpu + egui Boots an egui app rendered via wgpu.

Note: there is no web feature. The wasm32 browser entry point lives in the unpublished oxiui-web crate (publish = false), used as a copy-template — see Web (wasm32) entry point above.

Errors

App methods return Result<_, oxiui_core::UiError>. UiError is #[non_exhaustive].

Variant Meaning (facade context)
Backend(String) Windowing / GPU / backend-runtime initialisation failure (e.g. eframe or iced run error).
Render(String) Render-pipeline error.
Window(String) Window-management error.
Unsupported(String) Requested feature/backend not available (e.g. screenshot without software; App::run on wasm32).
Layout(String) Layout-engine error (unsatisfiable constraints).
Focus(String) Focus-management error.
Clipboard(String) Clipboard access error.
DragDrop(String) Drag-and-drop protocol error.
Other(String) Any other error.

A separate HotkeyConflict error (its own std::error::Error type) is returned by App::try_hotkey / HotkeyRegistry::register on a duplicate (Modifiers, Key) binding.

Examples

The crate ships runnable examples (see examples/):

cargo run --example hello                              # egui (default)
cargo run --example hello_iced   --features iced       # iced backend
cargo run --example hello_table  --features table      # table widget
cargo run --example hello_dioxus --features dioxus     # Dioxus adapter

Related Crates

Crate Role
oxiui-core Core traits/types: UiCtx, Theme, Palette, Color, UiError, events, reactive primitives, constraint solver.
oxiui-text Text shaping and font handling.
oxiui-theme COOLJAPAN themes (cooljapan_default, dark, light, CooljapanTheme).
oxiui-table Table widget (table feature).
oxiui-accessibility accesskit-based a11y tree (a11y feature).
oxiui-render-soft Pure-CPU software renderer (software feature).
oxiui-render-wgpu wgpu GPU renderer (gpu feature).
oxiui-egui egui + eframe backend (egui feature).
oxiui-iced iced retained-mode backend (iced feature).
oxiui-slint Slint adapter. Not a facade feature (removed in 0.2.0, KNOWN-NON-PURE) — depend on it directly instead.
oxiui-dioxus Dioxus adapter (dioxus feature).
oxiui-web wasm32 browser entry point — unpublished (publish = false) copy-template, not a facade feature/dependency.

License

Apache-2.0 — COOLJAPAN OU (Team Kitasan)