Hyprland:会话环境与桌面集成排障
本页目录
“终端里能运行,桌面快捷键却不行”通常说明两个进程拿到的环境不同。“服务 active,界面却没有响应”则说明进程存活不等于它连接到了正确的图形会话。排错时把启动来源、环境变量和实际接口分开检查。
从三个问题开始
- 发生故障的是哪个组件:合成器、外壳、portal、输入法,还是应用?
- 它由谁启动:登录管理器、Hyprland、systemd 用户服务,还是交互 Shell?
- 它连接哪个会话:是否拿到了当前
WAYLAND_DISPLAY和相关实例信息?
先记录触发动作和时间,再查看该组件的日志。不要先重启全部桌面服务,这会丢失一些用于定位的状态。
Shell 与用户服务不是同一个环境
交互 Shell 读取 .zshrc 后可能把 ~/.local/bin 加入 PATH;systemd 用户管理器不会自动执行这个文件。因此一个 wrapper 可以在终端里找到,却不能被桌面服务启动。
终端内检查命令来源:
用户管理器的环境可以通过 systemctl --user show-environment 查看。只比较相关变量,避免把完整环境直接发到公开渠道。
若会话由自定义脚本组织,应在合成器创建图形环境后导入明确需要的变量,再启动依赖这些变量的服务:
这些命令应在正确的图形会话内运行;从没有 Wayland 环境的远程 Shell 执行并不能修复会话。使用发行版会话管理或 UWSM 时,优先遵循其生命周期管理,不再叠加一套不相关的启动脚本。
服务的顺序与生命周期
用户服务中,After= 表示顺序,不会自动拉起另一个服务;Wants= 表达启动依赖;PartOf= 可以让服务随目标的停止/重启传播动作。这些字段需要配合实际存在的会话 target。
下面是名为 doc-shell.service 的示意单元,要求已存在并正确管理 hyprland-session.target,且 /usr/bin/qs 和 Caelestia 配置已安装:
[Unit]
Description=Example desktop shell
PartOf=hyprland-session.target
After=graphical-session-pre.target
ConditionEnvironment=WAYLAND_DISPLAY
[Service]
ExecStart=/usr/bin/qs -c caelestia -n
Restart=on-failure
RestartSec=2
[Install]
WantedBy=hyprland-session.target
它解释服务的组成,不应与已经运行的外壳服务同时启用。ConditionEnvironment 只检查变量是否存在,不证明 socket 仍有效;Wayland 会话结束后,还需要会话管理者停止所属服务。systemd 用户会话约定
屏幕共享与文件选择
应用通常通过 xdg-desktop-portal 请求屏幕共享、文件选择等桌面能力,再由对应后端处理。安装了后端不代表请求一定被路由到正确的实现。
在当前用户环境中检查实际服务,名称可能随发行版变化:
检查 XDG_CURRENT_DESKTOP、portal 后端选择配置、当前会话和 PipeWire。若文件选择正常但共享屏幕失败,应继续查 screencast 接口与音视频链路;不同 portal 功能可能由不同后端提供。不要为了“只留一个”而盲目卸载所有其他后端。Hyprland portal
输入法与音频
输入法先分应用测试:原生 Wayland、XWayland、GTK、Qt 可能走不同路径。Fcitx5 进程存在只是第一步,还要检查输入环境、应用配置和当前输入组。编辑器自动切换另见 Neovim 输入。
音频先查询系统状态:
先确认默认设备和实际播放流,再检查外壳音量控件。改变默认输出设备与移动一个已存在的播放流不是完全相同的动作;应用可能保留自己的路由。
用症状选择恢复范围
| 症状 | 先验证 | 恢复范围 |
|---|---|---|
| 外壳消失,窗口仍能移动 | QML 日志、外壳服务 | 修复并重启单个外壳 |
| 快捷键启动失败 | 命令路径、会话 PATH | 修改明确的命令或服务环境 |
| 注销后旧外壳仍在 | 所属 target、残留进程 | 修正会话停止传播 |
| 屏幕共享空白 | portal、PipeWire、会话环境 | 修复对应后端或会话连接 |
| 主题只有部分应用变化 | 模板输出与重载 | 修复单个应用配色链 |
每次恢复后重做原来的触发动作,并测试一次注销/登录。运行中修复能生效,不代表下次登录的启动顺序也正确。