Skip to main content

Launcher

Struct Launcher 

Source
pub struct Launcher { /* private fields */ }

Implementations§

Source§

impl Launcher

Source

pub fn chrome(self, chrome: Chrome) -> Self

Source

pub fn text_aa(self, aa: TextAa) -> Self

Glyph antialiasing; see TextAa.

Source

pub fn frame_latency(self, frames: u32) -> Self

How many frames may be queued ahead of the one on screen, for every window (backlog C47). Two by default (kui_wgpu::DEFAULT_FRAME_LATENCY): every vsync gets a frame at light load, where one lost 1–6% of them on macOS. On macOS 14+ the runner starts frames that run back to back at the display’s vsync (mod pacer), so the second queued frame is slack and costs no latency; where it cannot — Linux, a pumped runner — such a frame reaches the screen a vsync later than with one. One on Windows, where one already delivered every vsync (RG46). KUI_FRAME_LATENCY overrides it, and KUI_FRAME_PACING=0 turns the pacing off, for comparing without a rebuild. Values below one are one.

Source

pub fn diagnostics(self, on: bool) -> Self

Whether the core looks for silent misconfigurations and the runner prints them to stderr (see kui_core::diag). Default: on in debug builds, off in release — a shipped app stays quiet, a development build says why the grow weight did nothing.

Source

pub fn devtools(self, on: bool) -> Self

Opens the app inside the core’s devtools panel (docs/adr/0024-the-devtools-are-the-cores.md): the event stream, the facts and the tree, docked beside the app’s own tree. KUI_DEVTOOLS=1 in the environment is the same ask for an app that never made it. Sugar for setup_core(|c| c.set_devtools(on)).

Source

pub fn devtools_key(self, key: Accel) -> Self

Respells the chord that moves the keyboard into the devtools panel and back out — and brings a hidden panel back — from its default Ctrl+Shift+I: Accel::parse("f12"), "mod+shift+d", any spelling a menu item takes. The panel’s other chords stay Ctrl+Shift+<letter>; with another chord set, Ctrl+Shift+I is the app’s again. Sugar for setup_core(|c| c.set_devtools_key(key)).

Source

pub fn setup_core(self, f: impl FnOnce(&mut Core) + 'static) -> Self

Runs f on the main window’s core before its first frame — the place for what a core is told rather than declared: the devtools doors, a pinned theme, set_native_menus. Every call adds one; they run in order.

Source

pub fn core(self, core: Core) -> Self

Opens the main window on core rather than on one the launcher makes: everything the host registered on it beforehand — fonts, images, sounds, tokens, a pinned theme, the devtools doors, set_native_menus, the text-cache budget — reaches the window, and the core’s session is the app’s, so a declared second window joins it and the handles a headless frame minted keep drawing. What the launcher is told still applies on top, in the order it always has: Launcher::diagnostics (or the build’s default), then KUI_DEVTOOLS, then every Launcher::setup_core. A C host registers on a context and hands it to kui_run_with, which is this door (backlog AR27); a Rust host that built a core to draw headless first has it too.

Source

pub fn deferred_events(self) -> Self

Says that this app answers an event after on_event returns — which only a host driving the loop itself can do, since only it has a turn between pumps (Launcher::open, PumpRunner). Node’s update is the case: on_event keeps the event, the pump returns, and JS runs the handler and submits the next view.

What it changes is one thing: an input whose events reached the app does not ask for the frame itself. Ordinarily it does, and for an app that answered inside on_event that frame is right — it shows the button let go and what letting go did. For one that has not answered yet the same frame shows the button let go and the count still at its old value, with the new one a pump later: a two-frame release, plain to see at an 8 ms pump. Declining to ask leaves the frame to the host, which asks (PumpRunner::request_redraw, and every setView and drained pollEvents does) once its handler has run, so the release and its answer land in one frame.

Nothing else is suppressed. A transition, a caret blink, a first-frame retry, a Waker wake or the OS’s own repaint still paint whenever they ask, including during a platform’s modal move-resize loop, and an input that reached nobody still asks for its own frame — so the worst this can cost is that a frame some other subsystem asked for in the same pump shows the input’s answer one frame late.

Source

pub fn system(self, pinned: SystemEnv) -> Self

Pins part of env.system for this app’s windows: every field of pinned that is not “cannot tell” is what the views read, over whatever the OS says, for as long as the app runs; the fields left at their default keep following the OS, and a change to one of those still arrives as the system event, carrying the pin with it.

kui_native::app("mine").system(SystemEnv { motion: MotionPref::Reduced, ..Default::default() });

For looking at the window a user who asked for less motion, or a dark appearance, would get — on a machine whose owner asked for neither. The headless core takes the same reading through core.env.system and needs none of this; a window cannot, because its runner writes the real reading before every frame, which is why there is no set_env on one and this is on the launcher instead: the app asking in its own code, the same place KUI_SMOKE_FRAMES was kept out of a shipped build for — an app you ship should not change its motion because of a variable in the environment it was launched from (backlog F47).

Source

pub fn icon(self, rgba: Vec<u8>, width: u32, height: u32) -> Self

The icon every window of the app is created with: rgba is width × height pixels, four bytes each, row by row from the top left, alpha not premultiplied. Windows shows it in the title bar, Alt-Tab and the taskbar and X11 in the window manager’s; macOS draws the bundle’s .icns in the Dock and Wayland the .desktop file’s icon, and neither has a window icon, so there it is nothing. Something a taskbar can shrink cleanly — 64 to 256 px. Panics when the pixels are not that size, a programming error at startup; Launcher::try_icon says why instead.

kui_native::app("mine").icon(rgba, 64, 64);

A Windows program’s own icon is a resource linked into its executable, where Explorer finds it — and winit does not give it to the windows; Launcher::icon_resource does, and wins over the pixels there.

Source

pub fn try_icon( self, rgba: Vec<u8>, width: u32, height: u32, ) -> Result<Self, String>

Launcher::icon for pixels that came from outside the program — Node’s icon option, C’s kui_set_icon — refused with the reason rather than a panic. The launcher is consumed either way, as Launcher::try_extension_as’s is.

Source

pub fn icon_resource(self, id: u16) -> Self

The executable’s icon resource id as every window’s icon, on Windows: the .ico a 1 ICON "app.ico" line in the program’s .rc links in, the one Explorer already draws for the file — each of the title bar and the taskbar loads the frame drawn for its own size. A resource the executable does not have is said once on stderr, and Launcher::icon’s pixels are used if there are any. Nothing on other platforms, so an app passes both and each OS takes its own.

Source

pub fn custom_titlebar(self) -> Self

Shorthand for .chrome(Chrome::Custom).

Source

pub fn borderless(self) -> Self

Shorthand for .chrome(Chrome::Borderless).

Source

pub fn size(self, w: f64, h: f64) -> Self

Initial inner size, logical px (KUI_WINDOW=WxH still overrides). Clamped into the min_size/max_size bounds, as the OS would.

Source

pub fn min_size(self, w: f64, h: f64) -> Self

Smallest inner size the user may resize the window to, logical px. The OS enforces it; the initial size is clamped up into it.

Source

pub fn max_size(self, w: f64, h: f64) -> Self

Largest inner size the user may resize the window to, logical px. A bound below the matching min_size loses to it, as on the OS side.

Source

pub fn extension(self, ext: impl Extension + 'static) -> Self

Loads ext under its own name as its namespace — import fs binds fs. The slots it fills are declared as ui.slot("<name>/<slot>") (ADR 0014). Panics when the name is already another extension’s namespace: two of one name need extension_as.

Source

pub fn extension_as( self, namespace: impl Into<String>, ext: impl Extension + 'static, ) -> Self

Loads ext under namespace — import fs as left. The host decides the namespace, so the same plugin loaded twice is two namespaces, two sets of slots and two sets of params. Panics on a namespace already taken, an empty one, or an extension whose slot names contain /: all three are programming errors at startup.

Source

pub fn try_extension_as( self, namespace: impl Into<String>, ext: impl Extension + 'static, ) -> Result<Self, String>

extension_as for a caller that has to report the refusal rather than die of it — a plugin path that came from outside the program, which is Node’s extensions option. The launcher is consumed either way: a host that cannot load the extension it was told to load has nothing useful left to run.

Source

pub fn with_extensions(self, extensions: Extensions) -> Self

A list already loaded, replacing any extension calls before it — what a C host built into a context with kui_ctx_add_extension and hands to kui_run_with, so that the one loader and its error channel serve the window too.

Source

pub fn extensions(self, exts: Vec<Box<dyn Extension>>) -> Self

extension for each, in order.

Source

pub fn run<A: App>(self, app: A) -> Result<(), Box<dyn Error>>

Source

pub fn open<A: App>(self, app: A) -> Result<PumpRunner<A>, Box<dyn Error>>

Opens the window but keeps the event loop in the caller’s hands: the returned PumpRunner processes OS events only when PumpRunner::pump is called, so a foreign loop (Node/libuv, a game loop, a test harness) can interleave with winit on the main thread. One event loop per process — winit event loops are not recreatable on any desktop platform — but any number of windows on it, and any number of runners in turn: a runner whose main window has closed parks the loop, and the next open on the thread takes it back (backlog F58), so a process can open a window, close it, and open another.

Auto Trait Implementations§

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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

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

Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

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.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more