私のラップトップのDisplayPortに外部モニターをプラグインまたはアウトするときにトリガーされるイベントはありますか?ACPIDとUDEVはまったく反応しません。
Intelチップのオンボードグラフィックスを使用しています。ここでは、すでに数年古い同様の議論があります。
ポーリングを使用したくありませんが、ディスプレイが接続されているかどうかに応じてディスプレイ設定を自動的に設定する構成が必要です。
私のラップトップのDisplayPortに外部モニターをプラグインまたはアウトするときにトリガーされるイベントはありますか?ACPIDとUDEVはまったく反応しません。
Intelチップのオンボードグラフィックスを使用しています。ここでは、すでに数年古い同様の議論があります。
ポーリングを使用したくありませんが、ディスプレイが接続されているかどうかに応じてディスプレイ設定を自動的に設定する構成が必要です。
回答:
注: これは、i915駆動のグラフィックスカードを搭載したラップトップでテストされました。
注:新しい画面がプラグインされると、イベントはホストに送信されません。これは、最後の編集後もそのままでした。したがって、唯一の方法はポーリングを使用することです。それらを可能な限り効率的にしようとしています...
最後に、より良い解決策が1つあります(ACPIを使用)。
イベントはまだありませんが、ACPIはxrandr
問い合わせるよりも効率的です。(注:これには ACPIカーネルモジュールをロードする必要がありますが、ルート権限は必要ありません)。
私の最終的な解決策(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秒未満の遅延で、リソースを食べるプロセスの最上位に移動します(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
すると情報が提供されますが、ステータスをポーリングする必要があります。
すべてのログ(カーネル、デーモン、Xなど)をスキャンし、/proc
&を検索しました/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秒かかります(注:リソースを食べる人ではないようです)。
間違ったことを教えないようにするために、Webとドキュメントを検索しましたが、DBusとScreensについては何も見つかりませんでした。
最後に、2つの異なるウィンドウで実行しました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コネクタにモニターを接続する場合。したがって、これを理解する方法があるかもしれません。
なんらかの理由でhotplugルートを使用したくない場合は、inotifywaitを使用してスクリプト内でポーリングしないことも可能です。
#!/ bin / bash SCREEN_LEFT = DP2 SCREEN_RIGHT = eDP1 START_DELAY = 5 renice +19 $$> / dev / null $ START_DELAYスリープ OLD_DUAL = "ダミー" while [1]; 行う DUAL = $(cat / sys / class / drm / card0-DP-2 / status) if ["$ OLD_DUAL"!= "$ DUAL"]; それから if ["$ DUAL" == "connected"]; それから echo「デュアルモニターのセットアップ」 xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT 他に echo「シングルモニターのセットアップ」 xrandr --auto fi OLD_DUAL = "$ DUAL" fi inotifywait -q -e close / 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の2つのホットプラグインターフェイスを提供します。
次のファイルに小さなCデモがあります。 http://www.kernel.org/doc/pending/hotplug.txt
現在、Linux上のシステム/アプリケーションソフトウェアのほとんどは、相互に通信するためにいくつかのipc技術を使用しています。D-Busは現在GNOMEアプリケーションで主に使用されており、役立つ可能性があります。
D-BUSを使用すると、システムを介したイベントまたは信号の送信が容易になり、システム内のさまざまなコンポーネントが通信し、最終的にはより統合しやすくなります。たとえば、Bluetoothデーモンは、音楽プレーヤーが傍受できる着信コール信号を送信し、通話が終了するまで音量をミュートすることができます。
wiki:
D-Busは、システムデーモン(「新しいハードウェアデバイスの追加」や「プリンターキューの変更」など)とユーザーごとのログインセッションデーモン(ユーザーアプリケーション間の一般的なプロセス間通信のニーズ)の両方を提供します。
このためのPythonライブラリもあり、ubuntuは最近「zeitgeist」と呼ばれるこの機能を使用しました。
グラフィカルに、モニターがで認識されるかどうかを確認Monitor
できます。これは、Ubuntu、Fedora、およびその他(このような場所)で見つけることができることを知っています。
システム/設定/モニター
また、必要なモニターのオン/オフを切り替えたり、両方を同時に使用したり、両方のモニターまたは独立したモニターで画像を複製したりできます。