是否有一种工具可以使您:
- 记住每个显示器当前的RandR配置(位置,方向,分辨率等),
- 插入显示器后,是否会自动应用最后一个已知的良好配置,而无需使用applet或xrandr(1)乱搞?
这些配置必须基于每个用户,每个显示器来应用。
如果没有这种工具,我想自己动手,但据我所知,无法告诉您已插入监视器。我是否必须使用xrandr -q进行轮询偶尔找出输出连接或断开,或者有更有效的方法吗?可以将udev调整为做到这一点吗?
是否有一种工具可以使您:
这些配置必须基于每个用户,每个显示器来应用。
如果没有这种工具,我想自己动手,但据我所知,无法告诉您已插入监视器。我是否必须使用xrandr -q进行轮询偶尔找出输出连接或断开,或者有更有效的方法吗?可以将udev调整为做到这一点吗?
Answers:
我正在使用这个简单的(自制的)脚本,该脚本不断轮询RandR,并在VGA连接/断开时在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
完整步骤:
Ctrl+Alt+t
导航到一个合适的位置以制作和存储自动切换Shell脚本。例
cd ./Desktop/
使用所需的文本编辑器创建和编辑.sh文件(在这里,我使用了pluma。您可以尝试使用nano,vim等)。为方便起见命名。例
sudo pluma homemadeMonitor.sh
编辑文件并复制粘贴上述脚本中的所有内容(带有#!/ bin / bash的脚本)
通过在终端中键入以下命令,使.sh文件可执行。
sudo chmod +x homemadeMonitor.sh
运行.sh文件
./homemadeMonitor.sh
回答问题的“ [a]告知监视器已插入”的方式:
支持仍然相差很多,但是在最近的内核中,有些支持可以在发生显示热插拔时生成udev事件。使用内核2.6.38和ATI X1400硬件,我第一次连接VGA显示器时会收到一个事件,但是在随后的显示器断开或重新连接时没有任何事件。英特尔硬件可能有更好的支持。NVIDIA专有驱动程序当前不支持KMS。我没有尝试在NVIDIA硬件上寻找热插拔事件,但是我怀疑它是否可以工作。
如果要尝试使用udev,可以尝试以下步骤:
[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事件。
对于可以按用户和按显示器存储监视器配置文件的工具,autorandr会做到这一点。https://github.com/wertarbyte/autorandr。
我的笔记本电脑配有NVIDIA卡,因此我使用分散后端而不是xrandr:http ://willem.engen.nl/projects/disper/ 。如果您将Autorandr称为,则将使用disper作为后端来管理您的监视器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),几乎一样。
udev
autorandr
:github.com/phillipberndt/autorandr
我使用了上面建议的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部分和export一样重要DISPLAY
,您可以使用echo $DISPLAY
来查看它等于哪个数字。使用xrandr -q
就看你有外部显示器。最后的else声明只是为了确保您在不显示的情况下也不会卡住。
一个小程序可以等待X服务器通知已更改的监视器配置,然后执行给定命令(例如autorandr
,另一个答案中提到的命令),网址为:https : //bitbucket.org/portix/srandrd/overview
这似乎是使用的更清洁的解决方案udev
(您必须担心要找到合适的X服务器等)。
如果必须让它在插入时自动检测显示,则似乎最干净的解决方案是添加UDEV规则以运行包含xrandr命令的脚本。这是一个用户解决方案1的示例:
使用udevadm
此步骤监视(输出)UDEV事件对于每个用户来说都是最重要的。运行udevadm monitor --environment --udev
。然后连接您的HDMI电缆。
UDEV规则
根据上述命令的输出,用户在处创建了该UDEV规则/etc/udev/rules.d/95-monitor-hotplug.rules
。
KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/dan/.Xauthority", RUN+="/usr/local/bin/hotplug_monitor.sh"
注意使用的环境变量,因此xrandr将在用户配置文件下运行。
xrandr脚本hotplug_monitor.sh
您可能需要调整xrandr选项以适合您的需求。
#! /usr/bin/bash
export DISPLAY=:0
export XAUTHORITY=/home/dan/.Xauthority
function connect(){
xrandr --output HDMI1 --right-of LVDS1 --preferred --primary --output LVDS1 --preferred
}
function disconnect(){
xrandr --output HDMI1 --off
}
xrandr | grep "HDMI1 connected" &> /dev/null && connect || disconnect
对于出于某种原因而不想采用热插拔路由的用户,仍然可以使用inotifywait不在脚本中进行轮询:
#!/ bin / bash SCREEN_LEFT = DP2 SCREEN_RIGHT = eDP1 START_DELAY = 5 renice +19 $$> / dev / null 睡眠$ START_DELAY OLD_DUAL =“ dummy” 而[1]; 做 DUAL = $(cat / sys / class / drm / card0-DP-2 / status) 如果[“ $ OLD_DUAL”!=“” $ DUAL“]; 然后 如果[“ $ DUAL” ==“ connected”];然后 回显“双显示器设置” xrandr-输出$ SCREEN_LEFT-自动-正常旋转--pos 0x0-输出$ SCREEN_RIGHT-自动-正常旋转-下面$ SCREEN_LEFT 其他 回声“单显示器设置” xrandr-汽车 科幻 OLD_DUAL =“ $ DUAL” 科幻 inotifywait -q -e关闭/ sys / class / drm / card0-DP-2 / status> / dev / null 做完了
使用xrandr进行轮询会给我的全新笔记本电脑带来严重的可用性问题(鼠标会定期停顿)。
当使用peoro的解决方案时,我从xrandr获得了一些额外的输出,因此我在grep中使用了-c选项来计算匹配数。我将其调整为适用于HDMI,还添加了音频开关:
#!/bin/bash
# adapted from http://unix.stackexchange.com/questions/4489/
# default monitor is LVDS1
MONITOR=LVDS1
# functions to switch from LVDS1 to HDMI1
function ActivateHDMI {
xrandr --output HDMI1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
pactl set-card-profile 0 output:hdmi-stereo-extra1
MONITOR=HDMI1
}
function DeactivateHDMI {
xrandr --output HDMI1 --off --output LVDS1 --auto
pactl set-card-profile 0 output:analog-stereo
MONITOR=LVDS1
}
# functions to check if HDMI is connected and in use
function HDMIActive {
[ $MONITOR = "HDMI1" ]
}
function HDMIConnected {
[[ `xrandr | grep "^HDMI1" | grep -c disconnected` -eq 0 ]]
}
# actual script
while true
do
if ! HDMIActive && HDMIConnected
then
ActivateHDMI
fi
if HDMIActive && ! HDMIConnected
then
DeactivateHDMI
fi
sleep 1s
done
我想看这个问题的人不是那些想使用GNOME的人,而那些使用GNOME的人不必看这个问题,而是出于完整性考虑:
GNOME内置了此功能。如果您通过gnome-control-center更改设置,则gnome-settings-daemon会记住它(在中.config/monitors.xml
),并在插入或拔出监视器时自动应用它。
遗憾的是,monitors.xml文件中的配置没有很好的文档说明。在这里查看问题。gnome显示工具也无法设置摇摄,按监视器缩放以及不进行缩小。由于许多人同时使用HiDPI笔记本电脑屏幕和常规DPI屏幕,因此这些工具不足以得到可行的解决方案。
我已经将其视为Wayland的路线图项目,因此,当它最终出现时,我们可能会看到针对所提及问题的解决方案。直到在Gnome上,我在延迟手动设置xrandr之后才运行启动脚本。
例如,为了简化Xfce,请安装“ arandr”,该软件包应在您的发行版软件包中可用。使用“ arandr”配置显示,然后将其另存为“ displayLayout”。Arandr应该为您添加“ .sh”扩展名,以便可以如上面iyrin提到的脚本“ hotplug_monitor.sh”中所写的那样直接在“ function connect()”中使用,例如:
function connect(){
/path/to/displayLayout.sh
}
要使用断开连接机制,请在脚本顶部的“#!/ bin / bash”下方添加,如下所示:
#!/bin/bash
#
PLUGGED_EXTERNAL=`xrandr | awk /"connected [0-9]"/'{print $1}'`
xrandr将检测显示并将输出传递给awk,它将根据正则表达式“ connected”对其进行过滤,后跟一个数字,这实际上是我们想要的。我认为没有必要在正则表达式中匹配精确的分辨率,因为主显示被报告为“已连接的主”,后跟数字即分辨率。然后awk“ print $ 1”将仅打印第一列,在这种情况下,它是外部监视器的名称,并将其存储在PLUGGED_EXTERNAL变量中。接下来,可以像这样使用脚本$ PLUGGED_EXTERNAL中的固定显示名称“ HDMI1”代替:
function disconnect(){
xrandr --output $PLUGGED_EXTERNAL --off
}
xrandr | grep "$PLUGGED_EXTERNAL connected" &> /dev/null && connect || disconnect
编辑我的答案以使其设置更简单。
安装autorandr以自动在xrandr中进行屏幕布局,从https://github.com/nalipaz/autorandr/releases获取最新的.deb 并运行:
dpkg -i [file]
使用存储的屏幕布局设置自动运行
autorandr --save [docked|mobile|home|etc]
举例来说,在没有插入任何显示器的笔记本电脑上,我按照自己的方式进行了设置,然后运行:
autorandr --save mobile
然后插入我的hdmi并重新配置arandr,然后运行:
autorandr --save docked
设置完每个布局后,您可以运行(用以前喜欢的名称替换“移动设备”,我使用移动设备):
autorandr --default mobile
现在已经完成了autorandr的设置,您可以通过安装一个软件包来自动化该过程,该软件包将轮询连接的显示器并autorandr --change
在检测到后运行。是的,我了解udev,可以设置它是否适合您,但在我的测试中,udev不适用于我的hdmi。每20个插拔一次它只能工作1个,有时甚至完全停止了。
从此处下载最新的.deb:https://github.com/nalipaz/poll-xrandr/releases/,然后使用
dpkg -i [file]
很可能有必要在完成时运行更多任务autorandr --change
,autorandr允许将这些命令插入到名为〜/ .autorandr / postswitch的文件中。进行如下操作:
cd ~/.autorandr/ && touch postswitch && chmod +x postswitch
现在,编辑后切换文件,使其具有类似于以下内容的内容:
#!/bin/bash
if pidof conky > /dev/null 2>&1; then
killall conky
fi
(sleep 2s && xrandr-adjust-brightness restore -q) &
(sleep 2s && nitrogen --restore) &
(sleep 3s && conky -q) &
另外,您可能希望将autorandr和poll-xrandr添加到您的初创公司,类似于以下两个命令:
autorandr --change &
poll-xrandr &
拔下电源插头或插入监视器,然后观看魔术!
udevadm monitor --property
从终端运行并插入监视器。使用我的卡,插入电源时会看到一个事件。您可以在udev中使用+ RUN规则和一些bash脚本来获取所需的内容。但是,我不确定您如何使用udev在每个用户的基础上实现此功能。