web-dev-qa-db-ja.com

外部ディスプレイが接続されているときにRandR構成を自動的に適用するためのツール

次のことを可能にするツールがあります:

  • モニターごとに現在のRandR構成(位置、方向、解像度など)を記憶します。
  • アプレットやxrandr(1)をいじる必要なしに、ディスプレイが接続されるとすぐに、最後の既知の適切な構成を自動的に適用しますか?

構成は、ユーザーごと、ディスプレイごとに適用する必要があります。

実際にそのようなツールがない場合は、自分で1つにまとめたいと思いますが、見る限りでは、モニターが接続されていることを確認する方法はありません。xrandr-qでポーリングする必要がありますか?出力が接続または切断されたことを時々把握するために、またはそれを行うためのより効率的な方法はありますか? udevはそれを行うように調整できますか?

58

VGAが接続/切断されたときにRandRをポーリングし続け、LVDS1とVGA1を切り替えるこのシンプルな(自家製の)スクリプトを使用しています。 ([〜#〜] hdmi [〜#〜]出力の場合、次のスクリプトファイルで、すべてのVGA1HDMI1

汚いソリューションですが、問題なく機能しています。

これは私のセットアップ用にカスタマイズされています。ほとんどの場合、RandR出力名(LVDS1およびVGA1)および 私とは異なり VGAのRandRデフォルトモードで問題ないでしょう。

#!/bin/bash

# setting up new mode for my VGA
xrandr --newmode "1920x1080" 148.5 1920 2008 2052 2200 1080 1089 1095 1125 +hsync +vsync
xrandr --addmode VGA1 1920x1080

# default monitor is LVDS1
MONITOR=LVDS1

# functions to switch from LVDS1 to VGA and vice versa
function ActivateVGA {
    echo "Switching to VGA1"
    xrandr --output VGA1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
    MONITOR=VGA1
}
function DeactivateVGA {
    echo "Switching to LVDS1"
    xrandr --output VGA1 --off --output LVDS1 --auto
    MONITOR=LVDS1
}

# functions to check if VGA is connected and in use
function VGAActive {
    [ $MONITOR = "VGA1" ]
}
function VGAConnected {
    ! xrandr | grep "^VGA1" | grep disconnected
}

# actual script
while true
do
    if ! VGAActive && VGAConnected
    then
        ActivateVGA
    fi

    if VGAActive && ! VGAConnected
    then
        DeactivateVGA
    fi

    sleep 1s
done

完全な手順:

  1. 上記のスクリプト(homemadeMonitor.sh)お好みのディレクトリに

  2. ターミナルで次のコマンドを入力して、.shファイルを実行可能にします

    chmod +x homemadeMonitor.sh

  3. .shファイルを実行する

    ./homemadeMonitor.sh

20
peoro

質問の「[a]モニターが接続されていることを通知する方法」の部分への応答:

サポートはまだかなり異なりますが、最近のカーネルでは、ディスプレイのホットプラグが発生したときにudevイベントを生成するためのサポートがいくつかあります。カーネル2.6.38とATI X1400ハードウェアでは、VGAディスプレイを初めて接続したときにイベントが発生しますが、その後のディスプレイの切断または再接続時にイベントが発生しません。 Intelハードウェアの方がサポートが優れている可能性があります。 NVIDIA独自のドライバーは現在KMSをサポートしていません。私はNVIDIAハードウェアでホットプラグイベントを探したことがありませんが、うまくいくかどうかはわかりません。

Udevを試してみたい場合は、次の手順を試してください。

  • 最新のカーネルに更新する
  • カーネルモード設定(KMS)が有効になっていることを確認します。有効になっている場合は、カーネル出力で報告されます。鉱山は[drm] radeon kernel modesetting enabledおよび[drm] initializing kernel modesetting
  • 実行udevadm monitor --propertyし、(切断する)接続時にイベントが報告されるかどうかを確認します。

ディスプレイホットプラグでudevイベントを取得している場合は、次のようなudevルールでスクリプトをトリガーできます。

ACTION=="change", SUBSYSTEM=="drm", HOTPLUG=="1", RUN+="/path/to/hotplug.sh"

注:これは、独自のバイナリドライバでnVIDIA GPUを使用する場合、動作しません。 KMSを使用しません。 udevイベントは取得されません

21
Andy

モニター構成プロファイルをユーザーごとおよびディスプレイごとに保存できるツールに関しては、 autorandr がまさにそれを行います。

私のラップトップはNVIDIAカードを持っているので、xrandrの代わりに ディスパーバックエンド を使用します。 Autorandrは、autodisperと呼ぶ場合、モニターを管理するバックエンドとしてdisperを使用します。ただし、この記事の残りの部分では、一貫性のためにautorandrと呼びます。

autorandr --save profile_nameを使用してプロファイルを保存できます。 autorandrを単独で実行すると、プロファイルのリストが表示され、現在の構成として検出されているプロファイルが識別されます。

例えば:

$ autorandr
laptop
syncmaster19 (detected)

autorandr --changeを使用して、現在の構成に適切なプロファイルを自動的にロードするように指示できます。このコマンドは、ホットプラグされたときに実行するudevルールと組み合わせて、要求どおりの動作をします。

追加の予防策として、そのコマンドに--default laptopを追加しました。これにより、現在の構成と一致する保存されたプロファイルがない場合、ラップトップのディスプレイがデフォルトになります。したがって、ディスプレイを切り替えるために使用する完全なコマンドは次のとおりです。

autorandr --change --default laptop

残念ながら、モニターをホットプラグしても、私のマシンではudev出力がありません。私はNVIDIA独自のドライバーを使用しているので、それは当然のことです。そのため、今のところXF68Displayキー(Fn-F8)にバインドしていますが、これはほぼ同じです。

19
Jack Senechal

上記のudevルールと次のようなシェルスクリプトを使用しました

#!/bin/sh

dmode="$(cat /sys/class/drm/card0-VGA-1/status)"
export DISPLAY=:0
export XAUTHORITY=/home/yourusername/.Xauthority

if [ "${dmode}" = disconnected ]; then
     /usr/bin/xrandr --auto
Elif [ "${dmode}" = connected ];then
     /usr/bin/xrandr --output VGA1 --auto --right-of LVDS1
else /usr/bin/xrandr --auto
fi

Xauthority部分はエクスポートDISPLAYと同様に不可欠です。echo$DISPLAYを使用して、それがどの番号に等しいかを確認できます。 xrandr -qを使用して、お持ちの外部モニターを表示します。最後のelseステートメントは、ディスプレイなしで立ち往生しないようにするためのものです。

7
Cappie

Xサーバーが変更されたモニター構成について通知するのを待ってから、所定のコマンド(たとえば、別の回答で言及されているautorandr)を実行する小さなプログラムは、次の場所にあります https:// bitbucket .org/portix/srandrd/overview

これはudevを使用するより適切な解決策のようです(適切なXサーバーを見つけることを心配する必要がある場合など)。

6

プラグイン時にディスプレイを自動的に検出する必要がある場合は、xrandrコマンドを含むスクリプトを実行するUDEVルールを追加するのが最もクリーンな解決策のようです。これは、あるユーザーのソリューションの例です 1

udevadmを使用してUDEVイベントを監視(出力)します
この手順は、各ユーザーにとって最も重要です。 udevadm monitor --environment --udevを実行します。次に、HDMIケーブルを接続します。

UDEVルール
上記のコマンドの出力に基づいて、ユーザーは/etc/udev/rules.d/95-monitor-hotplug.rulesでこのUDEVルールを作成しました。

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/dan/.Xauthority", RUN+="/usr/local/bin/hotplug_monitor.sh"

Xrandrがユーザープロファイルで実行されるように、使用される環境変数に注意してください。

xrandrスクリプトhotplug_monitor.sh

必要に応じて、xrandrオプションを調整できます。

#! /usr/bin/bash

export DISPLAY=:0
export XAUTHORITY=/home/dan/.Xauthority

function connect(){
    xrandr --output HDMI1 --right-of LVDS1 --preferred --primary --output LVDS1 --preferred 
}

function disconnect(){
      xrandr --output HDMI1 --off
}

xrandr | grep "HDMI1 connected" &> /dev/null && connect || disconnect
5
iyrin

何らかの理由でhotplugルートを使用したくない場合は、inotifywaitを使用してスクリプト内でポーリングしないことも可能です。

#!/ bin/bash 
 
 SCREEN_LEFT = DP2 
 SCREEN_RIGHT = eDP1 
 START_DELAY = 5 
 
 renice +19 $$>/dev/null 
 
 sleep $ START_DELAY 
 
 OLD_DUAL = "dummy" 
 
 while [ 1]; do 
 DUAL = $(cat /sys/class/drm/card0-DP-2/status)

 if ["$ OLD_DUAL"!= "$ DUAL"];次に
 if ["$ DUAL" == "connected"]; then 
 echo 'デュアルモニターのセットアップ' 
 xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT 
 else 
 echo 'シングルモニターセットアップ' 
 xrandr --auto 
 fi 
 
 OLD_DUAL = "$ DUAL" 
 fi 
 
 inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null 
 done 
 

Xrandrでポーリングすると、私の真新しいラップトップで深刻なユーザビリティの問題が発生しました(マウスは定期的に停止します)。

3
Balzola

たとえばXfceで単純化するには、ディストリビューションパッケージで利用可能な「arandr」をインストールしてください。 「arandr」を使用してディスプレイを設定し、たとえば「displayLayout」として保存します。 Arandrは「.sh」拡張子を追加する必要があるため、上記のiyrinによって言及されたスクリプト「hotplug_monitor.sh」で記述されている「関数connect()」で直接使用できます。次に例を示します。

function connect(){
 /path/to/displayLayout.sh
}

切断メカニズムを使用するには、次のようにスクリプトの先頭に "#!/ bin/bash"のすぐ下を追加します。

#!/bin/bash
#
PLUGGED_EXTERNAL=`xrandr | awk /"connected [0-9]"/'{print $1}'`

xrandrは表示を検出し、出力をawkに渡します。awkは、 "connected"の正規表現に基づいてフィルター処理を行い、その後に必要な数字が続きます。私の意見では、プライマリディスプレイは「接続されたプライマリ」の後に番号が続く「解像度」として報告されるため、正規表現で正確な解像度に一致させる必要はありません。次に、awk "print $ 1"は、この場合は外部モニターの名前である最初の列のみを印刷し、これはPLUGGED_EXTERNAL変数に格納されます。次に、スクリプトの固定表示名 "HDMI1"の代わりに、$ PLUGGED_EXTERNALを次のように使用できます。

function disconnect(){
  xrandr --output $PLUGGED_EXTERNAL --off
}

xrandr | grep "$PLUGGED_EXTERNAL connected" &> /dev/null && connect || disconnect
1
user180381

この質問を見ている人はGNOMEを使いたいという人ではないと思います。GNOMEを使う人はこの質問を見る必要はありませんが、完全を期すためです。

GNOMEにはこの機能が組み込まれています。 gnome-control-centerを介して設定を変更すると、gnome-settings-daemonはそれを記憶します(.config/monitors.xml)で、モニターのプラグインまたはプラグアウト時に自動的に適用されます。

残念ながら、monitors.xmlファイルの構成は十分に文書化されていません。質問 ここ を参照してください。 gnome表示ツールも、パン、モニターごとのスケーリングを設定する手段がなく、ズームアウトしません。多くの人々がHiDPIラップトップ画面を通常のDPI画面と一緒に使用しているので、ツールは実用的なソリューションを得るのに十分ではありません。

私はこれを見てきました ウェイランドのロードマップアイテムとして記載されています ですから、ついに、言及された問題の修正が見つかるかもしれません。それまでは、Gnomeでxrandrを手動でセットアップするための遅延の後、起動スクリプトを実行しました。

1

Peoroのソリューションを使用すると、xrandrから余分な出力が得られたため、grepで-cオプションを使用して、一致の数をカウントしました。私はそれをHDMIに適合させ、オーディオスイッチも追加しました:

#!/bin/bash
# adapted from http://unix.stackexchange.com/questions/4489/

# default monitor is LVDS1
MONITOR=LVDS1

# functions to switch from LVDS1 to HDMI1
function ActivateHDMI {
    xrandr --output HDMI1 --mode 1920x1080 --dpi 160 --output LVDS1 --off
    pactl set-card-profile 0 output:hdmi-stereo-extra1
    MONITOR=HDMI1
}
function DeactivateHDMI {
    xrandr --output HDMI1 --off --output LVDS1 --auto
    pactl set-card-profile 0 output:analog-stereo
    MONITOR=LVDS1
}

# functions to check if HDMI is connected and in use
function HDMIActive {
    [ $MONITOR = "HDMI1" ]
}
function HDMIConnected {
    [[ `xrandr | grep "^HDMI1" | grep -c disconnected` -eq 0 ]]
}

# actual script
while true
do
    if ! HDMIActive && HDMIConnected
    then
        ActivateHDMI
    fi

    if HDMIActive && ! HDMIConnected
    then
        DeactivateHDMI
    fi

    sleep 1s
done
1
Aaros

セットアップを簡単にするために私の回答を編集しています。

Autorandrをインストールしてxrandrの画面レイアウトを自動化し、最新の.debを https://github.com/nalipaz/autorandr/releases から取得して実行します。

dpkg -i [file]

保存された画面レイアウトでautorandrをセットアップする

autorandr --save [docked|mobile|home|etc]

例として、モニターが接続されていないラップトップで、私は思い通りにセットアップしてから実行しました。

autorandr --save mobile

次に、私のhdmiを接続してarandrを再構成し、実行しました。

autorandr --save docked

実行できる各レイアウトを設定した後(「モバイル」を以前のお気に入りの名前に置き換えて、モバイルを使用しました):

autorandr --default mobile

Autorandrがすべてセットアップされたので、接続されたディスプレイをポーリングして検出時にautorandr --changeを実行するパッケージをインストールすることにより、プロセスを自動化できます。はい、私はudevについて知っており、それが機能する場合は設定できますが、私のテストでは、udevが私のhdmiに対して一貫して機能しませんでした。 20プラグごとに1つだけしか機能しませんでした。時々完全に停止しました。

こちらから最新の.debをダウンロードします。 https://github.com/nalipaz/poll-xrandr/releases/ でインストールします。

dpkg -i [file]

autorandr --changeの完了時に、より多くのタスクを実行する必要がある可能性が高いです。autorandrでは、これらのコマンドを〜/ .autorandr/postswitchというファイルに挿入できます。次のようにします。

cd ~/.autorandr/ && touch postswitch && chmod +x postswitch

次に、postswitchファイルを編集して、次のような内容にします。

#!/bin/bash
if pidof conky > /dev/null 2>&1; then
  killall conky
fi
(sleep 2s && xrandr-adjust-brightness restore -q) &
(sleep 2s && nitrogen --restore) &
(sleep 3s && conky -q) &

さらに、次の2つのコマンドのように、autorandrとpoll-xrandrをスタートアップに追加することもできます。

autorandr --change &
poll-xrandr &

モニターのプラグを抜いたり差し込んだりして、魔法を見てください!

0
nicholas.alipaz