01 · 全景与心智模型¶
如果只看到 432 个 omarchy-* 文件,Omarchy 很容易显得像一袋互不相关的脚本。更准确的理解是:它用 430 个被 router 注册的窄命令维护同一个桌面系统的声明、生成状态和副作用。
先把它想成控制面¶
Hyprland、Quickshell、pacman、systemd、PipeWire、NetworkManager 才是实际执行工作的“数据面”。Omarchy 不重新实现它们,而是把用户动作翻译成这些系统已有的接口:
flowchart TB
Intent[用户动作<br/>命令/菜单/快捷键] --> Control[Omarchy 控制面]
Control --> Package[pacman / AUR]
Control --> Service[systemd / D-Bus]
Control --> WM[Hyprland / UWSM]
Control --> Desktop[Quickshell IPC]
Control --> Config[配置编译与链接]
Package --> Machine[可运行的桌面状态]
Service --> Machine
WM --> Machine
Desktop --> Machine
Config --> Machine
这带来一个很实用的判断:一条命令是否“完成”,不能只看它有没有返回 0,还要看下游系统接收了什么、状态写在哪里、失败后能否重放。
六层架构¶
| 层 | 主要位置 | 责任 | 生命周期 |
|---|---|---|---|
| 发行内容 | /usr/share/omarchy |
默认配置、脚本、主题、Shell | 随包升级 |
| 系统集成 | /etc、/usr/lib |
登录、PAM、systemd、pacman hook | root 管理 |
| 用户意图 | ~/.config/omarchy 等 |
显式定制和扩展 | 用户持有 |
| 生成状态 | ~/.local/state/omarchy |
当前主题、模块、完成标记 | 可重建或迁移 |
| 图形运行时 | Hyprland + Quickshell | UI、通知、面板、IPC | 每次会话 |
| 瞬态协调 | $XDG_RUNTIME_DIR、/tmp |
锁、握手、日志、选择结果 | 进程/启动周期 |
层之间不是随意互写。比如主题源属于发行内容或用户意图;omarchy-theme-set 把它编译到生成状态;Shell 再读取活动结果。直接修改生成目录会在下次切换时丢失,这是设计使然。
三条主生命周期¶
生命周期 A:机器变成 Omarchy¶
stateDiagram-v2
[*] --> Packages: 安装包
Packages --> SystemApplied: root 应用系统配置
SystemApplied --> UserProvisioned: 创建/确定 owner
UserProvisioned --> Finalized: 用户目录 finalization
Finalized --> FirstRun: 首次图形登录
FirstRun --> Ready: 会话服务就绪
root 阶段不能可靠操作用户 D-Bus、DConf、通知与音频会话,所以安装被刻意切成系统应用、用户 finalization 和图形 first-run。这里的“多阶段”不是历史包袱,而是权限和可用性边界。
生命周期 B:用户操作桌面¶
sequenceDiagram
participant U as 用户
participant C as omarchy CLI
participant S as Quickshell
participant O as OS 服务
U->>C: 快捷键/菜单/终端命令
alt 需要桌面 UI
C->>S: IPC 调用
S-->>U: panel/overlay/toast
else 需要系统副作用
C->>O: hyprctl/systemctl/pacman/配置写入
O-->>C: 状态/退出码
end
CLI 与 Shell 并非两套产品。CLI 是稳定的动作边界,Shell 是常驻 UI 和服务宿主。菜单、快捷键和终端最终可以复用同一动作。
生命周期 C:系统持续演进¶
flowchart LR
Lock[更新锁] --> Space[空间检查]
Space --> Snapshot[创建快照]
Snapshot --> Packages[系统包事务]
Packages --> Migrations[顺序迁移]
Migrations --> Hooks[用户 post-update hook]
Hooks --> Extras[AUR / mise / 清理]
Extras --> Restart[必要时重启服务]
包事务是迁移前的屏障:新脚本和新默认值先到位,迁移才开始改变用户/系统状态。每个迁移只有成功后才写 marker,因此失败可以续跑。
两种扩展哲学¶
Omarchy 同时采用了两种扩展方式:
- 数据扩展:菜单 JSON、主题 TOML、desktop 文件。这类更容易验证和合并;
- 代码扩展:插件 QML、用户 Lua、hook 脚本。这类能力更强,也需要明确的信任边界。
最新快照恰好强化了这个区别:远程下载的主题只能被当作数据,不得借主题安装执行 Lua 或终端配置。用户主动维护的本地工作副本则被视为另一种信任级别。
五个反复出现的设计原则¶
1. 小入口,大组合¶
每个 omarchy-* 命令尽量只做一件事;顶层流程通过 source 或子命令组合它们。代价是文件多,收益是动作可从 CLI、菜单、迁移和测试复用。
2. 成功才留事实¶
finalization、first-run 和 migration 都用 marker 表示完成。关键不是“有 marker”,而是 marker 写入必须晚于全部必要副作用。
3. 生成物与手写配置分离¶
~/.config 表达意图,~/.local/state 保存编译/选择结果。这个区分让原子切换、回退和重建成为可能。
4. 快路径服务日常,慢路径服务发现¶
CLI 正常执行通过文件名做最长前缀匹配,不扫描所有命令;只有 help、list、alias 和检查才建立完整元数据注册表。
5. 失败边界要看得见¶
Shell IPC 不自动启动 Shell,迁移不吞掉失败,升级验证失败明确阻止 reboot。这些选择牺牲了一点“看起来总能工作”,换来真实状态不被掩盖。
关键源码索引¶
docs/file-layout.md— 官方文件布局与 package-backed 边界bin/omarchy— 控制面统一 CLIbin/omarchy-apply-system— 系统阶段入口shell/shell.qml— 桌面常驻运行时bin/omarchy-update— 持续演进总入口
下一章把这张逻辑图落到真实目录和包边界:02 · 仓库地图与安装边界。