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.
Kael gives you precise control over every window your application creates. You open windows through cx.open_window, receive a typed WindowHandle<V> you can hold on to, and use the Window context to activate, hide, close, or redirect focus at any point during your app’s lifetime. All window configuration flows through a single WindowOptions struct, so you have one place to describe size, position, decorations, background appearance, and more.
Opening a window
Call cx.open_window with a WindowOptions value and a closure that returns the root view. The closure receives a mutable Window and App, mirroring the signature of your component’s render method.
use kael::prelude::*;
fn main() {
Application::new().run(|cx| {
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::centered(
size(px(900.), px(600.)),
cx,
)),
titlebar: Some(TitlebarOptions {
title: Some("My App".into()),
appears_transparent: false,
traffic_light_position: None,
}),
..WindowOptions::default()
},
|_window, cx| cx.new(|_| MyView),
)
.unwrap();
});
}
cx.open_window returns anyhow::Result<WindowHandle<V>>. Unwrap or propagate the error — it fails only if the platform cannot create a native window.
WindowOptions fields
| Field | Type | Default | Description |
|---|
window_bounds | Option<WindowBounds> | None | Initial position and size. None inherits the platform default. |
titlebar | Option<TitlebarOptions> | transparent titlebar | Title string, transparent mode, and traffic-light position (macOS). |
focus | bool | true | Whether the window takes focus on creation. |
show | bool | true | Whether the window is visible on creation. |
kind | WindowKind | Normal | Normal or Overlay. |
is_movable | bool | true | Whether the user can drag the window. |
is_resizable | bool | true | Whether the user can resize the window. |
is_minimizable | bool | true | Whether the user can minimize the window. |
display_id | Option<DisplayId> | None | Target display. None uses the main display. |
window_background | WindowBackgroundAppearance | Opaque | Background rendering mode. |
app_id | Option<String> | None | Desktop-environment app grouping identifier (Linux). |
window_min_size | Option<Size<Pixels>> | None | Minimum window dimensions. |
window_decorations | Option<WindowDecorations> | None | Client- or server-side decorations (Wayland only). |
tabbing_identifier | Option<String> | None | Native tab group name (macOS 10.12+). |
mouse_passthrough | bool | false | Pass mouse events to windows below this one. |
parent | Option<AnyWindowHandle> | None | Parent window for child/panel windows. |
Controlling size and position
WindowBounds wraps a Bounds<Pixels> and describes whether the window opens windowed, maximized, or fullscreen:
use kael::prelude::*;
// Center a 1 200 × 800 window on the primary display
let bounds = WindowBounds::centered(size(px(1200.), px(800.)), cx);
// Open maximized, restoring to 800 × 600
let bounds = WindowBounds::Maximized(Bounds::default());
// Open fullscreen
let bounds = WindowBounds::Fullscreen(Bounds::default());
Window appearance
WindowAppearance
WindowAppearance reflects the OS-level appearance applied to a window. You read the current value from window.appearance() and react to changes via window.observe_window_appearance.
use kael::{WindowAppearance};
// In your render method
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let bg = match window.appearance() {
WindowAppearance::Light | WindowAppearance::VibrantLight => rgb(0xffffff),
WindowAppearance::Dark | WindowAppearance::VibrantDark => rgb(0x1e1e1e),
};
div().w_full().h_full().bg(bg)
}
| Variant | Description |
|---|
Light | Standard light mode (aqua on macOS). |
VibrantLight | Light mode with vibrant/translucent effects (NSAppearanceNameVibrantLight). |
Dark | Standard dark mode (darkAqua on macOS). |
VibrantDark | Dark mode with vibrant effects (NSAppearanceNameVibrantDark). |
WindowBackgroundAppearance
Set window_background in WindowOptions to control how the window composites against the desktop:
use kael::WindowBackgroundAppearance;
WindowOptions {
window_background: WindowBackgroundAppearance::Blurred,
..WindowOptions::default()
}
| Variant | Description |
|---|
Opaque (default) | Solid background; content behind the window is not drawn. |
Transparent | Standard alpha transparency. |
Blurred | Transparent with platform blur (not always supported). |
You can also change the background after the window is open:
window.set_background_appearance(WindowBackgroundAppearance::Blurred);
WindowHandle<V> — holding a reference to a window
cx.open_window returns a WindowHandle<V> where V is the root view type. The handle is Copy + Clone and lets you interact with the window from anywhere in your app.
use kael::prelude::*;
struct AppState {
main_window: WindowHandle<MainView>,
}
// Later, from an async task or another window:
app_state.main_window.update(cx, |_view, window, _cx| {
window.activate_window();
})?;
Key methods on WindowHandle<V>:
| Method | Description |
|---|
.update(cx, |view, window, cx| …) | Mutate the root view and access Window. |
.read(cx) | Borrow the root view immutably. |
.read_with(cx, |view, cx| …) | Borrow with a closure. |
.entity(cx) | Obtain the underlying Entity<V>. |
AnyWindowHandle is the type-erased counterpart, used when the root type is not known statically.
Multi-window management
You can open as many windows as you like. Keep their handles in your application state to coordinate between them.
use kael::prelude::*;
struct App {
windows: Vec<WindowHandle<PanelView>>,
}
impl App {
fn open_panel(&mut self, cx: &mut kael::App) {
let handle = cx
.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::centered(size(px(400.), px(300.)), cx)),
focus: true,
..WindowOptions::default()
},
|_window, cx| cx.new(|_| PanelView),
)
.unwrap();
self.windows.push(handle);
}
}
cx.windows() returns all currently open window handles if you need to iterate over them without keeping your own list.
Closing windows
Call window.remove_window() from inside any Window context to close the window:
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
button("Close")
.on_click(cx.listener(|_this, _event, window, _cx| {
window.remove_window();
}))
}
Focus management
Use window.focus(&handle) to move keyboard focus to a focusable element, and window.focused(cx) to query which element currently holds focus.
// Move focus to a specific element
window.focus(&self.search_input_focus);
// Query the currently focused handle
if let Some(handle) = window.focused(cx) {
// ...
}
To bring the window itself to the foreground at the platform level:
window.activate_window();
Overlay windows and click-through
Set kind: WindowKind::Overlay to create a floating overlay that draws above normal windows. Combine it with mouse_passthrough: true so that click events fall through to whatever is beneath:
use kael::{WindowKind, WindowOptions};
cx.open_window(
WindowOptions {
kind: WindowKind::Overlay,
mouse_passthrough: true,
show: true,
focus: false,
..WindowOptions::default()
},
|_window, cx| cx.new(|_| HudOverlay),
)
.unwrap();
You can toggle pass-through at runtime:
window.set_mouse_passthrough(true);
Overlays are useful for HUD elements, screen annotations, or translucent panels that sit above other content without stealing mouse input.