Ein Tool zum automatischen Anwenden der RandR-Konfiguration, wenn ein externes Display angeschlossen ist

53

Gibt es ein Tool, mit dem man:

  • Speichern der aktuellen RandR-Konfiguration (Position, Ausrichtung, Auflösung usw.) auf Monitorbasis,
  • Die zuletzt als funktionierend bekannte Konfiguration wird automatisch angewendet, sobald das Display angeschlossen ist, ohne dass Applets oder xrandr (1) verwendet werden müssen.

Die Konfigurationen müssten pro Benutzer und pro Anzeige angewendet werden.

Wenn es ein solches Tool in freier Wildbahn nicht gibt, würde ich selbst gerne eines zusammenwerfen, aber soweit ich sehen kann, gibt es keine Möglichkeit, festzustellen, dass ein Monitor angeschlossen ist. Muss ich mit xrandr -q abfragen hin und wieder herauszufinden, dass ein Ausgang verbunden oder getrennt wurde, oder gibt es eine effizientere Möglichkeit, dies zu tun? Kann man udev darauf abstimmen?

Jaroslaw Fedewytsch
quelle
Sind Sie sicher, dass kein Monitor mit Ihrer Karte verbunden ist? Versuchen Sie, udevadm monitor --propertyvom Terminal aus zu starten und den Monitor anzuschließen. Bei meiner Karte wird ein Ereignis angezeigt, wenn sie eingesteckt ist. Möglicherweise können Sie in udev eine + RUN-Regel und einige Bash-Skripte verwenden, um das gewünschte Ergebnis zu erzielen. Ich bin mir jedoch nicht sicher, wie Sie dies mit udev auf Benutzerbasis implementieren können.
Steven D
@Steven: Dein Kommentar sollte eine Antwort sein. Es ist keine vollständige Antwort, aber es macht erhebliche Fortschritte. Wenn udev ein Hardware-Ereignis sieht, sollte es hal benachrichtigen, das ein dbus-Ereignis sendet, das vom Benutzercode gesehen werden kann.
Gilles 'SO- hör auf, böse zu sein'

Antworten:

19

Ich verwende dieses einfache (hausgemachte) Skript, das RandR weiterhin abruft und zwischen LVDS1 und VGA1 wechselt, wenn VGA verbunden / getrennt wird. ( Ändern Sie bei HDMI- Ausgängen in der folgenden Skriptdatei alle VGA1in. HDMI1)

Es ist eine schmutzige Lösung, aber es funktioniert gut.

Es ist an mein Setup angepasst: Wahrscheinlich müssen Sie die RandR-Ausgabenamen ( LVDS1und VGA1) ändern, und im Gegensatz zu mir ist Ihr RandR-Standardmodus für VGA wahrscheinlich in Ordnung.

#!/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

Volle Schritte:

  1. Öffnen Sie das Terminal durch Drücken von Ctrl+Alt+t
  2. Navigieren Sie zu einem geeigneten Speicherort, um das automatisch umschaltende Shell-Skript zu erstellen und zu speichern. Beispiel

    cd ./Desktop/

  3. Erstellen und bearbeiten Sie die .sh-Datei mit Ihrem gewünschten Texteditor (hier habe ich pluma verwendet. Sie können nano, vim usw. ausprobieren). Nennen Sie es zu Ihrer Bequemlichkeit. Beispiel

    sudo pluma homemadeMonitor.sh

  4. Bearbeiten Sie die Datei und fügen Sie alles aus dem oben genannten Skript ein (das mit #! / Bin / bash).

  5. Machen Sie die .sh-Datei ausführbar, indem Sie den folgenden Befehl im Terminal eingeben

    sudo chmod +x homemadeMonitor.sh

  6. Führen Sie die SH-Datei aus

    ./homemadeMonitor.sh

peoro
quelle
Gutes Drehbuch! Danke, ich brauchte so etwas. Ich habe es einfach kopiert und so eingerichtet, dass es automatisch ausgeführt wird. Vielen Dank!
Linuxios
21

Als Antwort auf den Teil der Frage "[a], um festzustellen, ob ein Monitor angeschlossen ist":

Die Unterstützung variiert immer noch ziemlich stark, aber mit den neuesten Kerneln gibt es eine gewisse Unterstützung für das Generieren von udev-Ereignissen, wenn ein Anzeige-Hotplug auftritt. Mit Kernel 2.6.38 und ATI X1400-Hardware erhalte ich beim ersten Anschließen eines VGA-Bildschirms ein Ereignis, aber keine Ereignisse beim anschließenden Trennen oder erneuten Anschließen des Bildschirms. Intel-Hardware wird möglicherweise besser unterstützt. Der proprietäre NVIDIA-Treiber unterstützt derzeit KMS nicht. Ich habe nicht versucht, nach Hotplug-Ereignissen auf NVIDIA-Hardware zu suchen, aber ich bezweifle, dass dies funktionieren würde.

Wenn Sie mit udev experimentieren möchten, können Sie die folgenden Schritte ausführen:

  • Update auf den neuesten Kernel
  • Stellen Sie sicher, dass die Kernelmodus-Einstellung (KMS) aktiviert ist. Wenn aktiviert, sollte dies in Ihrer Kernel-Ausgabe gemeldet werden. Meins sagt [drm] radeon kernel modesetting enabledund[drm] initializing kernel modesetting
  • Laufen Sie udevadm monitor --propertyund prüfen Sie, ob Ereignisse gemeldet werden, wenn Sie Anzeigen (trennen)

Wenn udev-Ereignisse auf dem Display angezeigt werden, können Sie ein Skript mit einer udev-Regel wie der folgenden auslösen:

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

Hinweis: Dies funktioniert nicht , wenn Sie eine NVIDIA-GPU mit dem proprietären Binärtreiber verwenden, da KMS nicht verwendet wird. Sie werden nicht alle udev Veranstaltungen.

Andy
quelle
19

Bei einem Tool, das Monitorkonfigurationsprofile pro Benutzer und pro Anzeige speichern kann, wird autorandr genau das tun. https://github.com/wertarbyte/autorandr .

Mein Laptop hat eine NVIDIA-Karte, daher verwende ich das Disper-Backend anstelle von xrandr: http://willem.engen.nl/projects/disper/ . Autorandr verwendet disper als Backend, um Ihre Monitore zu verwalten, wenn Sie es als aufrufen autodisper. Für den Rest dieses Beitrags beziehe ich mich jedoch auf die autorandrKonsistenz.

Sie können Profile mit speichern autorandr --save profile_name. Wenn autorandrSie das Programm alleine ausführen, erhalten Sie eine Liste mit Profilen und können feststellen, welches als aktuelle Konfiguration erkannt wurde.

Zum Beispiel:

$ autorandr
laptop
syncmaster19 (detected)

Sie können festlegen, dass das entsprechende Profil für die aktuelle Konfiguration automatisch mit geladen wird autorandr --change. Dieser Befehl würde, zusammen mit einer udev-Regel, die ihn ausführt, wenn er per Hot-Plug ausgeführt wird, genau das tun, was Sie angefordert haben.

Als zusätzliche Vorsichtsmaßnahme habe ich --default laptopdiesen Befehl angehängt , sodass er standardmäßig auf dem Laptop angezeigt wird, wenn kein gespeichertes Profil vorhanden ist, das der aktuellen Konfiguration entspricht. Der vollständige Befehl zum Wechseln der Anzeige lautet also:

autorandr --change --default laptop

Leider gibt mein Computer keine udev-Ausgabe aus, wenn ich meinen Monitor an das Stromnetz anschließe. Ich verwende die proprietären NVIDIA-Treiber, was nicht verwunderlich ist. Daher habe ich es vorerst an die XF68Display-Taste (Fn-F8) gebunden, was fast genauso gut ist.

Jack Senechal
quelle
1
autorandr war Zeitverschwendung, schlecht dokumentiert, zufälliges Blinken des Monitors, keine Anweisungen zum Installieren / Deinstallieren. Könnte es lösen mitudev
Leo Gallucci
5
Nur für den Fall, es gibt eine schön gepflegte, in Python umgeschriebene Gabel von autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs
7

Ich habe die oben vorgeschlagene udev-Regel zusammen mit einem Shell-Skript verwendet, das so aussieht

#!/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

Der Xauthority-Teil ist ebenso wichtig wie der Export DISPLAY. Sie können Echo verwenden, um $DISPLAYzu sehen, welcher Zahl er entspricht. Verwenden Sie xrandr -q, um die externen Monitore anzuzeigen, die Sie haben. Die letzte else-Anweisung soll nur sicherstellen, dass Sie nie ohne Anzeige stecken bleiben.

Cappie
quelle
6

Ein kleines Programm, das darauf wartet, dass der X-Server ihn über geänderte Monitorkonfigurationen benachrichtigt und dann einen bestimmten Befehl ausführt (z. B. den autorandrin einer anderen Antwort genannten), ist verfügbar unter: https://bitbucket.org/portix/srandrd/overview

Dies scheint eine sauberere Lösung zu sein, die verwendet wird udev(wo Sie sich Sorgen machen müssen, den richtigen X-Server zu finden usw.).

Joachim Breitner
quelle
5

Wenn die Anzeige beim Anschließen automatisch erkannt werden soll, ist das Hinzufügen einer UDEV-Regel zur Ausführung eines Skripts mit Ihren xrandr-Befehlen anscheinend die sauberste Lösung. Hier ist ein Beispiel für die Lösung 1 eines Benutzers :

Überwachen (Ausgeben) von UDEV-Ereignissen mitudevadm
Dieser Schritt ist für jeden Benutzer am wichtigsten. Rennen udevadm monitor --environment --udev. Schließen Sie dann Ihr HDMI-Kabel an.

UDEV-Regel
Basierend auf der Ausgabe des obigen Befehls hat der Benutzer diese UDEV-Regel um erstellt /etc/udev/rules.d/95-monitor-hotplug.rules.

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

Beachten Sie die verwendeten Umgebungsvariablen, damit xrandr unter dem Benutzerprofil ausgeführt wird.

xrandr script hotplug_monitor.sh

Möglicherweise möchten Sie die xrandr-Optionen an Ihre Bedürfnisse anpassen.

#! /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
Iyrin
quelle
3

Für diejenigen, die aus irgendeinem Grund den Hotplug-Weg nicht einschlagen möchten, ist es dennoch möglich, in einem Skript nicht mit inotifywait abzufragen:

#! / bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

$ START_DELAY schlafen

OLD_DUAL = "Dummy"

während [1]; machen
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if ["$ OLD_DUAL"! = "$ DUAL"]; dann
        if ["$ DUAL" == "connected"]; dann
            Echo 'Dual-Monitor-Setup'
            xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT
        sonst
            Echo 'Single Monitor Setup'
            xrandr --auto
        fi

        OLD_DUAL = "$ DUAL"
    fi

    inotifywait -q -e close / sys / class / drm / card0-DP-2 / status> / dev / null
getan

Das Polling mit xrandr führte bei meinem brandneuen Laptop zu schwerwiegenden Usability-Problemen (die Maus kam regelmäßig zum Stillstand).

Balzola
quelle
1

Bei der Verwendung der peoro-Lösung habe ich eine zusätzliche Ausgabe von xrandr erhalten, daher habe ich die Option -c für grep verwendet, die die Anzahl der Übereinstimmungen zählt. Ich habe es für HDMI angepasst und auch einen Audio-Schalter hinzugefügt:

#!/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
Aaros
quelle
1

Ich vermute, die Leute, die sich mit dieser Frage befassen, sind nicht diejenigen, die GNOME verwenden möchten, und diejenigen, die GNOME verwenden, müssen sich diese Frage nicht ansehen, sondern der Vollständigkeit halber:

GNOME hat diese Funktionalität eingebaut. Wenn Sie das Setup über gnome-control-center ändern, merkt sich der gnome-settings-daemon das (eingehende) Setup .config/monitors.xmlund wendet es automatisch an, wenn ein Monitor angeschlossen oder ausgesteckt wird.

Leider ist die Konfiguration in der Datei monitore.xml nicht gut dokumentiert. Siehe Frage hier . Das Gnome-Anzeigewerkzeug hat auch keine Möglichkeit, Schwenken und Skalieren pro Monitor einzurichten, und es kann nicht herausgezoomt werden. Da viele Benutzer einen HiDPI-Laptop-Bildschirm zusammen mit einem normalen DPI-Bildschirm verwenden, reichen die Tools nicht aus, um eine funktionsfähige Lösung zu erhalten.

Ich habe dies als Roadmap-Punkt für Wayland gesehen, aber wenn es endlich soweit ist, werden wir möglicherweise eine Lösung für die genannten Probleme finden. Bis dahin habe ich auf Gnome nach einer Verzögerung ein Startskript ausgeführt, um xrandr manuell einzurichten.

Joachim Breitner
quelle
1

Um es zum Beispiel in Xfce zu vereinfachen, installieren Sie bitte "arandr", das in Ihren Distributionspaketen verfügbar sein sollte. Konfigurieren Sie Ihre Anzeige mit "arandr" und speichern Sie sie beispielsweise als "displayLayout". Arandr sollte für Sie die Erweiterung ".sh" hinzufügen, damit sie direkt in "function connect ()" verwendet werden kann, wie in dem von iyrin oben erwähnten Skript "hotplug_monitor.sh" beschrieben, zum Beispiel:

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

Um den Trennungsmechanismus zu verwenden, fügen Sie am oberen Rand des Skripts direkt unter "#! / Bin / bash" Folgendes hinzu:

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

xrandr erkennt die Anzeige und übergibt die Ausgabe an awk. Diese filtert sie basierend auf dem regulären Ausdruck "connected", gefolgt von einer Ziffer, die im Wesentlichen das ist, was wir wollen. Meiner Meinung nach ist es nicht erforderlich, die exakte Auflösung in regulären Ausdrücken abzugleichen, da die primäre Anzeige als "verbundene primäre" angezeigt wird, gefolgt von einer Zahl, dh der Auflösung. Dann gibt awk "print $ 1" nur die erste Spalte aus, die in diesem Fall der Name des externen Monitors ist, und diese wird in der Variablen PLUGGED_EXTERNAL gespeichert. Als nächstes kann anstelle des festen Anzeigenamens "HDMI1" im Skript $ PLUGGED_EXTERNAL wie folgt verwendet werden:

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

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

Bearbeiten meiner Antwort, um die Einrichtung zu vereinfachen.

Installieren Sie autorandr, um das Bildschirmlayout in xrandr zu automatisieren, holen Sie sich die neueste .deb-Datei von https://github.com/nalipaz/autorandr/releases und führen Sie Folgendes aus :

dpkg -i [file]

Richten Sie autorandr mit gespeicherten Bildschirmlayouts ein

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

Als Beispiel: Auf meinem Laptop ohne angeschlossene Monitore richte ich eine beliebige Konfiguration ein und lief dann wie folgt ab:

autorandr --save mobile

Dann steckte ich mein HDMI ein und rekonfigurierte arandr, dann lief:

autorandr --save docked

Nachdem Sie jedes Ihrer Layouts eingerichtet haben, können Sie Folgendes ausführen (ersetzen Sie 'mobile' durch den vorherigen bevorzugten Namen, den ich für mobile Geräte verwendet habe):

autorandr --default mobile

Jetzt, da autorandr vollständig eingerichtet ist, können Sie den Prozess automatisieren, indem Sie ein Paket installieren, das nach verbundenen Displays sucht und autorandr --changebei Erkennung ausgeführt wird. Ja, ich kenne udev und Sie können das einrichten, wenn es für Sie funktioniert, aber in meinen Tests hat udev für mein HDMI nicht durchgehend funktioniert. Es funktionierte nur 1 von 20 Steckern / Steckern oder so, und manchmal hörte es einfach ganz auf.

Laden Sie die neueste .deb-Datei von hier herunter: https://github.com/nalipaz/poll-xrandr/releases/ und installieren Sie sie mit

dpkg -i [file]

Es ist höchstwahrscheinlich erforderlich, dass Sie nach Abschluss von weitere Tasks autorandr --changeausführen. Mit autorandr können diese Befehle in eine Datei mit dem Namen ~ / .autorandr / postswitch eingefügt werden. Gehen Sie wie folgt vor:

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

Bearbeiten Sie nun die Postswitch-Datei so, dass sie etwa wie folgt aussieht:

#!/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) &

Zusätzlich möchten Sie wahrscheinlich autorandr und poll-xrandr zu Ihren Startups hinzufügen, ähnlich wie die folgenden zwei Befehle:

autorandr --change &
poll-xrandr &

Ziehen Sie den Stecker aus der Steckdose oder schließen Sie einen Monitor an und beobachten Sie die Magie!

nicholas.alipaz
quelle