CATATAN: Ini diuji pada laptop dengan kartu grafis yang digerakkan i915.
Latar Belakang
CATATAN: Ketika layar baru dicolokkan, tidak ada acara dikirim ke tuan rumah, ini tetap benar bahkan setelah edit terakhir saya. Jadi satu-satunya cara adalah menggunakan polling. Mencoba menjadikannya seefisien mungkin ...
EDIT # 3
Akhirnya ada satu solusi yang lebih baik (melalui ACPI):
Masih belum ada acara, tetapi ACPI tampaknya lebih efisien daripada xrandr
bertanya. (Catatan: Ini membutuhkan modul kernel ACPI yang dimuat, tetapi tidak memerlukan hak akses root).
Solusi terakhir saya (menggunakan bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Sekarang ujian:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Itu sudah terhubung, jadi sekarang saya mencabutnya:
$ if isVgaConnected; then echo yes; else echo no; fi
no
CATATAN: ${1:+*-1+1}
mengizinkan boolean argumen: Jika ada sesuatu yang hadir , jawabannya akan terbalik: ( crtState >> 4 ) * -1 + 1
.
dan skrip terakhir:
#!/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
PERINGATAN: lebih ringan dari xrandr
, tetapi tidak penting dengan penundaan lebih kecil dari 0,02 detik, skrip Bash akan pergi ke bagian atas proses pemakan sumber daya ( top
)!
Sementara ini biaya ~ 0,001 detik:
$ time read -a </proc/stat crtStat
Ini membutuhkan ~ 0,030 detik:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
Ini besar! Jadi tergantung pada apa yang Anda butuhkan, delay
bisa diatur antara 0.5
dan 2
.
EDIT # 2
Saya akhirnya menemukan sesuatu, menggunakan ini:
Penafian penting: Bermain dengan /proc
dan /sys
entri dapat merusak sistem Anda !!! Jadi jangan coba yang berikut ini pada sistem produksi.
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
... setelah beberapa pembersihan entri yang tidak diinginkan:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
Saya sudah bisa membaca ini:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Saat saya mencolokkan, cabut, dan pasang kembali kabel monitor.
Jawaban Asli
Ketika konfigurasi diminta (berjalan system/preferences/monitor
atau xrandr
), kartu grafis melakukan jenis pemindaian , jadi menjalankan xrandr -q
memberi Anda info, tetapi Anda harus polling status.
Saya telah memindai semua log, (kernel, daemon, X, dan sebagainya) mencari melalui /proc
& /sys
, dan tampaknya tidak ada yang memenuhi permintaan Anda.
Saya sudah mencoba ini juga:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
Setelah semua itu, jika Anda menjalankan System/Preferences/Monitor
sementara tidak ada layar baru yang baru saja dicolokkan, atau dicabut, alat akan muncul secara sederhana (normal). Tetapi jika Anda sudah memasang atau mencabut layar sebelumnya, kadang-kadang Anda akan menjalankan alat ini dan Anda akan melihat desktop Anda membuat jenis reset atau refresh (sama jika Anda menjalankan xrandr
).
Ini sepertinya mengkonfirmasi bahwa alat ini meminta xrandr
(atau bekerja dengan cara yang sama) dengan memungut status secara berkala, mulai saat dijalankan.
Anda bisa mencoba sendiri:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Ini akan menampilkan berapa banyak layar (display) yang terhubung, selama 10 detik.
Saat ini berjalan, pasang dan / atau cabut layar / monitor Anda dan lihat apa yang terjadi. Jadi Anda bisa membuat fungsi tes Bash kecil:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
yang bisa digunakan seperti pada:
$ if isVgaConnected; then echo yes; fi
Tapi hati-hati, xrandr
butuh sekitar 0,140 detik hingga 0,200 detik sementara tidak ada perubahan yang terjadi pada colokan dan hingga 0,700 detik setiap kali sesuatu dicolokkan atau dicabut tepat sebelumnya ( CATATAN: Tampaknya bukan menjadi pemakan sumber daya).
EDIT # 1
Untuk memastikan saya tidak mengajarkan sesuatu yang salah, saya telah mencari di Web dan dokumen, tetapi tidak menemukan apa pun tentang DBus dan Layar .
Akhirnya, saya telah menjalankan di dua jendela yang berbeda dbus-monitor --system
(saya telah bermain dengan opsi juga) dan skrip kecil yang saya tulis:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... dan lagi terpasang, daripada mencabut monitor, berkali-kali. Jadi sekarang saya bisa mengatakan:
- Dalam konfigurasi ini, menggunakan driver i915 , tidak ada cara lain selain berlari
xrandr -q
untuk mengetahui apakah monitor dicolokkan atau tidak.
Tetapi berhati-hatilah, karena tampaknya tidak ada cara lain. Misalnya, xrandr
sepertinya membagikan informasi ini, sehingga desktop GNOME saya akan beralih ke xinerama
secara otomatis ... ketika saya berlarixrandr
.
Beberapa dokumen