Seelen UI 核心库(seelen-core)完全指南:Rust 核心 + TypeScript/Deno 绑定的混合架构与 Widget/插件/主题开发
2026/9/13 15:20:27 网站建设 项目流程

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)暴露模块:constantserrorhandlersrectresourcestatesystem_stateutils,并 re-export 了chronoSeelenLibErrorrect相关类型。
  • TS 侧(libs/core/src/lib.ts)以同名模块 re-export 为主,并额外导出与 Tauri 后端通信的关键 API:invokeSeelenCommandSeelenEventsubscribe等。

值得注意的设计细节:

  1. 入口文件是 mod.ts 而非 src/lib.ts。由于@deno/dnt存在一个已知 bug(循环依赖检测问题),libs/core/mod.ts 作为 re-export 中转层存在,并提醒开发者使用madge --circular ./mod.ts检测循环依赖。

  2. 类型生成走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.jsonsettings_by_app.schema.jsontheme.schema.jsonplugin.schema.jsonwidget.schema.jsonicon_pack.schema.json六份 JSON Schema,并调用SeelenEvent::generate_ts_fileSeelenCommand::generate_ts_file生成 src/handlers/events.ts 与 src/handlers/commands.ts(这两个文件头部都标注"This file was generated via rust macros. Don't modify manually.")。这解释了为什么命令/事件枚举在 Rust 宏中定义、在 TS 中以枚举形式出现——单点定义、双端生效。

  3. 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),并做了三件额外的事:

  • LICENSEreadme.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_desktopsswitch_workspacecreate_workspacedestroy_workspacemove_window_to_workspace多桌面管理
壁纸wallpaper_nextwallpaper_prevset_as_wallpaperwallpaper_save_thumbnail壁纸轮换与设置
系统外观get_system_colorsset_system_accent_colorget_system_dark_modeset_system_dark_modeget_foreground_window_color主题色/深色模式联动
夜间模式get_system_night_light_settingsset_system_night_light_enabledset_system_night_light_color_temperatureWindows 夜灯控制
状态读写state_get_settingsstate_write_settingsstate_get_themesstate_get_pluginsstate_get_widgetsstate_get_wallpapersstate_get_icon_packs各资源的状态查询
工具/调试runopen_fileselect_file_on_explorerlog_from_webviewdebug_open_dev_toolsdebug_get_widgets_statuses实用工具与 Widget 调试
Widget 运行时trigger_widgettrigger_context_menutrigger_dialogset_current_widget_statusset_self_positionget_self_window_handleWidget 自身的生命周期控制

subscribe —— 订阅后台推送事件

subscribe封装了 Tauri 的listen,返回UnSubscriber(取消订阅函数),并通过AllSeelenEventPayloads保证事件名与负载类型一一对应。

const unsub = await subscribe(SeelenEvent.GlobalFocusChanged, ({ payload }) => { // 前台窗口变化时执行逻辑 }); // 组件卸载时取消订阅 unsub();

事件枚举(src/handlers/events.ts)同样覆盖系统与状态两大维度:global-focus-changedglobal-mouse-movesystem::monitors-changedcolors-changeddark-mode-changedmedia-sessionspower-statusbluetooth-devices-changedclipboard::data-changedsettings-changedthemesplugins-changedwidgets-changedUserResources::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.rsby_theme.rsby_wallpaper.rsby_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.ts1_rect.ts2_triggering.ts3_autosize.ts按依赖顺序组织,加上positioning.ts(定位)、performance.ts(性能)、interfaces.ts(接口),外加 Rust 侧的declaration.rsdialog.rscontext_menu.rs——可以说 Widget 开发所需的一切契约都在这里。

系统状态:monitors、ui_colors、language、user 与 bluetooth

libs/core/src/system_state/ 承载运行时系统快照类型,TS 侧入口 libs/core/src/system_state/mod.ts 导出monitorsui_colorslanguageuserbluetooth

值得展开的两点:

  1. ui_colors(ui_colors.rs 与 ui_colors.ts):把 Windows 的 Mica/亚克力、强调色等系统取色结果结构化为UiColors,配合事件colors-changed与命令get_system_colors,让 Widget 能跟随系统主题动态取色(这是动态主题色 Widget 的数据来源)。
  2. bluetooth(system_state/bluetooth/):通过build_enums.rsclass_of_device.ymlappearance_values.yml等 YAML 清单构建枚举(如ClassOfDeviceLowEnergyAppearance),再生成对应 Rust 枚举(class_of_device_enums.rslow_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.tsState.tsasync.ts等 TS 工具,以及 Rust 侧的slug.rs(slug 化)、traits.rs。而 libs/core/src/constants/mod.ts 定义了SupportedLanguages常量数组与SupportedLanguagesCode类型,覆盖 80 余种语言(含zh-CNzh-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的代码主要在以下两种场景被消费:

  1. Seelen UI 应用内的 Widget/插件/主题:它们在独立的 WebView 中运行,通过invoke/subscribe与后台 Rust 进程通信。src/ui/(应用内置 UI)与src/static/widgets/(内置 Widget 目录)下的代码即是这些契约的直接消费者。
  2. 第三方扩展开发者:通过 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询