- name
- gpui-app
- description
- 从零搭建 gpui / gpui-component 桌面应用的起步模板。涵盖 Cargo.toml git 依赖(gpui + gpui_platform + gpui-component)、main.rs 入口(application().run / open_window / Root)、资产与图标注册、WindowOptions、退出与激活。创建新 gpui 项目、初始化工程、写 main.rs 或配置依赖时使用。
# gpui 应用起步模板
以下内容按 zed 主干 gpui(0.2.x)与 gpui-component 0.5.x 源码核实(zed `crates/gpui/examples/hello_world.rs`、gpui-component `examples/hello_world`)。
## 1. Cargo.toml
gpui 不发布 crates.io 正式版,统一用 git 依赖;**gpui_platform 必须一并引入**(平台后端 + 入口函数):
```toml
[package]
name = "my-app"
version = "0.1.0"
edition = "2024"
[dependencies]
gpui = { git = "https://github.com/zed-industries/zed" }
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit"] }
# Linux 需要窗口系统后端时:features = ["font-kit", "x11", "wayland"]
# 用组件库时再加:
gpui-component = { git = "https://github.com/longbridge/gpui-component" }
gpui-component-assets = { git = "https://github.com/longbridge/gpui-component" } # 图标资产,可选
[profile.dev.package]
# gpui 渲染相关 crate 在 dev 下也开优化,否则明显卡顿(上游同款配置)
gpui = { opt-level = 3 }
gpui_platform = { opt-level = 3 }
taffy = { opt-level = 3 }
resvg = { opt-level = 3 }
rustybuzz = { opt-level = 3 }
ttf-parser = { opt-level = 3 }
```
注意:crate 名 `gpui-component`,导入名 `gpui_component`。若与 gpui-component 同用,两处 git 的 zed 版本由 Cargo 统一解析;编译报 gpui 版本冲突时,以 gpui-component 锁定的 zed rev 为准。
## 2. 纯 gpui 最小应用
```rust
use gpui::{
App, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions,
div, prelude::*, px, rgb, size,
};
use gpui_platform::application;
struct HelloWorld {
text: SharedString,
}
impl Render for HelloWorld {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.flex_col()
.gap_2()
.size_full()
.justify_center()
.items_center()
.bg(rgb(0x2e7d32))
.text_color(rgb(0xffffff))
.child(format!("Hello, {}!", self.text))
}
}
fn main() {
application().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size(px(500.), px(500.)), cx);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_window, cx| cx.new(|_| HelloWorld { text: "World".into() }),
)
.unwrap();
cx.activate(true); // macOS 置前;Windows/Linux 无害
});
}
```
要点:
- `use gpui::prelude::*;` 必带,否则 `.flex()`/`.child()`/`Render` 等 trait 方法全部找不到(E0599)。
- `open_window` 构建闭包签名 `(&mut Window, &mut App) -> Entity<V>`,必须返回 `cx.new(…)`。
- 入口是 `gpui_platform::application()`;`Application::new()` 已不存在。
## 3. gpui-component 应用(带 Root)
```rust
use gpui::{App, Window, WindowOptions, prelude::*};
use gpui_component::{ActiveTheme as _, Root, button::Button, h_flex};
struct Example;
impl Render for Example {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.size_full()
.justify_center()
.items_center()
.bg(cx.theme().background)
.child(Button::new("hi").primary().label("Hello"))
}
}
fn main() {
gpui_platform::application()
// 图标可用的前提:注册资产(或自定义 rust-embed AssetSource)
.with_assets(gpui_component_assets::Assets)
.run(move |cx| {
gpui_component::init(cx); // 必须最先调用
cx.spawn(async move |cx| {
cx.open_window(WindowOptions::default(), |window, cx| {
let view = cx.new(|_| Example);
// 每个窗口第一层视图必须是 Root,否则 Dialog/Sheet/Notification 图层缺失
cx.new(|cx| Root::new(view, window, cx).bg(cx.theme().background))
})
.expect("Failed to open window");
})
.detach();
});
}
```
三条硬性顺序:`init(cx)` 最先 → 窗口首层 `Root` → 主题访问 `use gpui_component::ActiveTheme as _;` 后 `cx.theme()`。
## 4. 常用 WindowOptions 字段
`window_bounds: Option<WindowBounds>`(`Windowed`/`Maximized`/`Fullscreen`)、`titlebar: Option<TitlebarOptions>`、`focus`、`show`、`kind`、`is_movable`、`is_resizable`、`is_minimizable`、`window_background`、`app_id`、`window_min_size`、`window_decorations`、`icon`。无 `WindowBounds::Fixed`。
## 5. 退出与窗口关闭
窗口关闭默认**不**退出应用,需要"最后窗口关闭即退出"时(已对照 `examples/on_window_close_quit.rs`):
```rust
cx.on_window_closed(|cx, _window_id| {
if cx.windows().is_empty() {
cx.quit();
}
})
.detach();
```
相关:代码里主动关窗用 `window.remove_window()`;绑定快捷键 `cx.bind_keys([KeyBinding::new("cmd-w", CloseWindow, None)])` 配合 `actions!(example, [CloseWindow])` 与元素上的 `.on_action(|_: &CloseWindow, window, _| window.remove_window())`。
## 6. 下一步
- 布局/样式:`skill://gpui/references/layout-style.md`
- 实体与状态:`skill://gpui/references/entity.md`
- 动作与快捷键:`skill://gpui/references/action.md`
- 组件目录:`skill://gpui-component`
- 新旧 API 对照:`skill://gpui-migration`
Ver no GitHub