Skip to main content

生态、安装与第一个窗口

GPUI 是 Zed 团队维护的 Rust 桌面 UI 框架。它的目标不是包一层 WebView,而是直接使用平台窗口、文本系统与 GPU 渲染后端来绘制原生桌面应用。官方文档把它描述为混合 immediate/retained mode 的 GPU 加速 UI 框架,这意味着你会在 render 中声明当前状态应该长成什么样,同时由 GPUI 保留实体、窗口、焦点、事件和资源等运行时状态。

什么时候适合选 GPUI

适合:

  • 你想写 Rust 原生桌面应用,并且愿意接受较新的 API。
  • 应用需要复杂文本、键盘操作、高刷新率 UI 或类编辑器交互。
  • 团队能承受 pre-1.0 框架的升级成本。
  • 你希望从 Zed 的真实工程实践中学习 UI 架构。

不太适合:

  • 你需要非常稳定的长期 ABI/API。
  • 你需要大量现成业务组件、成熟设计器或企业级可视化工具。
  • 你只想把网页快速打包成桌面端,这类场景 Tauri 往往更直接。

依赖选择

GPUI 本身可以直接使用 gpuigpui_platform。本教程以 GitHub 上 zed-industries/zed 的最新 main 为准,不以 crates.io 的滞后版本为准。官方 README 可能展示 version = "*" 的发布版写法,但当前实践应改成 git 依赖;为了让构建可复现,建议锁定到你验证过的 Zed 提交:

[dependencies]
gpui = { git = "https://github.com/zed-industries/zed", rev = "04de6dab7c890d815e316f2f9554f9eeeaf8ebb2" }
gpui_platform = { git = "https://github.com/zed-industries/zed", rev = "04de6dab7c890d815e316f2f9554f9eeeaf8ebb2", features = ["font-kit", "wayland", "x11"] }

如果你只在单平台构建,可以按官方 README 缩减 gpui_platform features:

  • macOS:features = ["font-kit"]
  • Linux / FreeBSD:至少启用 waylandx11
  • Windows:通常不需要额外 feature

如果你想像 HiPoster 一样快速构建复杂表单、菜单、Tab、输入框、可拖拽分栏和主题,建议同时使用 gpui-component

HiPoster 采用 git 依赖,和 GPUI Component 官方文档的安装方式一致:

[dependencies]
gpui = { git = "https://github.com/zed-industries/zed" }
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit"] }
gpui-component = { git = "https://github.com/longbridge/gpui-component" }
gpui-component-assets = { git = "https://github.com/longbridge/gpui-component" }
reqwest = { version = "0.12", features = ["json", "multipart"] }
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
directories = "6.0"

如果项目要用 gpui-component,还要注意组件库本身会跟随它验证过的 Zed 提交。2026-07-06 检查到 gpui-component main372446c007672cabe1b8d9a2dba547f8c2646049,其 workspace 里固定的 Zed revision 是 1d217ee39d381ac101b7cf49d3d22451ac1093fe。这意味着:纯 GPUI 教程以 Zed 最新 main 为准;使用组件库时,以能同时编译 gpui-component 和你的应用的 Zed revision 为准。

平台准备

macOS:

  • 安装 Xcode 或 Xcode Command Line Tools。
  • GPUI 使用 Metal 渲染,打包 .app 时还要处理 Info.plist、图标和签名。

Linux:

  • 启用 gpui_platformwaylandx11 或两者。
  • 确认系统有图形栈、Vulkan/OpenGL 相关运行库和字体配置。
  • 打包时按发行版处理 .desktop、图标和依赖。

Windows:

  • 使用 MSVC toolchain。
  • 安装 Visual Studio Build Tools 2022,并选择 Desktop development with C++。
  • 从 Developer PowerShell for VS 2022 构建,避免找不到 cl.exe、SDK 或链接器。

最小窗口

一个 GPUI 应用的启动流程是:

  1. 创建 Application
  2. run 回调里拿到 App 上下文。
  3. 调用 open_window 创建窗口。
  4. cx.new 创建实现了 Render 的根视图。
use gpui::{div, prelude::*, px, size, App, Bounds, Context, Window};
use gpui::{WindowBounds, WindowOptions};
use gpui_platform::application;

struct HelloGpui;

impl Render for HelloGpui {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.size_full()
.flex()
.items_center()
.justify_center()
.text_xl()
.child("Hello GPUI")
}
}

fn main() {
application().run(|cx: &mut App| {
let bounds = Bounds::centered(None, size(px(800.), px(480.)), cx);

cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| cx.new(|_| HelloGpui),
)
.expect("open window");

cx.activate(true);
});
}

使用 GPUI Component 的启动方式

HiPoster 使用 GPUI Component,因此入口多了三件事:

  • gpui_platform::application() 选择平台后端。
  • 调用 gpui_component::init(cx) 初始化组件库的主题和全局设置。
  • Root::new(view, window, cx) 包住窗口第一层视图。
use gpui::*;
use gpui_component::{button::*, Root};

struct HelloComponent;

impl Render for HelloComponent {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.v_flex()
.size_full()
.items_center()
.justify_center()
.gap_2()
.child("Hello GPUI Component")
.child(Button::new("ok").primary().label("OK"))
}
}

fn main() {
gpui_platform::application().run(move |cx| {
gpui_component::init(cx);

cx.spawn(async move |cx| {
cx.open_window(WindowOptions::default(), |window, cx| {
let view = cx.new(|_| HelloComponent);
cx.new(|cx| Root::new(view, window, cx))
})
.expect("open window");
})
.detach();
});
}

这个版本更接近 HiPoster,也更适合后面教程里的复杂应用。

GPUI 的三个层次

学习 GPUI 时可以把它分成三层:

  • Entity:有身份的状态,由 GPUI 运行时持有。
  • View:实现 RenderEntity,每次需要绘制时返回元素树。
  • Element:具体绘制与布局单元,例如 div()ButtonInputTabBar

这三个层次决定了 GPUI 的日常写法:状态放在结构体里,结构体由 cx.new 变成 Entity<T>,界面由 render 根据状态生成元素树。下一章我们把这个模型落到一个真实项目结构里。