Root View

Root is the Base-owned root view of every uni-kit window. gpui_kit::open_window is the application entry point and always creates this type. Base does not expose a separate window helper; component::Root re-exports the Base type.

Install

Base owns the content and overlay host, keyboard traversal and selection copying. Calling gpui_component::init explicitly registers the styled window extension: dialogs, sheets, notifications, tooltips, menus, touch selection, theme and window chrome. Initialize it before creating windows. A Base-only application calls gpui_base::init and needs no Component or Kit dependency. Cargo feature unification does not change the root type.

This complete Tested consumer recipe is compiled from the isolated gpui-kit consumer workspace. It initializes uni-kit, then opens a window whose root is a Root wrapping the application view.

use gpui_kit::{
    AppContext as _, Context, IntoElement, ParentElement as _, Render, Styled as _, Window,
    WindowOptions, div,
};

pub fn run() {
    gpui_kit::application()
        .with_assets(gpui_kit::assets::Assets)
        .run(|cx| {
            gpui_kit::init(cx);
            // The window's root view is a `Root` wrapping the view, which
            // renders dialogs, sheets and notifications above it.
            gpui_kit::open_window(WindowOptions::default(), cx, |_, cx| {
                cx.new(|_| BootstrapView)
            })
            .expect("failed to open window");
        });
}

struct BootstrapView;

impl Render for BootstrapView {
    fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
        div().size_full().child("My application")
    }
}
// Installed in ui/components. That directory is on the Slint include path, so import by file name:
import { Root } from "root.slint";

gpui_kit::open_window is cx.open_window plus the Root wrapper. Root must be the window’s root view so window-level facilities such as dialogs, sheets, notifications, focus traversal, and text selection remain available. Client-side window borders are selected from the window’s decoration mode; server-decorated and layer-shell windows do not require Root configuration.

open_window returns the window and the view, so a view that must be built inside the window (it owns an InputState, say) can still be kept:

let (window, editor) = gpui_kit::open_window(WindowOptions::default(), cx, |window, cx| {
    cx.new(|cx| Editor::new(window, cx))
})?;
SlintNo Slint version of this example yet.

#Closing windows and quitting

Applications define their own quit and close-window actions and key bindings. gpui_kit::init does not install them. Handle unsaved changes and any confirmation in the application before closing a window or quitting.

GPUINo GPUI version of this example yet.
VerticalLayout {
    spacing: 8px;
    alignment: start;
    Text {
        text: "A window's root view is the application view wrapped in Root. The application owns the quit and close-window actions; Root only hosts the layers above it.";
        color: Theme.muted-foreground;
        font-size: Theme.font-size-sm;
    }
    Button {
        text: "Close window";
    }
}

#Overlays

Root always mounts the dialog, sheet and notification layers above application content. Applications only call window.open_dialog, window.open_sheet or window.push_notification; no manual mounting or configuration is needed. Child view caching does not affect overlay rendering.

#Migrating to 0.7.0

Root::render_dialog_layer, Root::render_sheet_layer and Root::render_notification_layer have been removed. Delete their calls and the corresponding .children(...) expressions from application views. Previously customized layer positions now use the window-level Root’s overlay placement.

GPUINo GPUI version of this example yet.
Rectangle {
    width: 100%;
    height: Theme.viewport < 480px ? 280px : 360px;
    border-width: 1px;
    border-color: Theme.border;
    border-radius: Theme.radius-lg;
    clip: true;
    Root {
        width: 100%;
        height: 100%;
        dialog-open <=> root.dialog-open;
        dialog-title: "Confirm";
        dialog-description: "Apply these changes?";
        notices: [
            { title: "Synced", message: "All changes are saved.", status: Status.success }
        ];
        VerticalLayout {
            padding: 16px;
            spacing: 8px;
            Button {
                text: "Open dialog";
                clicked => {
                    root.dialog-open = true;
                }
            }
            Text {
                text: "Notifications stack at the top-right of this frame.";
                color: Theme.muted-foreground;
                font-size: Theme.font-size-xs;
            }
        }
    }
}