跳转至

04 · 会话启动与 Hyprland

安装完成只是“磁盘上有系统”。真正的桌面从 SDDM 选择 Omarchy 会话开始,经 UWSM 导入环境,再由 Hyprland Lua 入口组装默认值、用户覆盖与动态状态。

启动链

sequenceDiagram
    participant S as SDDM
    participant D as omarchy.desktop
    participant U as UWSM
    participant E as env-bootstrap
    participant H as Hyprland
    participant L as hyprland.lua
    S->>D: 选择 Omarchy session
    D->>U: uwsm start ... hyprland.desktop
    U->>E: 导入 10-omarchy 环境
    E-->>U: OMARCHY_PATH / PATH / session vars
    U->>H: 启动受 systemd 管理的 compositor
    H->>L: 载入用户 Lua 入口

UWSM 不是多余的一层包装。它把 Wayland compositor 纳入 user systemd 会话,统一环境导入、应用 scope 和生命周期;Omarchy 的 Shell、应用启动器与用户服务因此共享同一会话语境。

环境只建立一次语义

default/uwsm/env.d/10-omarchy source env-bootstrap,再声明桌面会话默认值。env-bootstrap 同时被 shell/profile 路径复用,目标是让下列入口得到同一个 OMARCHY_PATH:

  • 交互式 shell;
  • 非登录 shell;
  • UWSM 图形会话;
  • 由快捷键或 desktop entry 启动的应用。

如果只在 .bashrc 里设置开发路径,图形会话通常看不到;这就是专门的 UWSM env.d 存在的原因。

Lua 入口是一张覆盖顺序表

用户的 ~/.config/hypr/hyprland.lua 不是把所有配置写在一个文件里,而是按明确顺序加载:

dofile(OMARCHY_PATH .. "/default/hypr/bootstrap.lua")
require("default.hypr.omarchy")
require("hypr.monitors")
require("hypr.input")
require("hypr.bindings")
require("hypr.looknfeel")
require("hypr.autostart")
require("default.hypr.toggles")

这段顺序本身就是配置契约:发行默认值先建立,用户模块随后覆盖,动态 toggle 最后附加。

bootstrap 做了什么

1. 清理可重载模块

Hyprland reload 并不会启动一个全新的 Lua VM。bootstrap 主动从 package.loaded 清掉选定前缀,保证被 require 的配置模块可以重新求值,否则 reload 可能继续复用旧表。

2. 建立查找优先级

Lua package.path 的核心优先级是:

~/.local/state/?.lua
~/.config/?.lua
$OMARCHY_PATH/?.lua

这与整个系统的状态模型一致:动态生成状态优先,用户显式配置其次,发行默认值兜底。

3. 提供 Hyprland 配置 DSL 基础

默认 helpers 和模块把窗口规则、绑定、monitor、workspace 等配置写成 Lua 组合,而不是拼接一份长文本。Lua 仍最终驱动 Hyprland 的配置对象,并没有替代 compositor。

默认模块的内部次序

default/hypr/omarchy.lua 大致依次加载:

  1. helpers 与路径;
  2. input / autostart / bindings 等默认集合;
  3. 可选的预装应用绑定;
  4. 环境变量;
  5. look and feel;
  6. window rules;
  7. 当前生成主题。

目录型模块由 require_all.files 按文件名排序加载。排序使默认集合可预测,也意味着新增文件名会参与顺序语义,不能假设文件系统遍历的偶然顺序。

flowchart TD
    Entry[用户 hyprland.lua] --> Boot[bootstrap]
    Boot --> Default[default.hypr.omarchy]
    Default --> Helpers[helpers / paths]
    Default --> Groups[bindings / apps / windows]
    Default --> Theme[current theme]
    Default --> User[用户 monitors/input/bindings/look/autostart]
    User --> Toggle[state 中的动态 toggles]

动态 toggle 为什么写进 state

窗口间距、透明度、workspace layout 等切换需要跨 Hyprland reload 保留,但它们又不是用户长期手写的声明。Omarchy 将生成的 Lua 片段放入 ~/.local/state,让它在 package 与用户配置之前被找到,并触发 Hyprland reload。

这是一种小型“配置编译”:CLI 改变状态,生成 Lua,compositor 重新读取。相比直接对运行中对象发一串临时命令,它更容易在 reload 后保持一致。

用户覆盖的边界

用户可以:

  • 在标准 hypr.* 模块中覆盖默认值;
  • 关闭全部 Omarchy 默认 bindings;
  • 只关闭预装应用 bindings,保留核心窗口管理绑定;
  • 在入口末尾添加额外 Lua。

但不应该直接修改 $OMARCHY_PATH/default/hypr,因为它由包拥有。升级应能改进默认值,而不重写 ~/.config/hypr。

排障顺序

现象 检查顺序
终端能找到开发命令,快捷键找不到 UWSM env.d → /etc/omarchy.conf → OMARCHY_PATH
修改用户 Lua 后 reload 仍旧 bootstrap 是否执行 → 模块是否在清理前缀中
用户样式被主题覆盖 加载次序:current theme 与用户 looknfeel 的具体属性
toggle 重启后丢失 ~/.local/state 生成模块与写权限
应用不在 systemd scope 是否经 uwsm-app / desktop session 启动

关键源码索引

会话准备好后,用户面对的统一入口是 CLI:05 · 元数据驱动的 CLI。