插入显示器时运行 X 程序

插入显示器时运行 X 程序

我的电脑有一个奇怪的错误。当我关闭显示器并重新打开时,屏幕保持空白。仅当在 X 下登录时才会发生这种情况(但不会在 Gdm 屏幕上)。我找到了一种让屏幕亮起的方法:

xset dpms force off
xset dpms force on

如何在显示器打开时自动运行这些命令?

显示器通过 DisplayPort 连接并报告 EDID 信息。操作系统是Ubuntu 18.04。

基于轮询的解决方案是不可接受的。打开监视器应该无需等待即可做出反应,因此轮询需要非常短的间隔,但这是一个不频繁的操作,因此不能保证 CPU 保持足够热以以亚秒间隔运行任务。我正在寻找一个扳机当插入监视器时,在 X 会话中运行。

答案1

我有一个使用 udev 的解决方案。它并不强大,但对我来说已经足够好了。

创建一个文件/etc/udev/rules.d/99-monitor.rules(确切的文件名并不重要,只要它只包含字母、数字_-扩展名即可.rules):

KERNEL=="card0", SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/sbin/monitor-change.udev.sh"

创建一个文件/usr/local/sbin/monitor-change.udev.sh并使其可执行:

#!/bin/bash
set -e

start_logging () {
  exec >/var/log/monitor-change.log 2>&1
  echo
  set -x
  date
}

awaken_monitor () {
  # Hack: the monitor stays blank, but forcing it off then on in software
  # somehow turns it on.
  xset dpms force off
  xset dpms force on
}

detect_xorg () {
  tty=/dev/tty$(fgconsole)
  # Find Xorg running on the foreground console
  pids=$(fuser "$tty" 2>/dev/null)
  auth_regexp=' -auth ([^ ]*)'
  for pid in $pids; do
    args=$(ps -o args= -p $pid)
    if [[ "$args" = /usr/lib/xorg/Xorg* ]] &&
       [[ "$args" =~ $auth_regexp ]]
    then 
      # Hard-code DISPLAY=:0 because it's hard to detect
      export DISPLAY=":0" XAUTHORITY="${BASH_REMATCH[1]}"
      return 0
    fi
  done
  return 1
}

#start_logging
detect_xorg
awaken_monitor

它作用于任何显示器变化。这包括关闭和打开显示器,并且不区分多个显示器,但是这台特定的机器只有一个显示器,所以对我来说已经足够了。

udev 脚本检测 X 会话(在此 Ubuntu 18.04 默认设置中,通常在 tty2 上运行)。这台机器上只有一个用户,所以我让事情变得简单。请注意,X 调用行假定使用 Gdm 方式调用 X 服务器;如果您不使用 Gdm,您可能需要更改此部分。

我更喜欢基于 dbus 的解决方案,但我不知道要对什么事件做出反应。

相关内容