有没有一种工具可以让人们:
- 记住每个显示器的当前 RandR 配置(位置、方向、分辨率等),
- 一旦插入显示器,就会自动应用最后一次正确的配置,而无需使用小程序或 xrandr(1) 进行处理?
这些配置必须针对每个用户、每个显示器进行应用。
如果没有这样的工具,我想自己组装一个,但据我所知,没有办法知道监视器已插入。我是否必须使用 xrandr -q 进行轮询偶尔找出输出已连接或断开,或者是否有更有效的方法来做到这一点? udev 可以调整来做到这一点吗?
答案1
关于可以按用户和每个显示器存储显示器配置配置文件的工具,自动排序就会这么做。
我的笔记本电脑有 NVIDIA 卡,所以我使用分散后端而不是 xrandr。如果您将其称为 ,Autorandr 将使用 分散 作为后端来管理您的监视器autodisper
。不过,在本文的其余部分中,为了保持一致性,我将其称为“autorandr
一致性”。
您可以使用 保存配置文件autorandr --save profile_name
。autorandr
然后,单独运行将为您提供一份配置文件列表,并确定哪个配置文件被检测为当前配置。
例如:
$ autorandr
laptop
syncmaster19 (detected)
您可以告诉它自动加载当前配置的适当配置文件autorandr --change
。该命令与 udev 规则配对以在热插拔时运行它,将执行您所请求的操作。
作为额外的预防措施,我已附加--default laptop
到该命令,如果没有与当前配置匹配的已保存配置文件,这将使其默认为笔记本电脑的显示。所以我用来切换显示的完整命令是:
autorandr --change --default laptop
不幸的是,当我热插拔显示器时,我的机器没有给出任何 udev 输出。我使用的是 NVIDIA 专有驱动程序,所以这并不奇怪。所以我现在将它绑定到 XF68Display 键(Fn-F8),这几乎一样好。
答案2
我正在使用这个简单的(自制)脚本,当 VGA 连接/断开连接时,它会不断轮询 RandR 并在 LVDS1 和 VGA1 之间切换。 (为了HDMI输出,在以下脚本文件中,将所有更改VGA1
为HDMI1
)
这是一个肮脏的解决方案,但它工作得很好。
它是为我的设置定制的:您很可能需要更改 RandR 输出名称 (LVDS1
和VGA1
) 和不像我您可能对 VGA 的 RandR 默认模式感到满意。
#!/bin/bash
# setting up new mode for my VGA
xrandr --newmode "1920x1080" 148.5 1920 2008 2052 2200 1080 1089 1095 1125 +hsync +vsync
xrandr --addmode VGA1 1920x1080
# default monitor is LVDS1
MONITOR=LVDS1
# functions to switch from LVDS1 to VGA and vice versa
function ActivateVGA {
echo "Switching to VGA1"
xrandr --output VGA1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
MONITOR=VGA1
}
function DeactivateVGA {
echo "Switching to LVDS1"
xrandr --output VGA1 --off --output LVDS1 --auto
MONITOR=LVDS1
}
# functions to check if VGA is connected and in use
function VGAActive {
[ $MONITOR = "VGA1" ]
}
function VGAConnected {
! xrandr | grep "^VGA1" | grep disconnected
}
# actual script
while true
do
if ! VGAActive && VGAConnected
then
ActivateVGA
fi
if VGAActive && ! VGAConnected
then
DeactivateVGA
fi
sleep 1s
done
完整步骤:
将上面的脚本 (
homemadeMonitor.sh
) 放入您首选的目录中通过在终端中键入以下命令使 .sh 文件可执行
chmod +x homemadeMonitor.sh
运行.sh文件
./homemadeMonitor.sh
答案3
回答问题的“判断显示器已插入的[一种]方法”部分:
支持仍然有很大差异,但最近的内核支持在发生显示热插拔时生成 udev 事件。对于内核 2.6.38 和 ATI X1400 硬件,我在第一次连接 VGA 显示器时收到一个事件,但在随后断开或重新连接显示器时没有事件。Intel硬件可能有更好的支持。NVIDIA专有驱动目前不支持KMS;我还没有尝试过在 NVIDIA 硬件上寻找热插拔事件,但我怀疑它是否有效。
如果您想尝试 udev,可以尝试以下步骤:
- 更新到最新的内核
- 确保内核模式设置 (KMS) 已启用。如果启用,它应该在您的内核输出中报告。我的说
[drm] radeon kernel modesetting enabled
和[drm] initializing kernel modesetting
- 运行
udevadm monitor --property
并查看当您(断开)连接显示器时是否报告事件
如果您在显示器热插拔上收到 udev 事件,则可以使用 udev 规则触发脚本,例如:
ACTION=="change", SUBSYSTEM=="drm", HOTPLUG=="1", RUN+="/path/to/hotplug.sh"
笔记:这会不是如果您使用带有专有二进制驱动程序的 nVIDIA GPU,则可以工作,因为它不使用 KMS。你会不是获取任何 udev 事件。
答案4
我使用了上面建议的 udev 规则以及一个如下所示的 shell 脚本
#!/bin/sh
dmode="$(cat /sys/class/drm/card0-VGA-1/status)"
export DISPLAY=:0
export XAUTHORITY=/home/yourusername/.Xauthority
if [ "${dmode}" = disconnected ]; then
/usr/bin/xrandr --auto
elif [ "${dmode}" = connected ];then
/usr/bin/xrandr --output VGA1 --auto --right-of LVDS1
else /usr/bin/xrandr --auto
fi
Xauthority 部分和导出一样重要DISPLAY
,您可以使用 echo$DISPLAY
来查看它等于哪个数字。用于xrandr -q
查看您拥有的外部显示器。最后的 else 语句只是为了确保您永远不会在没有显示的情况下陷入困境。