This was tested on a laptop with a i915 drived graphic card.
Definitively, in my config/install, there are not. :-(
When a new screen is plugged, no event is sent to the host! (This stay true after my last edit!)
So the only way is to use pooling... Trying to make them lighter as possible...
Last Edit : Finaly there is one better solution (through acpi):
At all, there are still no event! But acpi seem lighter than xrandr to inquire. (Nota: This require acpi modules loaded! But don't require root privileges)
My final purpose (using 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
(I'ts plugged! well, I unplugg them:)
if isVgaConnected ;then echo yes ;else echo no ;fi
no
Nota: ${1:+*-1+1} permit a boolean argument: If something is present, answer would be inversed: ( crtState >> 4 ) * -1 + 1.
and finalized:
#!/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
Warning, lighter than xrandr, but not unimportant with a delay smaller than 0.02 seconds, the bash script will go to the top of resource eaters process (top)! While time read -a </proc/stat crtStat cost ~0.001 sec, read -a < /proc/acpi/video/VID/CRT0/state crtState require ~0.030 sec! This is big!! So depending on what you need. delay could be reasonably set between 0.5 and 2
Hope this help!
Edit 1
I've finaly found something, using this:
(Important disclaimer: Playing with /proc and /sys entries could break your system!!! So don't try the following on production system!!! At all don't blame me for anything happening to your material, your health, your wife or your dog!)
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
... after some cleaning of unwanted entrys:
for ((i=0;i<=${#watchFileList[@]};i++));do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
I've been able to read this:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
When I plug, Unplug, and re-plug monitor cable.
Old post
When the config is inquired (running system/preferences/monitor or xrandr), graphic card do a kind of scan before or all.
So running xrandr -q give you the info, but you have to poll the status.
I'v scanned all logs, (kernel, daemon, X and so) searched through /proc and /sys, clearly nothing seem exist to satisfy your request.
I've tried this too:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
At all, I you run System/Preferences/Monitor while no new screen have just been plugged, nor unplugged, the tool will appear simply (normaly). But if you've plugged or unplugged a screen before, at time you run this tool you will see your desktop make a kind of reset or refresh (same if you run xrandr).
This seem confirm that this tool ask for xrandr (or work in the same manner) by pooling status periodicaly starting at time he is run.
You could try yourself:
for ((i=10;i--;));do xrandr -q | grep ' connected' | wc -l ;sleep 1;done
1
1
1
2
2
2
1
1
1
1
This will display how much screen are connect, for 10 seconds.
While this run, plug and/or unplug your screen and look what's happen.
So you could create a litle bash test function:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
useable in:
if isVgaConnected ;then echo yes;fi
But care, xrandr take about 0,140 sec to 0,200 sec while no change happens on plugs and upto 0,700 seconds whenever something was plugged or unplugged just before (Nota: It seem no to be a resource eater).
Edit: For ensuring I'm not teaching something false, I've searched around web and docs, but did'nt find anything about DBus and Screens.
Finaly, I've run in two differents windows dbus-monitor --system (I've been played with options too;) and the little script I wrote:
for ((i=1000;i--;));do isVgaConnected && echo yes || echo no;sleep .5;done
... and again plug, than unplug monitor, many times. So now I could say:
- In this configuration, using i915 driver, there is no other way than running
xrandr -q to know if a monitor is plugged or no.
But care, because as there is no other ways, xrandr seem share this info, so my gnome desktop swith to xinerama automaticaly... when I run xrandr
Some docs