是否有任何当我插上或缩小外部监视器到我的笔记本电脑的DisplayPort的所触发的事件?ACPID和UDEV完全不响应。
我在英特尔芯片上使用板载图形。这是已经有几年历史的类似讨论了。
我不想使用轮询,但是我需要一些配置来自动设置显示设置,具体取决于显示器是否已连接。
是否有任何当我插上或缩小外部监视器到我的笔记本电脑的DisplayPort的所触发的事件?ACPID和UDEV完全不响应。
我在英特尔芯片上使用板载图形。这是已经有几年历史的类似讨论了。
我不想使用轮询,但是我需要一些配置来自动设置显示设置,具体取决于显示器是否已连接。
Answers:
注意: 这已在装有i915驱动图形卡的笔记本电脑上进行了测试。
注意:插入新屏幕时,没有事件发送到主机,即使在我上次编辑后,该事件也保持不变。因此,唯一的方法是使用轮询。试图使它们尽可能高效...
最后,有一个更好的解决方案(通过ACPI):
仍然没有任何事件,但是ACPI似乎比xrandr
查询更有效率。(注意:这需要加载ACPI内核模块,但不需要root特权)。
我的最终解决方案(使用bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
现在进行测试:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
它已插入,所以现在我将其拔出:
$ if isVgaConnected; then echo yes; else echo no; fi
no
注意: ${1:+*-1+1}
允许使用布尔值参数:如果存在某些内容,答案将被反转:( crtState >> 4 ) * -1 + 1
。
最后的脚本:
#!/bin/bash
export crtProcEntry=/proc/acpi/video/VID/CRT0/state
isVgaConnected() {
local crtState
read -a < $crtProcEntry crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
delay=.1
unset switch
isVgaConnected || switch=not
while :;do
while isVgaConnected $switch;do
sleep $delay
done
if [ "$switch" ];then
unset switch
echo VGA IS connected
# doing something while VGA is connected
else
switch=not
echo VGA is NOT connected.
# doing something else, maybe.
fi
done
警告: Bash脚本比轻xrandr
,但不重要,延迟小于0.02秒,Bash脚本将到达资源消耗者进程(top
)的顶部!
尽管这需要0.001秒的时间:
$ time read -a </proc/stat crtStat
这需要约0.030秒:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
好大!因此,根据需要,delay
可以在0.5
和之间合理设置2
。
我终于找到了一些东西,使用这个:
重要免责声明:/proc
和/sys
条目一起玩可能会破坏您的系统!!!因此,请勿在生产系统上尝试以下操作。
mapfile watchFileList < <(
find /sys /proc -type f 2>/dev/null |
grep -i acpi\\\|i91
)
prompt=("/" "|" '\' '-');
l=0
while :; do
mapfile watchStat < <(
grep -H . ${watchFileList[@]} 2>/dev/null
)
for ((i=0;i<=${#watchStat[@]};i++)); do
[ "${watchStat[i]}" == "${oldStat[i]}" ] || echo ${watchStat[i]}
done
oldStat=("${watchStat[@]}")
sleep .5
printf "\r%s\r" ${prompt[l++]}
[ $l -eq 4 ]&&l=0
done
...在清理了不需要的条目后:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
我已经能够阅读以下内容:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
当我插入,拔出并重新插入显示器电缆时。
原始答案当查询配置时(运行system/preferences/monitor
或xrandr
),图形卡会执行scan的一种类型,因此运行会xrandr -q
为您提供信息,但您必须轮询状态。
我已经扫描了所有通过/proc
&进行搜索的日志(内核,守护程序,X等)/sys
,显然没有任何东西可以满足您的要求。
我也尝试过这个:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
毕竟,如果您System/Preferences/Monitor
在未插入新屏幕或未插入新屏幕的情况下运行,该工具将简单(正常)显示。但是,如果您以前插入或拔出了屏幕,有时您会运行此工具,并且您会看到桌面进行某种类型的重置或刷新(与运行相同xrandr
)。
这似乎可以确认该工具xrandr
从运行之时开始就通过定期轮询状态来请求(或以相同的方式工作)。
您可以尝试一下:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
这将显示连接的屏幕数(显示屏),持续10秒钟。
在此过程中,请插入和/或拔下屏幕/显示器,然后看看会发生什么。因此,您可以创建一些Bash测试功能:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
可用于以下方面:
$ if isVgaConnected; then echo yes; fi
但是请注意,xrandr
大约需要0.140到0.200秒钟,而插头上没有任何变化,而在刚插入或拔出某些东西之前,则最多需要0.700秒钟(注意:这似乎不是资源消耗者)。
为了确保我没有教给别人一些不正确的东西,我在网上和文档中进行了搜索,但是没有找到有关DBus和Screens的任何信息。
最后,我在两个不同的窗口中运行dbus-monitor --system
(我也一直在使用选项)和编写的小脚本:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
...并多次插入电源,而不是拔下显示器电源。所以现在我可以说:
xrandr -q
只能运行运行来了解是否已插入监视器。但是要小心,因为似乎没有其他方法。举例来说,xrandr
似乎分享这个信息,所以我的GNOME桌面将切换xinerama
自动... 当我跑xrandr
。
以下行出现在 udevadm monitor
KERNEL[46578.184280] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV [46578.195887] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
将显示器连接到VGA接口时。因此,可能有一种方法可以解决这个问题。
对于出于某种原因而不想采用热插拔路由的用户,仍然可以使用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 做完了
最好从您的.xsessionrc中调用它,不要忘记结尾&。使用xrandr进行轮询会给我的全新笔记本电脑带来严重的可用性问题(鼠标会定期停顿)。
/proc
而且inotifywait -q -e close /sys/class/drm/card0-DP-2/status
在断开系统上的DP-2的连接之后确实
显然应该有东西!:) / sys文件系统告诉用户空间可用的硬件,因此用户空间工具(例如udev或mdev)可以使用代表当前可用硬件的设备节点动态填充“ / dev”目录。Linux提供了两个热插拔接口:/ sbin / hotplug和netlink。
以下文件中有一个小型C演示。 http://www.kernel.org/doc/pending/hotplug.txt
今天,大多数情况下,Linux上的系统/应用程序软件都使用了一些ipc技术来相互通信。D-Bus现在主要用于GNOME应用程序,并且可能会有所帮助。
D-BUS可以促进通过系统发送事件或信号,从而允许系统中的不同组件进行通信并最终实现更好的集成。例如,蓝牙守护进程可以发送您的音乐播放器可以拦截的来电信号,使音量静音直到通话结束。
维基:
D-Bus提供系统守护程序(用于“添加新硬件设备”或“打印机队列已更改”之类的事件)和每个用户登录会话守护程序(用于满足用户应用程序之间的一般进程间通信需求)。
甚至还有一个Python库,并且ubuntu最近使用了称为“ zeitgeist ”的功能。
以图形方式可以看到该显示器是否被识别Monitor
,我知道您可以在Ubuntu(Ubuntu),Fedora和其他(或类似位置)上找到该显示器。
系统/首选项/监视器
您可以打开/关闭所需的任何显示器,或者同时使用两个显示器或独立显示器中的重复图像