Skip to main content

gpui_kit/
lib.rs

1//! GPUI Kit: one dependency for building desktop applications with GPUI.
2//!
3//! GPUI itself is published as a family of `gpui-pre-*` crates that move
4//! together. This crate depends on the matching set for you, so an
5//! application lists `gpui-kit` alone. `use gpui_kit::*;` is GPUI, and each
6//! layer is reachable by name:
7//!
8//! | Path            | Crate             | Feature          |
9//! | --------------- | ----------------- | ---------------- |
10//! | `gpui_kit::*`   | `gpui`            | always           |
11//! | `platform`      | `gpui_platform`   | desktop / web    |
12//! | [`base`]        | `gpui-base`       | always           |
13//! | [`component`]   | `gpui-component`  | `component` (on) |
14//! | [`assets`]      | `gpui-kit-assets` | `assets` (on)    |
15//!
16//! On desktop and web, `application` opens the platform. Mobile applications
17//! supply their backend to `Application::with_platform`. [`init`] initializes the enabled
18//! layers:
19//!
20//! ```no_run
21//! use gpui_kit::*;
22//!
23//! actions!(hello, [Quit]);
24//!
25//! struct Hello;
26//!
27//! impl Render for Hello {
28//!     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
29//!         div().child("Hello, World!")
30//!     }
31//! }
32//!
33//! fn main() {
34//!     gpui_kit::application().run(|cx| {
35//!         gpui_kit::init(cx);
36//!         gpui_kit::open_window(WindowOptions::default(), cx, |_, cx| cx.new(|_| Hello))
37//!             .expect("failed to open window");
38//!     });
39//! }
40//! ```
41//!
42//! Enable `gpui-fast` to select GPUI Fast for the core, platform, and enabled
43//! layers without changing imports. Upstream remains the default backend.
44//!
45//! See [`component`] for the same program with the styled component library.
46
47/// Defines unit actions without requiring consumers to depend on GPUI under the
48/// crate name `gpui`.
49///
50/// GPUI's original macro spells its derive as `gpui::Action`, which does not
51/// resolve when GPUI is consumed solely through this facade.
52#[macro_export]
53macro_rules! actions {
54    ($namespace:path, [ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
55        $(
56            #[derive(
57                ::std::clone::Clone,
58                ::std::cmp::PartialEq,
59                ::std::default::Default,
60                ::std::fmt::Debug,
61                $crate::Action
62            )]
63            #[action(namespace = $namespace)]
64            $(#[$attr])*
65            pub struct $name;
66        )*
67    };
68    ([ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
69        $(
70            #[derive(
71                ::std::clone::Clone,
72                ::std::cmp::PartialEq,
73                ::std::default::Default,
74                ::std::fmt::Debug,
75                $crate::Action
76            )]
77            $(#[$attr])*
78            pub struct $name;
79        )*
80    };
81}
82
83// Public facade decision — 2026-09-08:
84// GPUI Kit is the application-facing entry point. Users should depend on and
85// import gpui-kit without needing to know which GPUI crates implement it.
86// Keep GPUI APIs available through the Kit root and preserve the published
87// #[gpui_kit::test] macro. Do not replace it with Rust's built-in #[test].
88// A future switch to official GPUI crates is an internal dependency migration,
89// not a reason to steer Kit users toward gpui:: paths or require import changes.
90// Keep the existing gpui namespace re-export hidden for source compatibility;
91// it is not the recommended application API. It names this crate rather than
92// the GPUI crate: `gpui_kit::gpui::Window` is still GPUI's `Window` through the
93// glob below, and applications can alias the Kit as `gpui`
94// (`extern crate gpui_kit as gpui;`) so GPUI macro output resolves through the
95// Kit whichever GPUI it is built on. Pointing this at the GPUI crate would make
96// that alias ambiguous (E0659) wherever `gpui_kit::*` is glob-imported.
97//
98// With test-support, the glob below includes GPUI's test macro. Test modules
99// should import their Kit types explicitly to avoid shadowing Rust's #[test].
100#[cfg(not(feature = "gpui-fast"))]
101pub use ::gpui::*;
102#[cfg(feature = "gpui-fast")]
103pub use ::gpui_fast::*;
104
105// Preserve Kit-aware macro paths when the engine is Fast.
106#[cfg(all(feature = "gpui-fast", any(feature = "inspector", debug_assertions)))]
107pub use gpui_macros::derive_inspector_reflection;
108#[cfg(feature = "gpui-fast")]
109pub use gpui_macros::{
110    Action, AppContext, IntoElement, Render, VisualContext, bench, border_style_methods,
111    box_shadow_style_methods, cursor_style_methods, margin_style_methods, overflow_style_methods,
112    padding_style_methods, position_style_methods, property_test, register_action, style_helpers,
113    test, visibility_style_methods,
114};
115
116#[doc(hidden)]
117pub use crate as gpui;
118
119/// UI integration testing: render real components in headless windows, dispatch
120/// pointer and keyboard events, and assert state, focus, layout and callbacks.
121/// Run tests with `#[gpui_kit::test]`; use this module to interact with their UI.
122#[cfg(feature = "test-support")]
123pub mod test;
124
125pub use ::gpui_base as base;
126#[cfg(all(
127    not(any(target_os = "ios", target_os = "android")),
128    feature = "gpui-fast"
129))]
130pub use ::gpui_fast_platform as platform;
131#[cfg(all(target_family = "wasm", feature = "gpui-fast"))]
132pub use ::gpui_fast_web as web;
133#[cfg(all(
134    not(any(target_os = "ios", target_os = "android")),
135    not(feature = "gpui-fast")
136))]
137pub use ::gpui_platform as platform;
138#[cfg(all(target_family = "wasm", not(feature = "gpui-fast")))]
139pub use ::gpui_web as web;
140pub use gpui_base::is_mobile;
141
142/// The styled component library.
143///
144/// ```no_run
145/// use gpui_kit::component::button::*;
146/// use gpui_kit::*;
147///
148/// struct Hello;
149///
150/// impl Render for Hello {
151///     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
152///         div().child(Button::new("ok").primary().label("Let's Go!"))
153///     }
154/// }
155///
156/// fn main() {
157///     gpui_kit::application().run(|cx| {
158///         gpui_kit::init(cx);
159///         gpui_kit::open_window(WindowOptions::default(), cx, |_, cx| cx.new(|_| Hello))
160///             .expect("failed to open window");
161///     });
162/// }
163/// ```
164#[cfg(feature = "component")]
165pub use ::gpui_component as component;
166
167#[cfg(feature = "assets")]
168pub use ::gpui_kit_assets as assets;
169
170/// Open a window with a Base Root and return the window and application content.
171/// Applications own quit/close actions and confirmation flows.
172/// Call [`init`] before opening application windows.
173/// The builder returns application content, not another Root.
174///
175/// In an async context, call this inside `cx.update`.
176pub fn open_window<V: Render>(
177    options: WindowOptions,
178    cx: &mut App,
179    build: impl FnOnce(&mut Window, &mut App) -> Entity<V>,
180) -> Result<(AnyWindowHandle, Entity<V>)> {
181    let mut built = None;
182    let window = cx.open_window(options, |window, cx| {
183        let view = build(window, cx);
184        built = Some(view.clone());
185        cx.new(|cx| base::Root::new(view, window, cx))
186    })?;
187    Ok((
188        window.into(),
189        built.expect("open_window ran its build closure"),
190    ))
191}
192
193// Mobile applications provide their platform with `Application::with_platform`.
194#[cfg(not(any(target_os = "ios", target_os = "android")))]
195pub use platform::application;
196
197/// Initializes every enabled layer. Call it once, before using anything else.
198///
199/// With the `component` feature (on by default) this is
200/// `gpui_component::init`, which also initializes `gpui-base`; otherwise it
201/// is `gpui_base::init`.
202pub fn init(cx: &mut App) {
203    #[cfg(feature = "component")]
204    gpui_component::init(cx);
205    #[cfg(not(feature = "component"))]
206    gpui_base::init(cx);
207}
208
209/// Fluent UI test observation, inert unless `test-support` is enabled.
210pub use gpui_base::TestSupportExt;