如何用 hyprctl output create 为 Hyprland 动态添加和移除虚拟显示器?
【免费下载链接】HyprlandHyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.项目地址: https://gitcode.com/GitHub_Trending/hy/Hyprland
在没有接入新显示器的情况下,你可能需要给 Hyprland 多加一个"屏幕"——比如测试跨屏布局、给远程会话或自动化脚本准备一块独立输出。Hyprland 自带了这条路径:hyprctl output create添加虚拟显示器(fake output),hyprctl output remove移除它,整个过程不需要改配置文件,也不需要重启合成器。
执行前提只有一个:Hyprland 正在运行,且hyprctl能定位到该实例。正常情况下在 Hyprland 会话内的终端执行即可(环境里带有HYPRLAND_INSTANCE_SIGNATURE)。如果这个环境变量缺失,hyprctl会直接报错:
HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?) (3)多个 Hyprland 实例共存时,可以用-i <instance>指定目标实例,实例 ID 可通过hyprctl instances查看(见 hyprctl 源码)。
命令格式与参数
hyprctl output的完整用法说明如下(来自 OUTPUT_HELP):
usage: hyprctl [flags] output <create <backend> | remove <name>> create <backend>: Creates new virtual output. Possible values for backend: wayland, x11, headless or auto. remove <name>: Removes virtual output. Pass the output's name, as found in 'hyprctl monitors' flags: See 'hyprctl --help'也就是说两个子命令:
output create <backend> [name]:新建一个虚拟显示器。backend可选wayland、x11、headless、auto(取值范围同时见 hyprctl.usage)。output remove <name>:移除一个虚拟显示器,<name>必须是hyprctl monitors里看到的输出名。
创建时的名称可以自定义,例如测试代码里使用的HEADLESS-2、HYPRTEST-2(见 hyprtester/src/main.cpp)。下文示例统一用HEADLESS-2作为虚拟显示器名,你可以替换成自己的名字,但要注意后面的重名限制。
添加虚拟显示器
最常用的主路径是 headless 后端,直接执行:
hyprctl output create headless HEADLESS-2命令成功时返回ok。从 实现代码 可以看到创建流程的判定逻辑:
- 名称检查:如果传入的名称已被现有显示器占用,返回
Name already taken; - 实显冲突检查:如果该名称已被真实物理显示器使用,返回
A real monitor already uses that name.; - 后端匹配:合成器遍历可用的 Aquamarine 后端实现,headless 后端响应
headless或auto,wayland 后端响应wayland或auto,由匹配到的后端实际创建输出;没有任何后端处理该请求时返回no backend replied to the request。
关于auto:文档只说明它可以匹配 headless 或 wayland 两类后端,没有规定两者并存时的优先顺序,需要确定后端类型时建议直接显式指定headless或wayland。x11是文档列出的取值之一,但当前代码路径中只有 headless 与 wayland 两个后端的匹配分支,选择它时若没有后端响应会得到no backend replied to the request。
带-r标志可以让 hyprctl 在发出命令后刷新状态,-j则以 JSON 格式输出(标志说明见 hyprctl.usage)。
验证显示器是否创建成功
用hyprctl monitors查看当前所有输出及其属性(该命令的说明见 hyprctl.1.rst):
hyprctl monitors新建的虚拟显示器会出现在列表里,其名称就是创建时传入的名字。需要脚本化提取名称时,hyprctl.usage 中给出的补全表达式展示了标准做法:
hyprctl monitors | awk '/Monitor/{ print $2 }'加-j参数(hyprctl -j monitors)可获得 JSON 格式输出,便于进一步处理。
移除虚拟显示器
移除时传入hyprctl monitors中看到的输出名:
hyprctl output remove HEADLESS-2成功同样返回ok,之后该输出从hyprctl monitors的列表中消失。移除操作在 实现代码 中有两条明确的拒绝路径:
- 名称找不到对应显示器:
output not found; - 目标是真实物理显示器而非用户创建的虚拟输出:
cannot remove a real display. Use the monitor keyword.——这条提示指明,物理显示器要走monitor配置关键字去管理,output remove只针对虚拟输出。
常见返回信息与排查
| 返回信息 | 含义 |
|---|---|
ok | 命令成功执行 |
Name already taken | 传入的名称已被现有显示器占用 |
A real monitor already uses that name. | 该名称属于一台真实显示器,不能重复用于虚拟输出 |
no backend replied to the request | 没有任何后端处理所请求的 backend 类型 |
output not found | remove 时未找到该名称的显示器 |
cannot remove a real display. Use the monitor keyword. | 试图移除真实物理显示器 |
这些字符串都来自 dispatchOutput 实现,可以逐字对照排查。另外注意hyprctl遇到以error:开头的回复会返回非零退出码(hyprctl 源码),脚本中可以用退出码判断成败。
限制与边界
hyprctl output只负责虚拟显示器的增删,虚拟显示器不会写入配置文件,Hyprland 重启后即失效;持久化的显示器布局需要用monitor关键字在配置中声明。- 虚拟显示器名称在整个会话内必须唯一,且不能与真实显示器重名。
- 移除操作仅对
m_createdByUser(用户创建)的输出有效,这是源码中对真实显示器的硬拦截。 - 本文所有命令都作用于当前
HYPRLAND_INSTANCE_SIGNATURE指向的实例;多实例环境下务必用-i确认操作对象,避免把虚拟显示器加到错误的合成器实例上。
【免费下载链接】HyprlandHyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.项目地址: https://gitcode.com/GitHub_Trending/hy/Hyprland
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考