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//! See [`component`] for the same program with the styled component library.
43
44/// Defines unit actions without requiring consumers to depend on GPUI under the
45/// crate name `gpui`.
46///
47/// GPUI's original macro spells its derive as `gpui::Action`, which does not
48/// resolve when GPUI is consumed solely through this facade.
49#[macro_export]
50macro_rules! actions {
51 ($namespace:path, [ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
52 $(
53 #[derive(
54 ::std::clone::Clone,
55 ::std::cmp::PartialEq,
56 ::std::default::Default,
57 ::std::fmt::Debug,
58 $crate::Action
59 )]
60 #[action(namespace = $namespace)]
61 $(#[$attr])*
62 pub struct $name;
63 )*
64 };
65 ([ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
66 $(
67 #[derive(
68 ::std::clone::Clone,
69 ::std::cmp::PartialEq,
70 ::std::default::Default,
71 ::std::fmt::Debug,
72 $crate::Action
73 )]
74 $(#[$attr])*
75 pub struct $name;
76 )*
77 };
78}
79
80// Public facade decision — 2026-09-08:
81// GPUI Kit is the application-facing entry point. Users should depend on and
82// import gpui-kit without needing to know which GPUI crates implement it.
83// Keep GPUI APIs available through the Kit root and preserve the published
84// #[gpui_kit::test] macro. Do not replace it with Rust's built-in #[test].
85// A future switch to official GPUI crates is an internal dependency migration,
86// not a reason to steer Kit users toward gpui:: paths or require import changes.
87// Keep the existing gpui namespace re-export hidden for source compatibility;
88// it is not the recommended application API.
89//
90// With test-support, the glob below includes GPUI's test macro. Test modules
91// should import their Kit types explicitly to avoid shadowing Rust's #[test].
92pub use ::gpui::*;
93
94#[doc(hidden)]
95pub use ::gpui;
96
97/// UI integration testing: render real components in headless windows, dispatch
98/// pointer and keyboard events, and assert state, focus, layout and callbacks.
99/// Run tests with `#[gpui_kit::test]`; use this module to interact with their UI.
100#[cfg(feature = "test-support")]
101pub mod test;
102
103pub use ::gpui_base as base;
104#[cfg(not(any(target_os = "ios", target_os = "android")))]
105pub use ::gpui_platform as platform;
106#[cfg(target_family = "wasm")]
107pub use ::gpui_web as web;
108pub use gpui_base::is_mobile;
109
110/// The styled component library.
111///
112/// ```no_run
113/// use gpui_kit::component::button::*;
114/// use gpui_kit::*;
115///
116/// struct Hello;
117///
118/// impl Render for Hello {
119/// fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
120/// div().child(Button::new("ok").primary().label("Let's Go!"))
121/// }
122/// }
123///
124/// fn main() {
125/// gpui_kit::application().run(|cx| {
126/// gpui_kit::init(cx);
127/// gpui_kit::open_window(WindowOptions::default(), cx, |_, cx| cx.new(|_| Hello))
128/// .expect("failed to open window");
129/// });
130/// }
131/// ```
132#[cfg(feature = "component")]
133pub use ::gpui_component as component;
134
135#[cfg(feature = "assets")]
136pub use ::gpui_kit_assets as assets;
137
138/// Open a window with a Base Root and return the window and application content.
139/// Applications own quit/close actions and confirmation flows.
140/// Call [`init`] before opening application windows.
141/// The builder returns application content, not another Root.
142///
143/// In an async context, call this inside `cx.update`.
144pub fn open_window<V: Render>(
145 options: WindowOptions,
146 cx: &mut App,
147 build: impl FnOnce(&mut Window, &mut App) -> Entity<V>,
148) -> Result<(AnyWindowHandle, Entity<V>)> {
149 let mut built = None;
150 let window = cx.open_window(options, |window, cx| {
151 let view = build(window, cx);
152 built = Some(view.clone());
153 cx.new(|cx| base::Root::new(view, window, cx))
154 })?;
155 Ok((
156 window.into(),
157 built.expect("open_window ran its build closure"),
158 ))
159}
160
161// Mobile applications provide their platform with `Application::with_platform`.
162#[cfg(not(any(target_os = "ios", target_os = "android")))]
163pub use ::gpui_platform::application;
164
165/// Initializes every enabled layer. Call it once, before using anything else.
166///
167/// With the `component` feature (on by default) this is
168/// `gpui_component::init`, which also initializes `gpui-base`; otherwise it
169/// is `gpui_base::init`.
170pub fn init(cx: &mut App) {
171 #[cfg(feature = "component")]
172 gpui_component::init(cx);
173 #[cfg(not(feature = "component"))]
174 gpui_base::init(cx);
175}
176
177/// Fluent UI test observation, inert unless `test-support` is enabled.
178pub use gpui_base::TestSupportExt;