简体中文 · English
轻量跨平台桌面 GUI 框架 — 用 Rust 构建内存友好的小工具。
平台原生窗口 · tiny-skia 矢量渲染 · 平台原生文字排版 · 无运行时 · 无 GC。
| 平台 | 窗口/呈现 | 文字 |
|---|---|---|
| Windows | Win32 + GDI(DIB 拷屏) | DirectWrite |
| macOS | Cocoa/AppKit + CoreGraphics(CGImage blit) | Core Text |
渲染层(tiny-skia)与全部控件/布局/事件逻辑平台无关;每个平台只实现「窗口+事件循环」与「文字引擎」两条缝。
做小工具时,Electron 动辄上百 MB,Go GUI 因 runtime/GC 也要 15–40MB。windui 没有运行时、没有垃圾回收,Windows 上的实测:
| 指标 | 实测值 |
|---|---|
| 二进制体积(release,LTO+strip) | 最小窗口应用 0.64 MB;综合示例(全控件 + SVG)1.38 MB |
| 私有内存(PrivateBytes,100% 缩放) | 最小窗口 480×320 2.7 MB;关于窗 620×556 5.5 MB |
| 同上,200% 缩放 | 4.6 MB / 14.2 MB |
| 跨平台直接依赖 | tiny-skia(渲染)· resvg(SVG,默认开,不用则被 LTO 裁掉)· serde + toml(主题);平台系统绑定按 target 引入 |
内存数字离开 DPI 就没有意义:大头是软件光栅为窗口留的约 2.5 份全屏 RGBA 缓冲, 而缓冲按物理像素分配——200% 缩放下同一窗口的物理面积是 100% 的 4 倍,内存也跟着翻。 上表两行是同一批二进制在两种缩放下的实测,不是两套代码。
工作集另含 gdi32/dwrite 等跨进程共享的系统 DLL 映射(关于窗 100% 下约 22MB), 进程真正独占的只有上表的私有内存。
全部数字由
scripts/measure_footprint.ps1实测,跑一遍即可复现。
Signal<T>,闭包里 move 直接捕获、不用 clone() 前戏;set() 自动触发重绘。数据变化驱动子树重建(list_signal),动态列表不用手写 diff。App::theme_handle() 拿句柄,回调里 set(Theme::dark()) 即整树热切换;用 Role 表达的颜色(fg_role/bg_role)自动跟随。App::accelerated(true)),几何/渐变/阴影/文字光栅走 GPU;文字仍用 DirectWrite(系统字体缓存、ClearType)。默认软渲染;RDP / 无 GPU / 离屏截图自动回退、绝不 panic。--screenshot 离屏渲染存 PNG(--scale 1.5 验证高 DPI),适合自动化回归。下列截图全部由离屏渲染自动截取(--screenshot,见 scripts/readme_shots.ps1),未作任何后期修饰。
主要示例统一走无边框窗口 + 自绘标题栏——标题栏本身就是控件树的一部分,和正文用同一套布局与主题。
![]() | ![]() |
| 控件总览:七个分页按控件族分组(表单 / 按钮 / 布局 / 文字 / 数据 / 图片 / 关于) | 主题:TOML 部分覆盖 + Role 角色着色,运行期整树热切换 |
![]() | ![]() |
| 模态对话框:背景遮罩 + 带标题栏的面板 + 点单元格即编辑的表格 | 虚拟滚动:列表 10 万行 / 表格 1 万行,只构建视口内的行 |
![]() | ![]() |
| 图片与矢量:PNG/SVG、Fit 模式、圆角裁剪、单色着色 | 关于页:可点击卡片 + 胶囊徽章 + 描边按钮 + Toast |
use windui::prelude::*;
fn main() {
// 状态是 Signal<T>:Copy 句柄,闭包直接捕获,写入自动触发重绘
let on = signal(true);
let ui = Element::col()
.fill()
.padding(20)
.spacing(12)
.bg(Color::hex(0xF5F6FA))
.child(Element::label("Hello, windui!").font_size(22.0).width_match())
.child(Element::checkbox("启用功能", on))
.child(Element::button("确定").on_click(move |ctx| {
println!("checkbox = {}", on.get());
ctx.request_close();
}));
App::new("Demo", 360, 240).content(ui).run();
}
| 类别 | 控件 |
|---|---|
| 布局 | col / row(LinearLayout,支持 weight)、stack(FrameLayout)、grid(等宽网格)、flex_spacer |
| 文本 | label(自动换行)、label_signal(绑信号)、link(可点击链接)、rich(富文本:多样式 span / 折叠段) |
| 按钮 | button(hover/press/focus 三态 + 点击/回车/空格激活)、icon_button(纯图标) |
| 表单 | checkbox / switch / radio(互斥组)/ slider(拖动+键盘)/ text_input(CJK 编辑+密码+多行)/ dropdown / check_menu / stepper / chip / tag_field / color_picker(取色面板) |
| 反馈 | progress(确定/不确定)/ tooltip(悬停提示)/ toast(居中轻提示)/ badge(胶囊徽章) |
| 容器 | scroll(滚轮/触摸+裁剪+滚动条)/ tabs / tabs_pill / divider / dialog(模态)/ dialog_panel(带标题栏)/ visible_when(条件可见) |
| 导航 | segmented(连体多段单选)/ nav_row(钻入行)/ collapsible / accordion·accordion_multi(手风琴) |
| 列表 | list / list_pill(侧栏样式)/ list_icons(单选/滚动/高亮/图标/禁用态)/ list_signal(数据驱动动态列表)/ reorder_list(拖拽排序) |
| 表格 | table(只读)/ table_custom / table_editable / table_sortable / table_sortable_server(服务端排序分页)/ table_selectable(多选) |
| 图片 | image / image_svg / image_view(PNG/SVG,状态调制/着色/圆角) |
| 系统 | 系统托盘(图标 + 左键/双击 + 原生右键菜单)、全局热键、多窗口(ctx.open_window,含单例窗口)、启动即隐藏、关闭转隐藏、无边框窗口(自定义标题栏)、文件拖放、剪贴板 |
控件状态统一绑定 Signal<T>(signal(初值) 创建的 Copy 句柄):checkbox/switch 绑
Signal<bool>、dropdown/list/tabs 绑 Signal<usize>、text_input 绑 Signal<String>。
set() 写入即自动触发重绘,无需手动标脏。用法见 docs/API_GUIDE.md §3.2。
cargo run --release --example fullshowcase # 运行综合示例窗口
cargo run --release --example ime -- --accelerated # 启用 Direct2D GPU 后端(Windows)
cargo run --example fullshowcase -- --screenshot out.png # 离屏渲染存 PNG
cargo test # 运行单元测试
cargo clippy --all-targets # 静态检查
示例按用途分四类:
| 类别 | 示例 |
|---|---|
| 完整应用 | settings(设置窗:标题栏 + 图标侧栏 + 内容 + 底部操作栏 + 两个对话框)、about(关于页)、ime_settings(输入法设置场景)、light_titlebar(安装器风格的浅色标题栏) |
| 控件与能力 | fullshowcase(控件总览,七个分页)、theming(TOML 主题 + 运行期换肤)、image(图片/SVG)、animation、emoji(彩色 emoji)、caret(文本光标四风格) |
| 数据展示 | virtual_list(虚拟滚动列表 + 表格)、virtual_table_server(服务端分页)、table_pager(分页操作栏)、dyn_list(数据驱动动态列表)、list、dropdown、tabs_pill、toast、progress、multiline |
| 系统集成 | tray(系统托盘)、hotkey(全局热键 + 启动即隐藏)、multi_window(子窗 + 跨窗共享状态)、file_drop、frameless(自定义标题栏 + 系统菜单)、background_task(跨线程更新)、ime |
另有 phase0–phase5 分阶段演示与 perfprobe 性能探针,供开发与回归比对使用。
详见 docs/DESIGN.md(架构设计)与 docs/ROADMAP.md(实施路线)。
应用层 App / UiHost(交互宿主,实现 AppHandler)
控件层 Element Builder · Widget trait · 布局算法
核心层 Arena + Node 树 · Measure/Arrange/Paint 三阶段 · 事件分发
渲染层 Canvas trait → tiny-skia 后端(纯 Rust,跨平台)
文字层 TextEngine trait → DirectWrite(Windows)/ Core Text(macOS)
平台层 AppHandler trait → win32(窗口/WndProc/DIB 呈现)/ macos(NSWindow/NSView/CGImage 呈现)
关键设计:节点存于 generational arena(非 Rc<RefCell>),Widget trait 退化为纯内容、布局递归由 Tree 独占 &mut self 驱动 —— 从根上规避 Rust 借用冲突。文字用平台原生引擎在 tiny-skia 预乘缓冲上抗锯齿合成。平台缝合层映射见 docs/MACOS_PORTING.md。
Windows 与 macOS 均已支持。MVP 控件集完成,持续完善中。
| 文档 | 面向 |
|---|---|
docs/API_GUIDE.md | 用本库写应用(API 风格、控件、扩展) |
docs/DEVELOPMENT.md | 在仓库内开发(构建、布局、加控件、平台缝) |
CONTRIBUTING.md | 贡献流程与 DCO 签署 |
docs/DESIGN.md | 架构设计与取舍 |
docs/ROADMAP.md | 实施路线与验收 |
docs/MACOS_PORTING.md | macOS 后端缝合层映射 |
AGENTS.md | 仓库开发约定(流程、陷阱速查) |
双许可,任选其一:
LICENSE-APACHE)LICENSE-MIT)除非另有声明,你有意提交到本仓库的贡献,将按上述双许可授权,无附加条款(见 CONTRIBUTING.md)。
457 commits
Rust
98.7%
简体中文 · English
轻量跨平台桌面 GUI 框架 — 用 Rust 构建内存友好的小工具。
平台原生窗口 · tiny-skia 矢量渲染 · 平台原生文字排版 · 无运行时 · 无 GC。
| 平台 | 窗口/呈现 | 文字 |
|---|---|---|
| Windows | Win32 + GDI(DIB 拷屏) | DirectWrite |
| macOS | Cocoa/AppKit + CoreGraphics(CGImage blit) | Core Text |
渲染层(tiny-skia)与全部控件/布局/事件逻辑平台无关;每个平台只实现「窗口+事件循环」与「文字引擎」两条缝。
做小工具时,Electron 动辄上百 MB,Go GUI 因 runtime/GC 也要 15–40MB。windui 没有运行时、没有垃圾回收,Windows 上的实测:
| 指标 | 实测值 |
|---|---|
| 二进制体积(release,LTO+strip) | 最小窗口应用 0.64 MB;综合示例(全控件 + SVG)1.38 MB |
| 私有内存(PrivateBytes,100% 缩放) | 最小窗口 480×320 2.7 MB;关于窗 620×556 5.5 MB |
| 同上,200% 缩放 | 4.6 MB / 14.2 MB |
| 跨平台直接依赖 | tiny-skia(渲染)· resvg(SVG,默认开,不用则被 LTO 裁掉)· serde + toml(主题);平台系统绑定按 target 引入 |
内存数字离开 DPI 就没有意义:大头是软件光栅为窗口留的约 2.5 份全屏 RGBA 缓冲, 而缓冲按物理像素分配——200% 缩放下同一窗口的物理面积是 100% 的 4 倍,内存也跟着翻。 上表两行是同一批二进制在两种缩放下的实测,不是两套代码。
工作集另含 gdi32/dwrite 等跨进程共享的系统 DLL 映射(关于窗 100% 下约 22MB), 进程真正独占的只有上表的私有内存。
全部数字由
scripts/measure_footprint.ps1实测,跑一遍即可复现。
Signal<T>,闭包里 move 直接捕获、不用 clone() 前戏;set() 自动触发重绘。数据变化驱动子树重建(list_signal),动态列表不用手写 diff。App::theme_handle() 拿句柄,回调里 set(Theme::dark()) 即整树热切换;用 Role 表达的颜色(fg_role/bg_role)自动跟随。App::accelerated(true)),几何/渐变/阴影/文字光栅走 GPU;文字仍用 DirectWrite(系统字体缓存、ClearType)。默认软渲染;RDP / 无 GPU / 离屏截图自动回退、绝不 panic。--screenshot 离屏渲染存 PNG(--scale 1.5 验证高 DPI),适合自动化回归。下列截图全部由离屏渲染自动截取(--screenshot,见 scripts/readme_shots.ps1),未作任何后期修饰。
主要示例统一走无边框窗口 + 自绘标题栏——标题栏本身就是控件树的一部分,和正文用同一套布局与主题。
![]() | ![]() |
| 控件总览:七个分页按控件族分组(表单 / 按钮 / 布局 / 文字 / 数据 / 图片 / 关于) | 主题:TOML 部分覆盖 + Role 角色着色,运行期整树热切换 |
![]() | ![]() |
| 模态对话框:背景遮罩 + 带标题栏的面板 + 点单元格即编辑的表格 | 虚拟滚动:列表 10 万行 / 表格 1 万行,只构建视口内的行 |
![]() | ![]() |
| 图片与矢量:PNG/SVG、Fit 模式、圆角裁剪、单色着色 | 关于页:可点击卡片 + 胶囊徽章 + 描边按钮 + Toast |
use windui::prelude::*;
fn main() {
// 状态是 Signal<T>:Copy 句柄,闭包直接捕获,写入自动触发重绘
let on = signal(true);
let ui = Element::col()
.fill()
.padding(20)
.spacing(12)
.bg(Color::hex(0xF5F6FA))
.child(Element::label("Hello, windui!").font_size(22.0).width_match())
.child(Element::checkbox("启用功能", on))
.child(Element::button("确定").on_click(move |ctx| {
println!("checkbox = {}", on.get());
ctx.request_close();
}));
App::new("Demo", 360, 240).content(ui).run();
}
| 类别 | 控件 |
|---|---|
| 布局 | col / row(LinearLayout,支持 weight)、stack(FrameLayout)、grid(等宽网格)、flex_spacer |
| 文本 | label(自动换行)、label_signal(绑信号)、link(可点击链接)、rich(富文本:多样式 span / 折叠段) |
| 按钮 | button(hover/press/focus 三态 + 点击/回车/空格激活)、icon_button(纯图标) |
| 表单 | checkbox / switch / radio(互斥组)/ slider(拖动+键盘)/ text_input(CJK 编辑+密码+多行)/ dropdown / check_menu / stepper / chip / tag_field / color_picker(取色面板) |
| 反馈 | progress(确定/不确定)/ tooltip(悬停提示)/ toast(居中轻提示)/ badge(胶囊徽章) |
| 容器 | scroll(滚轮/触摸+裁剪+滚动条)/ tabs / tabs_pill / divider / dialog(模态)/ dialog_panel(带标题栏)/ visible_when(条件可见) |
| 导航 | segmented(连体多段单选)/ nav_row(钻入行)/ collapsible / accordion·accordion_multi(手风琴) |
| 列表 | list / list_pill(侧栏样式)/ list_icons(单选/滚动/高亮/图标/禁用态)/ list_signal(数据驱动动态列表)/ reorder_list(拖拽排序) |
| 表格 | table(只读)/ table_custom / table_editable / table_sortable / table_sortable_server(服务端排序分页)/ table_selectable(多选) |
| 图片 | image / image_svg / image_view(PNG/SVG,状态调制/着色/圆角) |
| 系统 | 系统托盘(图标 + 左键/双击 + 原生右键菜单)、全局热键、多窗口(ctx.open_window,含单例窗口)、启动即隐藏、关闭转隐藏、无边框窗口(自定义标题栏)、文件拖放、剪贴板 |
控件状态统一绑定 Signal<T>(signal(初值) 创建的 Copy 句柄):checkbox/switch 绑
Signal<bool>、dropdown/list/tabs 绑 Signal<usize>、text_input 绑 Signal<String>。
set() 写入即自动触发重绘,无需手动标脏。用法见 docs/API_GUIDE.md §3.2。
cargo run --release --example fullshowcase # 运行综合示例窗口
cargo run --release --example ime -- --accelerated # 启用 Direct2D GPU 后端(Windows)
cargo run --example fullshowcase -- --screenshot out.png # 离屏渲染存 PNG
cargo test # 运行单元测试
cargo clippy --all-targets # 静态检查
示例按用途分四类:
| 类别 | 示例 |
|---|---|
| 完整应用 | settings(设置窗:标题栏 + 图标侧栏 + 内容 + 底部操作栏 + 两个对话框)、about(关于页)、ime_settings(输入法设置场景)、light_titlebar(安装器风格的浅色标题栏) |
| 控件与能力 | fullshowcase(控件总览,七个分页)、theming(TOML 主题 + 运行期换肤)、image(图片/SVG)、animation、emoji(彩色 emoji)、caret(文本光标四风格) |
| 数据展示 | virtual_list(虚拟滚动列表 + 表格)、virtual_table_server(服务端分页)、table_pager(分页操作栏)、dyn_list(数据驱动动态列表)、list、dropdown、tabs_pill、toast、progress、multiline |
| 系统集成 | tray(系统托盘)、hotkey(全局热键 + 启动即隐藏)、multi_window(子窗 + 跨窗共享状态)、file_drop、frameless(自定义标题栏 + 系统菜单)、background_task(跨线程更新)、ime |
另有 phase0–phase5 分阶段演示与 perfprobe 性能探针,供开发与回归比对使用。
详见 docs/DESIGN.md(架构设计)与 docs/ROADMAP.md(实施路线)。
应用层 App / UiHost(交互宿主,实现 AppHandler)
控件层 Element Builder · Widget trait · 布局算法
核心层 Arena + Node 树 · Measure/Arrange/Paint 三阶段 · 事件分发
渲染层 Canvas trait → tiny-skia 后端(纯 Rust,跨平台)
文字层 TextEngine trait → DirectWrite(Windows)/ Core Text(macOS)
平台层 AppHandler trait → win32(窗口/WndProc/DIB 呈现)/ macos(NSWindow/NSView/CGImage 呈现)
关键设计:节点存于 generational arena(非 Rc<RefCell>),Widget trait 退化为纯内容、布局递归由 Tree 独占 &mut self 驱动 —— 从根上规避 Rust 借用冲突。文字用平台原生引擎在 tiny-skia 预乘缓冲上抗锯齿合成。平台缝合层映射见 docs/MACOS_PORTING.md。
Windows 与 macOS 均已支持。MVP 控件集完成,持续完善中。
| 文档 | 面向 |
|---|---|
docs/API_GUIDE.md | 用本库写应用(API 风格、控件、扩展) |
docs/DEVELOPMENT.md | 在仓库内开发(构建、布局、加控件、平台缝) |
CONTRIBUTING.md | 贡献流程与 DCO 签署 |
docs/DESIGN.md | 架构设计与取舍 |
docs/ROADMAP.md | 实施路线与验收 |
docs/MACOS_PORTING.md | macOS 后端缝合层映射 |
AGENTS.md | 仓库开发约定(流程、陷阱速查) |
双许可,任选其一:
LICENSE-APACHE)LICENSE-MIT)除非另有声明,你有意提交到本仓库的贡献,将按上述双许可授权,无附加条款(见 CONTRIBUTING.md)。
457 commits
Rust
98.7%