Hyprland hyprctl 手册深度解析:通过 CLI 与脚本远程控制合成器
本文以 Hyprland 官方 man 手册 docs/hyprctl.1.rst 为核心,系统讲解 hyprctl 这一 CLI 工具的全部控制命令、信息查询命令与选项用法,并结合 hyprctl 客户端源码、服务端 IPC 实现 与 补全定义文件 深入说明其 Unix Socket 通信机制、实例选择逻辑与退出码约定,帮助你在脚本和自动化场景中对 Hyprland 进行可靠的程序化控制。
一、hyprctl 是什么:定位与调用方式
hyprctl 官方手册(hyprctl.1.rst)对它的定义非常简洁:hyprctl 是一个用于从命令行或脚本控制合成器部分功能的工具。它与 Hyprland 合成器进程解耦,运行在用户 shell 中,通过 IPC 通道向合成器下发指令并读取状态。
手册给出的调用格式(SYNOPSIS)为:
hyprctl [flags] command [args]
flags:可选标志,如-j(JSON 输出)、--batch(批量执行)等,完整清单见手册 OPTIONS 小节及 Strings.hpp 中内置的USAGE帮助文本;command:要执行的命令,分为控制类(CONTROL COMMANDS)与信息类(INFO COMMANDS)两大类;args:命令所需参数,部分命令没有参数时该位置可以填任意内容。
1.1 通信机制:Unix Socket 与实例签名
从源码结构看,hyprctl 与合成器之间通过 Unix Domain Socket 通信,这是理解所有命令行为的前提。
客户端侧(hyprctl/src/main.cpp):
- 运行时目录默认为
$XDG_RUNTIME_DIR/hypr,若该环境变量未设置则回退到/run/user/<uid>/hypr(见getRuntimeDir(),L87-L94); - 连接目标实例由环境变量
HYPRLAND_INSTANCE_SIGNATURE决定,socket 路径为<运行时目录>/<实例签名>/.socket.sock(L231-L241);若该变量未设置,hyprctl 会直接报错HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)——这是最常见的“找不到 Hyprland”错误来源,通常意味着当前 shell 不在 Hyprland 会话内。
服务端侧(src/ipc/s1/Unix.cpp):合成器在自身的实例目录下绑定同一个 .socket.sock 路径,由 src/ipc/s1/S1.cpp 中的 CSocket1 完成请求解析与命令分发。请求串以 [j]、[r]、[a]、[f] 等单字母前缀携带输出格式与行为标志(JSON、刷新状态、含全部输出、跟随模式),随后是命令名与参数,例如 j/monitors、r/dispatch workspace 2。
客户端在发起请求时会先统计请求中的空格数做参数下限校验(request() 中的 minArgs 检查),并设置 5 秒接收超时;高负载下服务端可能出现分段写入,客户端会持续读取直到服务端关闭连接再拼出完整回复(L255-L275),保证批量或大输出场景下回复不被截断。
二、控制命令(CONTROL COMMANDS)
手册将控制类命令归纳为 5 个,它们负责“改变合成器的状态或行为”,共同约定:成功时返回 ok,失败时返回错误信息。
2.1 dispatch:调用调度器
hyprctl dispatch "hl.dsp.exec_cmd('kitty')"
hyprctl dispatch "hl.dsp.window.close()"
dispatch 用于以参数调用一个 dispatcher(快捷键调度器),等价于在配置里触发对应的 keybind 动作。必须提供参数;对无参数的调度器,参数内容可以是任意值。
手册中的示例展示了 Lua 风格的调度器写法(hl.dsp.*),说明在 Lua 配置提供方下,调度器同样可以以表达式形式下发。完整的调度器清单可以在 补全定义文件 的 <DISPATCHERS> 部分查到,涵盖常用类别:
| 类别 | 调度器示例 | 说明 |
|---|---|---|
| 执行与按键转发 | exec、execr、pass、sendshortcut、sendkeystate |
执行 shell 命令、向窗口转发按键 |
| 窗口管理 | killactive、closewindow、togglefloating、setfloating、settiled、fullscreen、fullscreenstate、pin、centerwindow |
关闭、浮动/平铺、全屏、固定、居中 |
| 工作区 | workspace、movetoworkspace、movetoworkspacesilent、renameworkspace、movecurrentworkspacetomonitor、swapactiveworkspaces、togglespecialworkspace |
切换、移动、重命名、跨屏移动工作区 |
| 焦点与布局 | movefocus、movewindow、swapwindow、cyclenext、swapnext、resizeactive、moveactive、resizewindowpixel、movewindowpixel、splitratio |
方向移动、交换、调整大小与分割比例 |
| 组(group) | togglegroup、changegroupactive、lockgroups、moveintogroup、moveoutofgroup、movegroupwindow、denywindowfromgroup |
分组、组内切换、锁定组 |
| 其他 | submap、exit、forcerendererreload、dpms、event、global、focusurgentorlast、focuscurrentorlast、tagwindow、focuswindow、focusmonitor、toggleopaque、movecursor、movecursortocorner、alterzorder、fakefullscreen |
子键位映射、退出、渲染器重载、DPMS、socket2 自定义事件、全局快捷键等 |
例如脚本中常用:hyprctl dispatch workspace 2 切到 2 号工作区;hyprctl dispatch killactive 关闭当前窗口。
2.2 keyword:动态设置配置项
hyprctl keyword bind SUPER,0,pseudo
hyprctl keyword general:border_size 10
keyword 用于动态设置一个配置关键词,语法与在配置文件(hyprland.lua / 传统 hyprland.conf)中书写一致:keyword <关键词> <值>。它不修改配置文件,只改变运行时的配置状态。
手册明确提示:当你的配置提供方是 Lua 时,此命令不生效,应改用下面的 eval。这是因为 Lua 配置由脚本重建,直接改写传统配置树会破坏 Lua 侧的视图一致性。从源码看,keyword 在服务端对应前缀匹配(COMMAND_MATCH_PREFIX)注册的命令(见 src/ipc/s1/Commands.cpp 的 registerBuiltinCommands),客户端要求请求中至少含 2 个空格分隔的参数(request(fullRequest, 2),hyprctl/src/main.cpp L559-L560),即 keyword、名称、值三者缺一不可。
2.3 eval:动态执行 Lua 表达式
hyprctl eval 'hl.bind("SUPER + SHIFT + Q", hl.dsp.exec_cmd("firefox"))'
hyprctl eval 'hl.config({ general = { border_size = 10 } })'
eval 在使用 Lua 配置提供方时动态求值任意 Lua 表达式,可以访问 hl.* API:上例分别是运行时注册一个快捷键、以及修改 general.border_size 配置。dispatch 示例中的 hl.dsp.exec_cmd('kitty')、hl.dsp.window.close() 正是通过调度器执行 Lua 表达式的写法。
除一次性 eval 外,USAGE 帮助 中还提供了 repl [code]:不带代码时进入交互式 Lua REPL(^D 退出,支持 readline 历史与多行续行,见 main.cpp L569-L597),带代码时则单次执行并打印结果——对调试 Lua 配置非常实用。
2.4 reload:强制重载配置
hyprctl reload
强制重新加载配置文件。USAGE 帮助 说明其支持可选参数 config-only:hyprctl reload config-only 仅重载配置而跳过显示器(monitor)重载,适合只想应用配置改动、不希望触发热插拔流程的场景。服务端侧该命令按前缀匹配注册(Commands.cpp L1965),因此可以透传后续参数。
2.5 kill:点击杀窗模式
hyprctl kill
进入 kill mode:移动鼠标点击任意应用即可将其关闭;按 ESCAPE 退出该模式。它与 dispatch killactive 的区别在于目标由鼠标点选决定,无需窗口处于聚焦状态。
三、信息命令(INFO COMMANDS)
手册列出的信息命令用于读取合成器当前状态,输出为人类可读文本,配合 -j 可得到 JSON。以下先完整覆盖手册所列 9 个命令,再结合 USAGE 帮助文本 补齐当前版本实际可用的更多命令。
3.1 手册覆盖的 9 个命令
| 命令 | 手册描述 | 用途 |
|---|---|---|
version |
打印 Hyprland 版本、编译 flags、commit 与分支 | 故障排查、版本确认 |
monitors |
列出所有输出及其属性 | 查看分辨率、缩放、方向等;USAGE 补充:monitors all 会同时列出非激活输出 |
workspaces |
列出所有工作区及其属性 | 查看工作区占用、焦点、全屏等状态 |
clients |
列出所有窗口及其属性 | 脚本常配合 awk 提取 class、title 字段 |
devices |
列出所有已连接输入设备 | 键盘、鼠标等设备名可用于 switchxkblayout |
activewindow |
返回当前活动窗口名 | 状态栏、窗口监控常用 |
layers |
列出所有 layer(层级表面) | 查看 layer-shell 面板、状态栏等 |
splash |
返回当前随机欢迎语(splash) | 纯展示性输出 |
status |
返回内部状态信息,如配置格式、后端 | 判断当前配置提供方(传统/Lua)与后端类型 |
3.2 当前版本中的扩展命令
从 Strings.hpp 的完整 USAGE 帮助文本看,实际可用信息命令比手册更全,常用的包括:
activeworkspace:活动工作区及属性(与workspaces互补);animations:当前动画与贝塞尔曲线配置;binds:所有已注册的快捷键绑定;configerrors:当前所有配置解析错误,排错配置时非常有用;cursorpos:光标在全局布局坐标下的位置;descriptions:输出包含全部配置项、描述、值类型与取值范围的可解析 JSON,是程序化读取配置元信息的入口(服务端直接调用Config::Values::getAsJson(),见 Commands.cpp L1905-L1907);getoption <option>:读取某个配置项的当前值;globalshortcuts:所有全局快捷键(配合 globalshortcuts portal);instances:列出所有运行中的 Hyprland 实例(签名、时间戳、PID、Wayland socket),该命令不依赖 HYPRLAND_INSTANCE_SIGNATURE,多实例环境的管理入口;layouts:列出所有可用布局(含插件提供的布局);systeminfo:系统信息(可附带配置内容);workspacerules:已定义的工作区规则列表;decorations <window_regex>、setprop/getprop:窗口装饰与属性读写,setprop支持可选的lock参数防止被动态 windowrule 覆盖(见 SETPROP_HELP)。
此外还有交互/输出类子命令 hyprpaper(壁纸)、hyprsunset(色温)、plugin(插件 load/unload/list)、notify(内置通知)、output(创建/移除虚拟输出)、switchxkblayout、setcursor、seterror、rollinglog(支持 -f/--follow 跟踪日志)等,各自的子命令说明由 hyprctl <cmd> --help 输出对应的帮助文本(main.cpp L446-L467),例如 OUTPUT_HELP 说明了 output create wayland|x11|headless|auto 与 output remove <name> 的用法。
3.3 服务端的命令注册模型
从源码结构看,信息命令与控制命令在服务端统一注册进 CSocket1 的命令表:Commands.cpp L1936-L1978 中每个命令由 SCommand{name, match, handler} 描述,match 区分精确匹配(如 workspaces)与前缀匹配(如 monitors、dispatch、eval、reload),前缀匹配用于透传命令的后续参数;handler 接收解析后的 SRequest(含格式、刷新标志、是否包含非活动输出等),返回文本或 JSON 回复。这一注册模型也意味着插件可以注册自己的 IPC 命令(如 plugin、hyprpaper 通道),扩展 hyprctl 的能力边界。
四、选项(OPTIONS)
4.1 -j:JSON 输出
hyprctl -j clients
-j 让信息类命令以 JSON 输出,是脚本解析状态数据的标准方式。在 main.cpp L421-L423 中,-j 会转换为请求前缀中的 j 标志随请求发送;服务端据此切换 FORMAT_JSON 输出格式(见 S1.hpp 的 eOutputFormat)。
4.2 --batch:批量执行命令
hyprctl --batch "keyword general:border_size 2 ; keyword general:gaps_out 20"
--batch 指定一批要执行的命令,命令之间用 ; 分隔。其底层实现在 batchRequest():客户端将命令串加上 [[BATCH]] 标记后整体发送,由服务端统一调度执行;当同时使用 -j 时,客户端还会在每条命令前插入 j/ 前缀,使批次内每条子命令都以 JSON 格式回复。批量执行适合需要原子性地连续修改多项配置的场景,避免多次 socket 往返。
4.3 手册未覆盖、但源码确认的其他选项
USAGE 帮助 与 hyprctl.usage 共同确认了更完整的选项集合:
| 选项 | 作用 |
|---|---|
-i / --instance <sig|index> |
指定目标实例:可以是完整签名,也可以是 hyprctl instances 列表中的序号(0、1、…);源码在 main.cpp L501-L528 中实现:含下划线的参数按签名处理,纯数字按实例索引查找 |
-r |
命令下发后刷新状态(用于更新变量类状态) |
-q / --quiet |
禁用 hyprctl 输出(配合 -i 做静默检测等) |
-f / --follow |
仅 rollinglog 支持:持续跟踪日志,客户端进入 rollingRead() 循环读取直至 SIGINT(main.cpp L174-L203) |
-h / --help |
打印帮助;对 notify、output、plugin、setprop 等带子命令的项会打印各自的专项帮助 |
使用多实例(如多用户或多会话并行运行 Hyprland)时,instances + -i 的组合是唯一可靠地跨实例定位的手段。
五、返回值与退出码:编写健壮脚本的依据
手册约定控制命令“成功返回 ok,失败返回错误信息”。从 request() 的实现看,hyprctl 的进程退出码同样有明确语义,脚本可直接据此分支:
| 退出码 | 含义 |
|---|---|
| 0 | 成功,回复正常返回 |
| 1 | 无法创建 socket / 参数错误(如打印 USAGE 后返回) |
| 2 | 无法设置 socket 超时 / 缺少实例签名(部分路径) |
| 3 | HYPRLAND_INSTANCE_SIGNATURE 未设置——Hyprland 未运行或 shell 不在其会话内 |
| 4 | 无法连接目标 socket 路径 |
| 5 | 向 socket 写入失败(rollingRead 路径下表示读取失败) |
| 6 | 读取回复失败(含 5 秒超时未收到 IPC 响应) |
| 7 | 服务端回复以 error: 开头,即业务层面失败 |
| 8 | 仅交互式 Lua REPL:检测到行未完成的语法错误提示,用于多行续行 |
由此,典型的脚本健壮性写法是:先判断退出码是否为 3/4(连接性问题),再判断 7(业务错误),最后解析 stdout 中的 ok/error 文本。
六、Shell 补全与配套资源
仓库为 hyprctl 提供了三种 Shell 的补全脚本:hyprctl.bash、hyprctl.fish、hyprctl.zsh,它们由 hyprctl.usage 经 complgen 工具生成(文件头注释给出了再生成命令)。该 usage 文件同时是理解 hyprctl 参数空间的一份机器可读清单:<ARGUMENTS> 枚举全部命令、<DISPATCHERS> 枚举全部调度器、<NOTIFICATION_TYPES> 与 <PROPS> 分别约束 notify 图标编号与 setprop 可写属性,<WINDOWS>、<MONITORS>、<KEYBOARDS> 等还定义了动态补全来源(例如窗口类名来自 hyprctl clients 输出),可见 hyprctl 的输出本身就是后续命令补全的数据源,二者天然构成闭环。
测试侧,hyprtester 目录下的 hyprctlCompat.cpp 提供了与 hyprctl 兼容的测试通道,用于自动化测试中模拟对合成器的 hyprctl 式调用,进一步印证了上述“请求前缀 + Unix socket”协议是 Hyprland 自身测试体系也依赖的稳定接口。
七、手册元信息与延伸阅读
按 hyprctl.1.rst 的原始声明:
- 名称:
hyprctl——Utility for controlling parts of Hyprland from a CLI or a script; - Bug 报告:面向在线 issue 渠道提交(手册指向上游 issue 跟踪);
- 版权:Copyright (c) 2022, vaxerski;
- 配套文件:同名 roff 手册页 docs/hyprctl.1 由 Pandoc 自动生成的 man 页面,内容与 RST 源一致,安装后可直接
man hyprctl查阅。
关键源码索引
| 主题 | 路径 |
|---|---|
| 客户端入口、参数解析、socket 通信 | hyprctl/src/main.cpp |
| 完整 USAGE 与各子命令帮助文本 | hyprctl/src/Strings.hpp |
| 补全/命令与调度器枚举清单 | hyprctl/hyprctl.usage |
| 服务端命令注册与处理 | src/ipc/s1/Commands.cpp |
| 服务端 socket 绑定 | src/ipc/s1/Unix.cpp |
| 请求/响应与命令模型 | src/ipc/s1/S1.hpp |
适用前提与限制:以上行为均以当前仓库版本的源码与手册为准;keyword/eval 的可用性取决于当前配置提供方(传统配置或 Lua 配置);monitors all、repl、descriptions 等扩展命令以实际运行的 Hyprland 构建版本支持为准,可通过 hyprctl --help 现场确认。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00