Seelen UI 核心库(seelen-core)完全指南:Rust 核心 + TypeScript/Deno 绑定的混合架构与 Widget/插件/主题开发
【免费下载链接】Seelen-UIThe Fully Customizable Desktop Environment for Windows 10/11.项目地址: https://gitcode.com/GitHub_Trending/se/Seelen-UI
导读
本指南围绕 Seelen-UI 仓库中的核心库libs/core(即 readme.md 中所述的Seelen UI Library)展开,它并非应用本体,而是 Seelen UI 用于"创建和管理 Widget、插件(plugin)、主题(theme)"的基础库(core library)。Seelen UI 是一个面向 Windows 10/11 的高度可定制桌面环境(README 中描述为 "The Fully Customizable Desktop Environment for Windows 10/11."),而本库正是其扩展生态的基石。读完本文,你将理解该库"Rust 核心 + TypeScript/Deno 绑定"的混合架构、如何通过 JSR/npm 安装与构建、命令/事件/状态的调用模型,以及它在设置、主题、插件、Widget、系统状态等模块中的落地形态。
定位:Seelen UI 的"核心库"而非应用本体
仓库根目录的 libs/core/readme.md 明确界定了该库的职责:为 Seelen UI 提供创建和管理Widget(控件/小组件)、插件(Plugin)、主题(Theme)所必需的工具与类型。它是 Seelen UI 应用内 Widget 渲染与插件机制的类型契约和运行时桥接层,其 TypeScript 侧包描述也直接写为 "Seelen UI Library for Widgets"(见 libs/core/deno.json)。
从包元数据看,Cargo 包名为seelen-core,版本2.8.5(libs/core/Cargo.toml),与 libs/core/deno.json 中@seelen-ui/lib的版本保持一致——Rust 核心与 TS 绑定同源同版本发布,这是理解该库版本策略的关键。
混合架构:Rust 核心 + TypeScript/Deno 绑定
该库的核心设计是同一套领域模型用 Rust 定义、向 TypeScript 导出类型,从而在保证类型安全的同时兼顾性能。源码布局清晰反映了这一分层:
- Rust 侧(libs/core/src/lib.rs)暴露模块:
constants、error、handlers、rect、resource、state、system_state、utils,并 re-export 了chrono、SeelenLibError与rect相关类型。 - TS 侧(libs/core/src/lib.ts)以同名模块 re-export 为主,并额外导出与 Tauri 后端通信的关键 API:
invoke、SeelenCommand、SeelenEvent、subscribe等。
值得注意的设计细节:
入口文件是 mod.ts 而非 src/lib.ts。由于
@deno/dnt存在一个已知 bug(循环依赖检测问题),libs/core/mod.ts 作为 re-export 中转层存在,并提醒开发者使用madge --circular ./mod.ts检测循环依赖。类型生成走
cargo test而非构建二进制。见 libs/core/scripts/rust_bindings.ts 中的注释:"yeah cargo test generates the typescript bindings, why? ask to @aleph-alpha/ts-rs",即通过cargo test --features gen-binds触发ts-rs生成 TS 绑定与 JSON Schema。Rust 侧对应测试为 libs/core/src/lib.rs 的generate_schemas:它会生成settings.schema.json、settings_by_app.schema.json、theme.schema.json、plugin.schema.json、widget.schema.json、icon_pack.schema.json六份 JSON Schema,并调用SeelenEvent::generate_ts_file与SeelenCommand::generate_ts_file生成 src/handlers/events.ts 与 src/handlers/commands.ts(这两个文件头部都标注"This file was generated via rust macros. Don't modify manually.")。这解释了为什么命令/事件枚举在 Rust 宏中定义、在 TS 中以枚举形式出现——单点定义、双端生效。Cargo features 控制生成能力:
gen-binds(引入ts-rs)与salvo(引入 salvo web 框架,用于 HTTP 服务场景)均为可选 feature(libs/core/Cargo.toml),默认构建不携带,避免无关依赖膨胀。
安装:JSR 与 npm 双通道
原文档给出的安装方式如下(这是使用该库的官方途径):
# JSR(Deno 生态,推荐在 Deno 项目中使用) deno add @seelen-ui/lib # NPM(Node 生态) npm install @seelen-ui/lib包的实际入口与子路径在 libs/core/deno.json 中定义:
.→./src/lib.ts:主入口,导出所有类型与 API;./types→./gen/types/mod.ts:由 Rust 生成的类型绑定入口;./tauri→./src/re-exports/tauri.ts:Tauri 相关 re-export。
此外,构建脚本 libs/core/scripts/build_npm.ts 使用@deno/dnt将 Deno 源码转译为 npm 包(输出到./npm),并做了三件额外的事:
- 把
LICENSE与readme.md复制进 npm 包; - 手动复制
styles/下的 CSS 资产,并在 package.json 中注入./styles/*导出(因为 dnt 只处理 TS/JS); - 移除 npm 包中的
src目录(源码不随包分发,只发布构建产物)。
因此 npm 包除了类型与 JS,还带有@seelen-ui/lib/styles/*的样式资源入口,可供 Widget 直接引用基础样式(styles 目录包含 colors.css、reset.css、shadows.css、spacings.css)。
核心 API:命令、事件与订阅
TS 侧对外暴露的三件套位于 libs/core/src/handlers/mod.ts:
import { invoke, subscribe, SeelenCommand, SeelenEvent } from "@seelen-ui/lib";invoke —— 向后台进程发起调用
invoke是对 Tauriinvoke的类型安全封装:通过SeelenCommand字面量类型约束命令名,并通过条件类型让无参命令无需传参、有参命令强制传入对应参数,返回值也按命令映射(AllSeelenCommandReturns),同时把 Rust 侧的null映射为void/undefined,避免类型空洞。
// 示例:切换工作区 await invoke(SeelenCommand.SwitchWorkspace, { id: 2 }); // 示例:查询系统语言 const langs = await invoke(SeelenCommand.SystemGetLanguages);命令枚举(src/handlers/commands.ts)覆盖面很广,可归纳为几大类:
| 类别 | 代表命令(字符串值) | 说明 |
|---|---|---|
| 工作区/虚拟桌面 | get_virtual_desktops、switch_workspace、create_workspace、destroy_workspace、move_window_to_workspace | 多桌面管理 |
| 壁纸 | wallpaper_next、wallpaper_prev、set_as_wallpaper、wallpaper_save_thumbnail | 壁纸轮换与设置 |
| 系统外观 | get_system_colors、set_system_accent_color、get_system_dark_mode、set_system_dark_mode、get_foreground_window_color | 主题色/深色模式联动 |
| 夜间模式 | get_system_night_light_settings、set_system_night_light_enabled、set_system_night_light_color_temperature | Windows 夜灯控制 |
| 状态读写 | state_get_settings、state_write_settings、state_get_themes、state_get_plugins、state_get_widgets、state_get_wallpapers、state_get_icon_packs | 各资源的状态查询 |
| 工具/调试 | run、open_file、select_file_on_explorer、log_from_webview、debug_open_dev_tools、debug_get_widgets_statuses | 实用工具与 Widget 调试 |
| Widget 运行时 | trigger_widget、trigger_context_menu、trigger_dialog、set_current_widget_status、set_self_position、get_self_window_handle | Widget 自身的生命周期控制 |
subscribe —— 订阅后台推送事件
subscribe封装了 Tauri 的listen,返回UnSubscriber(取消订阅函数),并通过AllSeelenEventPayloads保证事件名与负载类型一一对应。
const unsub = await subscribe(SeelenEvent.GlobalFocusChanged, ({ payload }) => { // 前台窗口变化时执行逻辑 }); // 组件卸载时取消订阅 unsub();事件枚举(src/handlers/events.ts)同样覆盖系统与状态两大维度:global-focus-changed、global-mouse-move、system::monitors-changed、colors-changed、dark-mode-changed、media-sessions、power-status、bluetooth-devices-changed、clipboard::data-changed、settings-changed、themes、plugins-changed、widgets-changed、UserResources::wallpapers-changed等。Widget 开发者既可通过事件驱动 UI 刷新,也可与invoke组成"读-订阅-更新"的响应式数据流。
状态模型:settings、theme、plugin、widget、wallpaper 与 icon pack
libs/core/src/state/mod.ts(TS 侧)与 libs/core/src/state/mod.rs(Rust 侧)共同定义了 Seelen UI 的全部可配置资源类型。Rust 侧模块划分如下(libs/core/src/state/mod.rs):
mod icon_pack; // 图标包 mod placeholder; // 占位资源 mod plugin; // 插件(含 twm 窗口管理器 / weg 桌面组件等子类型) pub mod settings; // 设置(按显示器/主题/壁纸/Widget 拆分 + 按应用覆盖 settings_by_app + 快捷键) mod theme; // 主题(config.rs 定义结构,tests.rs 提供测试) mod wallpaper; // 壁纸 mod weg_items; // 桌面组件条目 mod widget; // Widget(declaration/dialog/context_menu/positioning 等) mod wm_layout; // 窗口管理器布局 mod workspaces; // 工作区其中settings子模块的分层设计非常典型(libs/core/src/state/settings/):
by_monitor.rs、by_theme.rs、by_wallpaper.rs、by_widget.rs:把设置按显示器、主题、壁纸、Widget 四个维度拆分,允许同一功能在不同场景下有不同的配置覆盖;settings_by_app.rs:按应用粒度覆盖(对应 JSON Schema 中的settings_by_app.schema.json,即Vec<AppConfig>);shortcuts.rs:快捷键配置。
theme 模块除结构定义(config.rs)外还自带 tests.rs 与 TS 侧 theming.ts,说明主题不仅是数据,还包含可运行的主题化逻辑。
widget 模块的 TS 侧组织(libs/core/src/state/widget/)体现了 Widget 抽象的渐进式分层:abstractions/目录下0_core.ts、1_rect.ts、2_triggering.ts、3_autosize.ts按依赖顺序组织,加上positioning.ts(定位)、performance.ts(性能)、interfaces.ts(接口),外加 Rust 侧的declaration.rs、dialog.rs、context_menu.rs——可以说 Widget 开发所需的一切契约都在这里。
系统状态:monitors、ui_colors、language、user 与 bluetooth
libs/core/src/system_state/ 承载运行时系统快照类型,TS 侧入口 libs/core/src/system_state/mod.ts 导出monitors、ui_colors、language、user与bluetooth。
值得展开的两点:
- ui_colors(ui_colors.rs 与 ui_colors.ts):把 Windows 的 Mica/亚克力、强调色等系统取色结果结构化为
UiColors,配合事件colors-changed与命令get_system_colors,让 Widget 能跟随系统主题动态取色(这是动态主题色 Widget 的数据来源)。 - bluetooth(system_state/bluetooth/):通过
build_enums.rs从class_of_device.yml、appearance_values.yml等 YAML 清单构建枚举(如ClassOfDevice、LowEnergyAppearance),再生成对应 Rust 枚举(class_of_device_enums.rs、low_energy_enums.rs)。这套"YAML 驱动代码生成"的模式保证了蓝牙设备分类的枚举与规范同步,最终同样通过generate_schemas导出到 TS 侧(bluetooth/mod.ts)。
工具函数与运行时能力
libs/core/src/utils/mod.ts 提供三个开箱即用的工具:
import { Rect, isSeelenUIRuntime, RuntimeStyleSheet } from "@seelen-ui/lib"; const r = new Rect(); // 默认全 0,表示一个矩形区域 if (isSeelenUIRuntime()) { // 仅在 Seelen UI Widget 运行时内为 true }Rect:矩形数据结构(left/top/right/bottom),对应 Rust 侧 libs/core/src/rect.rs;isSeelenUIRuntime():通过检测globalThis.window.__SLU_WIDGET判断当前环境是否为 Seelen UI Widget 运行时(注意:该函数与 TypeScript 的instanceof不同,它不检查某个类,而是检查全局标记,返回布尔值;文档示例中用globalThis.window as any断言是因为部分环境类型定义未声明该属性);RuntimeStyleSheet:来自 utils/DOM.ts,用于在 Widget 中动态注入/管理样式表。
此外 libs/core/src/utils/ 还包含List.ts、State.ts、async.ts等 TS 工具,以及 Rust 侧的slug.rs(slug 化)、traits.rs。而 libs/core/src/constants/mod.ts 定义了SupportedLanguages常量数组与SupportedLanguagesCode类型,覆盖 80 余种语言(含zh-CN、zh-TW),是语言选择器与 i18n 的基础。
构建与开发工作流
开发者若要从源码构建该库,可依据 libs/core/deno.json 中的 tasks:
# 1. 生成 Rust → TS 绑定与 JSON Schema(内部调用 cargo test --features gen-binds) deno task build:rs # 2. 使用 @deno/dnt 构建 npm 包到 ./npm deno task build:npm # 或者一步到位 deno task build测试配置("test"字段)会运行src/**/*.test.ts下的 TS 测试,仓库中已有 libs/core/src/lib.test.ts、icon_pack.test.ts 等测试文件;lint 强制explicit-function-return-type规则(显式函数返回类型),这也是该库强调类型安全的一个佐证。
运行时集成:从核心库到 Seelen UI 应用
libs/core的代码主要在以下两种场景被消费:
- Seelen UI 应用内的 Widget/插件/主题:它们在独立的 WebView 中运行,通过
invoke/subscribe与后台 Rust 进程通信。src/ui/(应用内置 UI)与src/static/widgets/(内置 Widget 目录)下的代码即是这些契约的直接消费者。 - 第三方扩展开发者:通过 JSR/npm 安装
@seelen-ui/lib,复用类型与 API 编写自己的 Widget、插件、主题,再放入 Seelen UI 的资源目录(如src/static/widgets/所示的 Widget 结构、src/static/plugins/所示的插件结构、src/static/themes/所示主题结构)供应用加载。
总结
libs/core的价值在于:用 Rust 单点定义领域模型,通过宏与ts-rs/schemars自动生成 TS 类型与 JSON Schema,再以invoke/subscribe桥接 Tauri 前后端。它同时为 Widget、插件、主题三类扩展提供类型安全的基础设施,是理解 Seelen UI 扩展机制的关键入口。对开发者而言,掌握命令/事件两张枚举表(commands.ts、events.ts),即可对接 Seelen UI 的绝大多数能力——从工作区管理、壁纸控制到系统取色、夜间模式与状态读写,无需深入底层 Windows API。
【免费下载链接】Seelen-UIThe Fully Customizable Desktop Environment for Windows 10/11.项目地址: https://gitcode.com/GitHub_Trending/se/Seelen-UI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考