Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Augani/kael/llms.txt

Use this file to discover all available pages before exploring further.

Every Kael window is created through App::open_window, which accepts a WindowOptions struct and returns a typed WindowHandle<V>. Once open, you interact with the window through its handle or through the &mut Window reference passed to your root view’s callbacks. This page documents the configuration types, handle APIs, focus primitives, and event dispatch phases that govern window behavior.

WindowOptions

WindowOptions is the primary configuration struct for new windows. All fields have sensible defaults via WindowOptions::default().
use kael::{WindowOptions, WindowBounds, WindowBackgroundAppearance};

let options = WindowOptions {
    window_bounds: Some(WindowBounds::centered(size(px(1200.), px(800.)), cx)),
    focus: true,
    show: true,
    window_background: WindowBackgroundAppearance::Blurred,
    ..Default::default()
};
window_bounds
Option<WindowBounds>
default:"None"
Initial state and restore size of the window. None inherits the platform default. See WindowBounds for the available variants.
titlebar
Option<TitlebarOptions>
Titlebar configuration. Set appears_transparent: true to hide the default system titlebar and draw a custom one. Set to None to suppress the titlebar entirely.
focus
bool
default:"true"
Whether the window should be focused (brought to the foreground) immediately after creation.
show
bool
default:"true"
Whether the window is initially visible. Set to false to create a hidden window and show it later.
kind
WindowKind
default:"WindowKind::Normal"
The type of window to create. Options: Normal, PopUp (always on top), Floating (on top of its parent), Overlay (above fullscreen apps).
is_movable
bool
default:"true"
Whether the user can drag the window.
is_resizable
bool
default:"true"
Whether the user can resize the window.
is_minimizable
bool
default:"true"
Whether the window can be minimized.
display_id
Option<DisplayId>
default:"None"
The display to open the window on. None uses the main display.
window_background
WindowBackgroundAppearance
default:"Opaque"
The background painting mode for transparent window areas. See WindowBackgroundAppearance.
app_id
Option<String>
default:"None"
Application identifier used by desktop environments (e.g. on Linux) to group windows belonging to the same app.
window_min_size
Option<Size<Pixels>>
default:"None"
Minimum dimensions the user can resize the window to.
window_decorations
Option<WindowDecorations>
default:"None"
Whether to use server-side or client-side decorations. Wayland only. See WindowDecorations.
tabbing_identifier
Option<String>
default:"None"
macOS 10.12+ native window tab group name. Windows sharing the same identifier are grouped as tabs.
mouse_passthrough
bool
default:"false"
When true, mouse events pass through to the windows behind this one. Useful for transparent overlay windows.
parent
Option<AnyWindowHandle>
default:"None"
Parent window handle for creating child windows. The child window will be owned by the parent at the platform level.

WindowBounds

WindowBounds controls the initial visual state of the window. Each variant carries a Bounds<Pixels> that represents the window’s restore size — the size it returns to when un-maximized or un-fullscreened.
pub enum WindowBounds {
    Windowed(Bounds<Pixels>),
    Maximized(Bounds<Pixels>),
    Fullscreen(Bounds<Pixels>),
}
Opens the window in a normal windowed state at the given position and size.
Opens the window maximized. bounds is the restore size used when the window is un-maximized.
Opens the window in fullscreen mode. bounds is the restore size.

Helper: WindowBounds::centered

pub fn centered(size: Size<Pixels>, cx: &App) -> Self
Creates a WindowBounds::Windowed that positions the window at the center of the primary display.
let bounds = WindowBounds::centered(size(px(800.), px(600.)), cx);

WindowHandle<V>

WindowHandle<V> is a typed, copyable handle to an open window whose root view is V. It does not keep the window alive on its own — the window stays open as long as it is displayed on screen.
pub struct WindowHandle<V> { /* ... */ }
WindowHandle<V> derefs to AnyWindowHandle, so any method available on AnyWindowHandle is also available directly.

Key methods

// Update the root view
pub fn update<C, R>(
    &self,
    cx: &mut C,
    update: impl FnOnce(&mut V, &mut Window, &mut Context<V>) -> R,
) -> Result<R>
where
    C: AppContext;

// Read the root view immutably
pub fn read<'a>(&self, cx: &'a App) -> Result<&'a V>;

// Read with a callback
pub fn read_with<C, R>(
    &self,
    cx: &C,
    read_with: impl FnOnce(&V, &App) -> R,
) -> Result<R>
where
    C: AppContext;

// Get the root Entity<V>
pub fn entity<C>(&self, cx: &C) -> Result<Entity<V>>
where
    C: AppContext;

// Check if this window is the currently active window
pub fn is_active(&self, cx: &mut App) -> Option<bool>;
All methods return Err (or None) if the window has been closed.
window_handle.update(cx, |view, window, cx| {
    view.set_count(42, window, cx);
})?;

let is_active = window_handle.is_active(cx);

AnyWindowHandle

AnyWindowHandle is a type-erased, copyable handle to any open window. Use it when you need to store or pass a window reference without knowing its root view type at compile time.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AnyWindowHandle {
    pub(crate) id: WindowId,
    state_type: TypeId,
}

Key methods

// Get the WindowId
pub fn window_id(&self) -> WindowId;

// Downcast to a typed handle — returns None if the root type doesn't match
pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>>;

// Update with an AnyView callback
pub fn update<C, R>(
    self,
    cx: &mut C,
    update: impl FnOnce(AnyView, &mut Window, &mut App) -> R,
) -> Result<R>
where
    C: AppContext;

// Read with a typed callback
pub fn read<T, C, R>(
    self,
    cx: &C,
    read: impl FnOnce(Entity<T>, &App) -> R,
) -> Result<T>
where
    C: AppContext,
    T: 'static;
fn close_all_windows(handles: &[AnyWindowHandle], cx: &mut App) {
    for handle in handles {
        handle.update(cx, |_, window, _| window.remove_window()).ok();
    }
}

Appearance enums

WindowAppearance

Controls the visual theme mode reported to the operating system. On macOS this maps to NSAppearance names.
pub enum WindowAppearance {
    Light,        // "aqua"
    VibrantLight, // "NSAppearanceNameVibrantLight"
    Dark,         // "darkAqua"
    VibrantDark,  // "NSAppearanceNameVibrantDark"
}
The default is Light. Vibrant variants use the macOS vibrancy material effect, which blends the window content with the desktop behind it.

WindowBackgroundAppearance

Determines how Kael paints the window background in areas with no opaque content.
pub enum WindowBackgroundAppearance {
    Opaque,      // The window manager does not composite behind this window
    Transparent, // Plain alpha blending
    Blurred,     // Blur the content behind the window (not always supported)
}
Blurred is not universally supported. If the platform does not support it, Kael may fall back to Transparent. Always paint a fallback background color in your root view.

WindowDecorations

Specifies whether the window manager (server) or your application (client) draws window chrome such as title bars and resize handles. Applies only on Wayland.
pub enum WindowDecorations {
    Server, // default — the compositor draws chrome
    Client, // your app draws its own decorations
}
The platform may ignore this setting. On X11 and macOS, decorations are always handled by the platform (Server). The window_decorations field of WindowOptions accepts Option<WindowDecorations>, where None means “use the default”.

WindowControls

A struct that describes which control operations the current platform supports. Returned by the platform on window creation and inspected to decide whether to render custom control buttons.
pub struct WindowControls {
    pub fullscreen: bool,
    pub maximize: bool,
    pub minimize: bool,
    pub window_menu: bool,
}
All fields default to true (Kael assumes the platform can do everything, unless told otherwise).

Focus management

Kael’s focus system is built around FocusHandle, a reference-counted token that identifies a focusable element in the rendered frame.

FocusHandle

pub struct FocusHandle {
    pub(crate) id: FocusId,
    pub tab_index: isize,
    pub tab_stop: bool,
    // ...
}
.focus(window)
(&mut Window)
Moves keyboard focus to the element associated with this handle.
.is_focused(window)
(&Window) -> bool
Returns true if this handle’s element currently holds focus.
.contains_focused(window, cx)
(&Window, &App) -> bool
Returns true if this handle’s element, or any of its descendants, is focused.
.within_focused(window, cx)
(&Window, &mut App) -> bool
Returns true if this handle is focused or is a descendant of the focused element.
.contains(other, window)
(&FocusHandle, &Window) -> bool
Returns true if other is a descendant of this handle in the last rendered frame.
.dispatch_action(action, window, cx)
(&dyn Action, &mut Window, &mut App)
Dispatches an action as if it originated from this focus handle’s element.
.downgrade()
() -> WeakFocusHandle
Returns a WeakFocusHandle that does not prevent the focus slot from being released.
.tab_index(index)
(isize) -> Self
Builder method that sets the element’s position in the tab order.
.tab_stop(enabled)
(bool) -> Self
Builder method that controls whether tab navigation will land on this element.

Focusable trait

Any view that can receive keyboard focus should implement Focusable:
pub trait Focusable: 'static {
    fn focus_handle(&self, cx: &App) -> FocusHandle;
}
Kael uses this method to wire up focus-related interactions. The VisualContext::focus method calls focus_handle() internally.

DispatchPhase

Events in Kael propagate through the element tree in two phases: capture then bubble.
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
pub enum DispatchPhase {
    #[default]
    Bubble,
    Capture,
}
Mouse events are dispatched front-to-back (foreground elements first). Keyboard events travel from the focused element up to the root. This is the phase you should use for almost all event handlers.
Mouse events are dispatched back-to-front (background elements first). Keyboard events travel from the root down toward the focused element. Use this for special cases like clearing “pressed” state. Stopping propagation during capture affects all handlers that rely on detecting non-local events in this phase.
Use the helper methods to test the current phase inside a handler:
pub fn bubble(self) -> bool  // true if DispatchPhase::Bubble
pub fn capture(self) -> bool // true if DispatchPhase::Capture
window.on_mouse_event(move |event: &MouseDownEvent, phase, window, cx| {
    if phase.bubble() {
        // handle the click
    }
});

Build docs developers (and LLMs) love