插入外接显示器时自动应用RandR配置的工具


53

是否有一种工具可以使您:

  • 记住每个显示器当前的RandR配置(位置,方向,分辨率等),
  • 插入显示器后,是否会自动应用最后一个已知的良好配置,而无需使用applet或xrandr(1)乱搞?

这些配置必须基于每个用户,每个显示器来应用。

如果没有这种工具,我想自己动手,但据我所知,无法告诉您已插入监视器。我是否必须使用xrandr -q进行轮询偶尔找出输出连接或断开,或者有更有效的方法吗?可以将udev调整为做到这一点吗?


您确定无法确定您的卡已插入监视器吗?尝试udevadm monitor --property从终端运行并插入监视器。使用我的卡,插入电源时会看到一个事件。您可以在udev中使用+ RUN规则和一些bash脚本来获取所需的内容。但是,我不确定您如何使用udev在每个用户的基础上实现此功能。
史蒂文D

@Steven:您的评论应该是答案。这不是一个完整的答案,但确实取得了重大进展。如果udev确实看到了硬件事件,则应通知hal,后者发送一个dbus事件,用户代码可以看到该事件。
吉尔(Gilles)“所以,别再邪恶了”

Answers:


19

我正在使用这个简单的(自制的)脚本,该脚本不断轮询RandR,并在VGA连接/断开时在LVDS1和VGA1之间切换。(对于HDMI输出,在以下脚本文件中,将所有更改VGA1HDMI1

这是一个肮脏的解决方案,但效果很好。

它是为我的设置定制的:您很可能需要更改RandR输出名称(LVDS1VGA1),而与我不同的是,您可以使用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

完整步骤:

  1. 通过按下打开终端 Ctrl+Alt+t
  2. 导航到一个合适的位置以制作和存储自动切换Shell脚本。例

    cd ./Desktop/

  3. 使用所需的文本编辑器创建和编辑.sh文件(在这里,我使用了pluma。您可以尝试使用nano,vim等)。为方便起见命名。例

    sudo pluma homemadeMonitor.sh

  4. 编辑文件并复制粘贴上述脚本中的所有内容(带有#!/ bin / bash的脚本)

  5. 通过在终端中键入以下命令,使.sh文件可执行。

    sudo chmod +x homemadeMonitor.sh

  6. 运行.sh文件

    ./homemadeMonitor.sh


好脚本!谢谢,我需要这样的东西。我只是复制了它并将其设置为自动运行。谢谢!
Linuxios 2012年

21

回答问题的“ [a]告知监视器已插入”的方式:

支持仍然相差很多,但是在最近的内核中,有些支持可以在发生显示热插拔时生成udev事件。使用内核2.6.38和ATI X1400硬件,我第一次连接VGA显示器时会收到一个事件,但是在随后的显示器断开或重新连接时没有任何事件。英特尔硬件可能有更好的支持。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事件。


19

对于可以按用户和按显示器存储监视器配置文件的工具,autorandr会做到这一点。https://github.com/wertarbyte/autorandr

我的笔记本电脑配有NVIDIA卡,因此我使用分散后端而不是xrandr:http ://willem.engen.nl/projects/disper/ 。如果您将Autorandr称为,则将使用disper作为后端来管理您的监视器autodisper。不过,对于本文的其余部分,我将其称为autorandr一致性。

您可以使用保存配置文件autorandr --save profile_nameautorandr单独运行将为您提供配置文件列表,并确定检测到哪个配置文件为当前配置。

例如:

$ autorandr
laptop
syncmaster19 (detected)

您可以使用告诉它自动为当前配置加载适当的配置文件autorandr --change。该命令与udev规则配对以在热插拔时运行该命令,即可完成您所请求的操作。

作为附加的预防措施,我附加--default laptop了该命令,如果没有保存的配置文件与当前配置匹配,它将默认显示在笔记本电脑的显示屏上。因此,我用来切换显示的完整命令是:

autorandr --change --default laptop

不幸的是,当我热插显示器时,我的机器没有任何udev输出。我正在使用NVIDIA专有驱动程序,所以这并不奇怪。因此,现在我将其绑定到XF68Display键(Fn-F8),几乎一样。


1
autorandr浪费时间,记录不好,监视器随机闪烁,没有安装/卸载说明。可以使用udev
Leo Gallucci

5
以防万一,有一个很好的维护在Python中重写的叉子autorandrgithub.com/phillipberndt/autorandr
Olegs Jeremejevs

7

我使用了上面建议的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声明只是为了确保您在不显示的情况下也不会卡住。



5

如果必须让它在插入时自动检测显示,则似乎最干净的解决方案是添加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

3

对于出于某种原因而不想采用热插拔路由的用户,仍然可以使用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进行轮询会给我的全新笔记本电脑带来严重的可用性问题(鼠标会定期停顿)。


1

当使用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

1

我想看这个问题的人不是那些想使用GNOME的人,而那些使用GNOME的人不必看这个问题,而是出于完整性考虑:

GNOME内置了此功能。如果您通过gnome-control-center更改设置,则gnome-settings-daemon会记住它(在中.config/monitors.xml),并在插入或拔出监视器时自动应用它。

遗憾的是,monitors.xml文件中的配置没有很好的文档说明。在这里查看问题。gnome显示工具也无法设置摇摄,按监视器缩放以及不进行缩小。由于许多人同时使用HiDPI笔记本电脑屏幕和常规DPI屏幕,因此这些工具不足以得到可行的解决方案。

我已经将其视为Wayland的路线图项目,因此,当它最终出现时,我们可能会看到针对所提及问题的解决方案。直到在Gnome上,我在延迟手动设置xrandr之后才运行启动脚本。


1

例如,为了简化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

0

编辑我的答案以使其设置更简单。

安装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 &

拔下电源插头或插入监视器,然后观看魔术!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.