Narzędzie do automatycznego stosowania konfiguracji RandR po podłączeniu zewnętrznego wyświetlacza

53

czy istnieje narzędzie, które umożliwia:

  • zapamiętuje aktualną konfigurację RandR (położenie, orientację, rozdzielczość itp.) dla poszczególnych monitorów,
  • automatycznie zastosować ostatnią znaną dobrą konfigurację, gdy tylko wyświetlacz zostanie podłączony, bez potrzeby przeszukiwania apletów lub xrandr (1)?

Konfiguracje musiałyby być stosowane dla poszczególnych użytkowników i dla poszczególnych wyświetlaczy.

Jeśli nie ma takiego narzędzia na wolności, sam chciałbym złożyć je razem, ale o ile widzę, nie ma sposobu, aby stwierdzić, że monitor został podłączony. Czy muszę sondować za pomocą xrandr -q raz na jakiś czas, aby dowiedzieć się, czy wyjście zostało podłączone lub odłączone, czy jest bardziej skuteczny sposób, aby to zrobić? Czy uda się to dostroić?

Jarosław Fedevych
źródło
Czy na pewno nie ma sposobu, aby stwierdzić, że do karty podłączono monitor. Spróbuj uruchomić udevadm monitor --propertyz terminala i podłączyć monitor. Z moją kartą widzę zdarzenie, gdy jest ono podłączone. Możesz użyć reguły + RUN w udev i trochę skryptów bash, aby uzyskać to, czego chcesz. Nie jestem jednak pewien, w jaki sposób można to zaimplementować dla poszczególnych użytkowników za pomocą udev.
Steven D
@Steven: Twój komentarz powinien być odpowiedzią. To nie jest pełna odpowiedź, ale robi znaczący postęp. Jeśli udev widzi zdarzenie sprzętowe, powinien powiadomić hal, który wysyła zdarzenie dbus, które może być odczytane przez kod użytkownika.
Gilles „SO- przestań być zły”

Odpowiedzi:

19

Korzystam z tego prostego (domowego) skryptu, który stale odpytuje RandR i przełącza się między LVDS1 i VGA1, gdy VGA zostanie podłączone / rozłączone. (Dla HDMI wyjść w poniższym pliku skryptu, zmienić wszystko VGA1do HDMI1)

To brudne rozwiązanie, ale działa dobrze.

Jest dostosowany do mojej konfiguracji: najprawdopodobniej będziesz musiał zmienić nazwy wyjściowe RandR ( LVDS1i VGA1) i w przeciwieństwie do mnie prawdopodobnie będziesz zadowolony z domyślnego trybu RandR dla VGA.

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

Pełne kroki:

  1. Otwórz Terminal, naciskając Ctrl+Alt+t
  2. Przejdź do dobrej lokalizacji, aby utworzyć i zapisać skrypt powłoki z automatycznym przełączaniem. Przykład

    cd ./Desktop/

  3. Utwórz i edytuj plik .sh za pomocą żądanego edytora tekstu (tutaj użyłem Plumy. Możesz wypróbować nano, vim itp.). Nazwij to dla swojej wygody. Przykład

    sudo pluma homemadeMonitor.sh

  4. Edytuj plik i skopiuj wklej wszystko ze wspomnianego wyżej skryptu (tego z #! / Bin / bash)

  5. Spraw, aby plik .sh był wykonywalny, wpisując następujące polecenie w terminalu

    sudo chmod +x homemadeMonitor.sh

  6. Uruchom plik .sh

    ./homemadeMonitor.sh

peoro
źródło
Dobry scenariusz! Dzięki, potrzebowałem czegoś takiego. Właśnie go skopiowałem i skonfigurowałem do automatycznego uruchamiania. Dzięki!
Linuxios
21

W odpowiedzi na „[a] sposób, aby powiedzieć, że monitor został podłączony” część pytania:

Obsługa wciąż jest bardzo zróżnicowana, ale w najnowszych jądrach jest dostępna obsługa generowania zdarzeń udev, gdy pojawia się hotplug wyświetlania. W przypadku jądra 2.6.38 i sprzętu ATI X1400 po pierwszym podłączeniu wyświetlacza VGA dostaję zdarzenie, ale żadnych zdarzeń po kolejnych rozłączeniach lub ponownych połączeniach wyświetlacza. Sprzęt Intel może mieć lepszą obsługę. Zastrzeżony sterownik NVIDIA obecnie nie obsługuje KMS; Nie próbowałem szukać zdarzeń hotplug na sprzęcie NVIDIA, ale wątpię, by to zadziałało.

Jeśli chcesz eksperymentować z udev, możesz wykonać następujące czynności:

  • aktualizacja do najnowszego jądra
  • upewnij się, że ustawienie trybu jądra (KMS) jest włączone. Jeśli jest włączony, powinien zostać zgłoszony w wynikach jądra. Mój mówi [drm] radeon kernel modesetting enabledi[drm] initializing kernel modesetting
  • uruchom udevadm monitor --propertyi sprawdź, czy zdarzenia są zgłaszane, gdy (dis-) connect wyświetla

Jeśli otrzymujesz zdarzenia udev podczas wyświetlania hotplug, możesz uruchomić skrypt za pomocą reguły udev, takiej jak:

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

Uwaga: To nie zadziała, jeśli używasz procesora graficznego nVIDIA z zastrzeżonym sterownikiem binarnym, ponieważ nie używa on KMS. Będziesz nie dostać żadnych wydarzeń udev.

Andy
źródło
19

Jeśli chodzi o narzędzie, które może przechowywać profile konfiguracji monitorów dla poszczególnych użytkowników i wyświetlaczy, autorandr zrobi to dokładnie. https://github.com/wertarbyte/autorandr .

Mój laptop ma kartę NVIDIA, więc zamiast xrandr używam zaplecza dispera: http://willem.engen.nl/projects/disper/ . Autorandr użyje disper jako backendu do zarządzania monitorami, jeśli nazwiesz go as autodisper. Jednak w dalszej części tego postu będę się nazywać autorandrspójnością.

Możesz zapisać profile za pomocą autorandr --save profile_name. Uruchomiony autorandrprzez siebie wtedy daje listę profili, a także określić, który z nich jest wykrywany jako bieżącej konfiguracji.

Na przykład:

$ autorandr
laptop
syncmaster19 (detected)

Możesz nakazać mu automatyczne ładowanie profilu odpowiedniego dla bieżącej konfiguracji za pomocą autorandr --change. To polecenie, w połączeniu z regułą udev, aby uruchomić ją, gdy jest podłączona podczas pracy, wykona to, o co prosisz.

Jako dodatkowe zabezpieczenie dołączyłem --default laptopdo tego polecenia, które sprawi, że będzie ono domyślnie wyświetlane na ekranie laptopa, jeśli nie ma zapisanego profilu pasującego do bieżącej konfiguracji. Zatem pełne polecenie, którego używam do przełączania wyświetlaczy to:

autorandr --change --default laptop

Niestety, moja maszyna nie daje żadnego wyjścia udev, kiedy podłączam monitor do sieci. Używam zastrzeżonych sterowników NVIDIA, więc nie jest to zaskakujące. Na razie związałem go z klawiszem XF68Display (Fn-F8), który jest prawie tak samo dobry.

Jack Senechal
źródło
1
autorandr to strata czasu, źle udokumentowane, przypadkowe mrugnięcia monitora, brak instrukcji instalacji / dezinstalacji. Można to rozwiązać za pomocąudev
Leo Gallucci
5
Na wszelki wypadek istnieje dobrze utrzymany przepisany w Pythonie widelec autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs
7

Użyłem sugerowanej powyżej reguły udev wraz ze skryptem powłoki, który wygląda

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

Część Xauthority jest niezbędna, podobnie jak eksport DISPLAY, możesz użyć echa, $DISPLAYaby zobaczyć, która liczba jest równa. Służy xrandr -qdo wyświetlania posiadanych monitorów zewnętrznych. Ostatnim stwierdzeniem jest upewnienie się, że nigdy nie utkniesz bez wyświetlacza.

Cappie
źródło
6

Mały program, który czeka na powiadomienie serwera X o zmianie konfiguracji monitora, a następnie wykonuje dane polecenie (np. autorandrWspomniane w innej odpowiedzi) jest dostępny pod adresem : https://bitbucket.org/portix/srandrd/overview

To wydaje się być czystszym rozwiązaniem, które przy użyciu udev(gdzie trzeba się martwić o znalezienie odpowiedniego serwera X itp.)

Joachim Breitner
źródło
5

Jeśli musisz go automatycznie wykrywać po podłączeniu, wydaje się, że najczystszym rozwiązaniem jest dodanie reguły UDEV w celu uruchomienia skryptu zawierającego polecenia xrandr. Oto przykład rozwiązania jednego użytkownika 1 :

Monitoruj (wyjściowe) zdarzenia UDEV za pomocąudevadm
Ten krok będzie najważniejszy dla każdego użytkownika. Uruchom udevadm monitor --environment --udev. Następnie podłącz kabel HDMI.

Reguła UDEV
Na podstawie danych wyjściowych powyższego polecenia użytkownik utworzył tę regułę UDEV pod adresem /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"

Zwróć uwagę na używane zmienne środowiskowe, aby xrandr był uruchamiany w profilu użytkownika.

skrypt xrandr hotplug_monitor.sh

Możesz dostosować opcje xrandr do swoich potrzeb.

#! /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
źródło
3

Dla tych, którzy z jakiegokolwiek powodu nie chcą wybrać trasy hotplug, nadal można nie odpytywać w skrypcie za pomocą inotifywait:

#! / bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

spać $ START_DELAY

OLD_DUAL = „manekin”

podczas gdy [1]; zrobić
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if [„$ OLD_DUAL”! = „$ DUAL”]; następnie
        jeśli [„$ DUAL” == „podłączony”]; następnie
            echo „Konfiguracja podwójnego monitora”
            xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal - poniżej $ SCREEN_LEFT
        jeszcze
            echo „Konfiguracja pojedynczego monitora”
            xrandr --auto
        fi

        OLD_DUAL = „$ DUAL”
    fi

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

Sondowanie za pomocą xrandr spowodowało poważne problemy z użytecznością na moim nowym laptopie (mysz od czasu do czasu przestała działać).

Balzola
źródło
1

Korzystając z rozwiązania peoro, otrzymałem dodatkowe wyjście z xrandr, więc użyłem opcji -c dla grep, która liczy liczbę dopasowań. Dostosowałem go do HDMI i dodałem również przełącznik audio:

#!/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
źródło
1

Sądzę, że ludzie, którzy patrzą na to pytanie, nie są tymi, którzy chcą używać GNOME, a ci, którzy używają GNOME, nie musieliby patrzeć na to pytanie, ale w interesie kompletności:

GNOME ma tę wbudowaną funkcjonalność. Jeśli zmienisz konfigurację za pomocą gnome-control-centre, gnome-settings-daemon zapamięta ją (wejdzie .config/monitors.xml) i automatycznie zastosuje, gdy monitor zostanie podłączony lub odłączony.

Niestety konfiguracja w pliku monitors.xml nie jest dobrze udokumentowana. Zobacz pytanie tutaj . Narzędzia wyświetlania gnomów również nie mają możliwości ustawiania przesuwania, skalowania dla monitora i nie pomniejszają. Ponieważ wiele osób korzysta z ekranu laptopa HiDPI wraz ze zwykłym ekranem DPI, narzędzia nie wystarczą, aby uzyskać praktyczne rozwiązanie.

Widziałem to jako element mapy drogowej dla Waylanda, więc kiedy wreszcie nadejdzie, możemy zobaczyć rozwiązanie wspomnianych problemów. Do tego czasu na Gnome po prostu uruchamiam skrypt startowy z opóźnieniem, aby ręcznie skonfigurować xrandr.

Joachim Breitner
źródło
1

Aby uprościć na przykład w Xfce, zainstaluj „arandr”, który powinien być dostępny w twoich pakietach dystrybucyjnych. Skonfiguruj wyświetlacz za pomocą „arandr”, a następnie zapisz go jako na przykład „displayLayout”. Arandr powinien dodać dla ciebie rozszerzenie „.sh”, aby można go było używać bezpośrednio w „function connect ()”, jak napisano w skrypcie „hotplug_monitor.sh” wspomnianym powyżej przez iyrin, na przykład:

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

Aby użyć mechanizmu rozłączania, dodaj na górze skryptu tuż pod „#! / Bin / bash” w następujący sposób:

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

xrandr wykryje wyświetlanie i przekaże dane wyjściowe do awk, który przefiltruje je na podstawie wyrażenia regularnego „połączony”, po którym następuje cyfra, która w gruncie rzeczy jest tym, czego chcemy. Moim zdaniem dopasowanie dokładnej rozdzielczości w wyrażeniu regularnym nie jest konieczne, ponieważ wyświetlanie pierwotne jest zgłaszane jako „podłączony pierwotny”, po którym następuje liczba, tj. Rozdzielczość. Następnie awk „print $ 1” wypisze tylko pierwszą kolumnę, która w tym przypadku jest nazwą monitora zewnętrznego i będzie przechowywana w zmiennej PLUGGED_EXTERNAL. Następnie zamiast stałej nazwy wyświetlanej „HDMI1” w skrypcie $ PLUGGED_EXTERNAL można użyć:

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

xrandr | grep "$PLUGGED_EXTERNAL connected" &> /dev/null && connect || disconnect
użytkownik180381
źródło
0

Edycja mojej odpowiedzi, aby ułatwić konfigurację.

Zainstaluj autorandr, aby zautomatyzować układ ekranu w xrandr, pobierz najnowszy plik .deb z https://github.com/nalipaz/autorandr/releases i uruchom:

dpkg -i [file]

Skonfiguruj autorandr z zapisanymi układami ekranu

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

Na przykład na moim laptopie bez podłączonych monitorów konfiguruję i konfiguruję tak, jak chcę, a następnie uruchamiam:

autorandr --save mobile

Następnie podłączyłem mój hdmi i ponownie skonfigurowałem arandr, a następnie uruchomiłem:

autorandr --save docked

Po skonfigurowaniu każdego z układów możesz uruchomić (zamień „mobile” na poprzednią ulubioną nazwę, użyłem mobile):

autorandr --default mobile

Teraz, gdy autorandr jest już skonfigurowany, możesz zautomatyzować proces, instalując pakiet, który będzie sprawdzał podłączone wyświetlacze i uruchamiał się autorandr --changepo wykryciu. Tak, wiem o udev i możesz to ustawić, jeśli działa dla ciebie, ale w moich testach udev nie działał konsekwentnie dla mojego hdmi. Działa tylko 1 na każde 20 wtyczek / odłączników i czasami po prostu całkowicie przestaje działać.

Pobierz najnowszą wersję .deb tutaj: https://github.com/nalipaz/poll-xrandr/releases/, a następnie zainstaluj za pomocą

dpkg -i [file]

Najprawdopodobniej konieczne jest uruchomienie większej liczby zadań po zakończeniu autorandr --change, autorandr umożliwia wstawienie tych poleceń do pliku o nazwie ~ / .autorandr / postswitch. Wykonaj następujące czynności:

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

Teraz edytuj plik postswitch, aby uzyskać coś podobnego do następującego:

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

Ponadto prawdopodobnie będziesz chciał dodać autorandr i poll-xrandr do swoich startupów, coś w rodzaju dwóch następujących poleceń:

autorandr --change &
poll-xrandr &

Odłącz lub podłącz monitor i obserwuj magię!

nicholas.alipaz
źródło