Uno strumento per applicare automaticamente la configurazione RandR quando è collegato uno schermo esterno


54

esiste uno strumento che consente di:

  • ricordare l'attuale configurazione RandR (posizione, orientamento, risoluzione ecc.) in base al monitor,
  • applica automaticamente l'ultima buona configurazione nota non appena viene collegato il display, senza la necessità di andare in giro con applet o xrandr (1)?

Le configurazioni dovrebbero essere applicate su base per utente, per display.

Se non esiste un tale strumento in natura, mi piacerebbe metterne uno da solo, ma per quanto posso vedere, non c'è modo di dire che un monitor è stato collegato. Devo eseguire il polling con xrandr -q di tanto in tanto per capire che un'uscita era collegata o disconnessa, o c'è un modo più efficiente per farlo? Udev può essere sintonizzato per fare proprio questo?


Sei sicuro che non c'è modo di dire che un monitor è stato collegato con la tua scheda. Prova a correre udevadm monitor --propertydal terminale e collega il monitor. Con la mia scheda, vedo un evento quando è collegato. Potresti essere in grado di utilizzare una regola + RUN in udev e alcuni script bash per ottenere ciò che desideri. Tuttavia, non sono sicuro di come potresti implementarlo su una base per utente usando udev.
Steven D,

@Steven: il tuo commento dovrebbe essere una risposta. Non è una risposta completa, ma fa progressi significativi. Se udev vede un evento hardware, dovrebbe avvisare hal che invia un evento dbus che può essere visto dal codice utente.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


19

Sto usando questo semplice script (casalingo) che continua a eseguire il polling di RandR e passa da LVDS1 a VGA1 quando VGA viene connessa / disconnessa. (Per le uscite HDMI , nel seguente file di script, cambiare tutto VGA1in HDMI1)

È una soluzione sporca, ma funziona bene.

È personalizzato per la mia configurazione: molto probabilmente dovrai cambiare i nomi di output di RandR ( LVDS1e VGA1) e, a differenza di me , probabilmente starai bene con la modalità predefinita di RandR per 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

Passi completi:

  1. Aprire il terminale premendo Ctrl+Alt+t
  2. Passare a una buona posizione per creare e memorizzare lo script della shell a commutazione automatica. Esempio

    cd ./Desktop/

  3. Crea e modifica il file .sh con l'editor di testo desiderato (qui ho usato pluma. Puoi provare nano, vim, ecc.). Denominalo a tuo piacimento. Esempio

    sudo pluma homemadeMonitor.sh

  4. Modifica il file e copia incolla tutto dallo script sopra menzionato (quello con #! / Bin / bash)

  5. Rendere eseguibile il file .sh digitando il seguente comando nel terminale

    sudo chmod +x homemadeMonitor.sh

  6. Esegui il file .sh

    ./homemadeMonitor.sh


Buona sceneggiatura! Grazie, avevo bisogno di qualcosa del genere. L'ho appena copiato e impostato per l'esecuzione automatica. Grazie!
Linuxios

21

Rispondere al "[a] modo di dire che un monitor è stato collegato" parte della domanda:

Il supporto varia ancora un po ', ma con i kernel recenti esiste un supporto per la generazione di eventi udev quando si verifica un hotplug di visualizzazione. Con l'hardware del kernel 2.6.38 e ATI X1400, ricevo un evento la prima volta che collego un display VGA ma nessun evento su successive disconnessioni o riconnessioni del display. L'hardware Intel potrebbe avere un supporto migliore. Il driver proprietario NVIDIA non supporta attualmente KMS; Non ho provato a cercare eventi hotplug sull'hardware NVIDIA, ma dubito che funzionerebbe.

Se vuoi sperimentare udev puoi provare i seguenti passi:

  • aggiornamento al kernel più recente
  • assicurarsi che l'impostazione della modalità kernel (KMS) sia abilitata. Se abilitato, dovrebbe essere riportato nell'output del kernel. Il mio dice [drm] radeon kernel modesetting enablede[drm] initializing kernel modesetting
  • eseguire udevadm monitor --propertye vedere se gli eventi vengono segnalati quando si (dis-) si connettono i display

Se ricevi eventi udev sul display hotplug, puoi attivare uno script con una regola udev come:

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

Nota: questo non funzionerà se si utilizza una GPU nVIDIA con il driver binario proprietario, poiché non utilizza KMS. Si Non ottenere qualsiasi eventi udev.


19

Per quanto riguarda uno strumento in grado di memorizzare i profili di configurazione del monitor in base all'utente e al display, autorandr farà esattamente questo. https://github.com/wertarbyte/autorandr .

Il mio laptop ha una scheda NVIDIA, quindi uso il disper backend invece di xrandr: http://willem.engen.nl/projects/disper/ . Autorandr userà disper come backend per gestire i tuoi monitor se lo chiami come autodisper. Per il resto di questo post, mi riferirò ad esso autorandrper coerenza.

Puoi salvare i profili con autorandr --save profile_name. L'esecuzione autorandrda sola ti fornirà quindi un elenco di profili e identificherà quale viene rilevato come la configurazione corrente.

Per esempio:

$ autorandr
laptop
syncmaster19 (detected)

Puoi dire di caricare automaticamente il profilo appropriato per la configurazione corrente con autorandr --change. Questo comando, associato a una regola udev per eseguirlo quando è hot plug, farebbe quello che hai richiesto.

Come ulteriore precauzione ho aggiunto --default laptopquel comando, che lo renderà predefinito sul display del laptop se non esiste un profilo salvato che corrisponda alla configurazione corrente. Quindi il comando completo che uso per cambiare display è:

autorandr --change --default laptop

Sfortunatamente la mia macchina non fornisce alcun output udev quando collego a caldo il mio monitor. Sto usando i driver proprietari NVIDIA, quindi non è sorprendente. Quindi per ora l'ho associato al tasto XF68Display (Fn-F8), che è quasi altrettanto buono.


1
autorandr è stato uno spreco di tempo, cattiva documentazione, lampeggi casuali del monitor, nessuna istruzione di installazione / disinstallazione. Potrebbe risolverlo usandoudev
Leo Gallucci il

5
Per ogni evenienza, c'è un bel fork riscritto e riscritto in Python di autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs

7

Ho usato la regola udev suggerita sopra insieme a uno script shell che sembra

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

La parte Xauthority è essenziale così come l'esportazione DISPLAY, puoi usare l'eco $DISPLAYper vedere a quale numero è uguale. Usa xrandr -qper vedere i monitor esterni che hai. L'ultima affermazione di altro è solo per assicurarsi che non sei mai bloccato senza un display.


6

Un piccolo programma che attende il server X per notificarlo in merito alla modifica della configurazione del monitor e quindi esegue un determinato comando (ad esempio il autorandrcitato in un'altra risposta) è disponibile all'indirizzo: https://bitbucket.org/portix/srandrd/overview

Questa sembra essere una soluzione più pulita che usando udev(dove devi preoccuparti di trovare il server X giusto ecc.)


5

Se è necessario che rilevi automaticamente il display quando è collegato, sembra che la soluzione più pulita sia quella di aggiungere una regola UDEV per eseguire uno script contenente i comandi xrandr. Ecco un esempio dalla soluzione 1 di un utente :

Monitorare (emettere) gli eventi UDEV conudevadm
questo passaggio sarà molto importante per ogni utente. Corri udevadm monitor --environment --udev. Quindi collegare il cavo HDMI.

Regola UDEV
In base all'output del comando precedente, l'utente ha creato questa regola UDEV in /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"

Nota le variabili d'ambiente utilizzate in modo che xrandr verrà eseguito sotto il profilo utente.

xrandr script hotplug_monitor.sh

Potresti voler regolare le opzioni di xrandr in base alle tue esigenze.

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

3

Per coloro che, per qualsiasi motivo, non vogliono seguire il percorso hotplug, è comunque possibile non eseguire il polling all'interno di uno script usando inotifywait:

#! / Bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

dormire $ START_DELAY

OLD_DUAL = "fittizio"

while [1]; fare
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if ["$ OLD_DUAL"! = "$ DUAL"]; poi
        se ["$ DUAL" == "connesso"]; poi
            echo 'Configurazione doppio monitor'
            xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT
        altro
            echo 'Impostazione monitor singolo'
            xrandr --auto
        fi

        OLD_DUAL = "$ DUAL"
    fi

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

Il polling con xrandr ha causato seri problemi di usabilità sul mio laptop nuovo di zecca (il mouse si arrestava periodicamente).


1

Quando ho usato la soluzione di peoro, ho ottenuto un output extra da xrandr, quindi ho usato l'opzione -c per grep che conta il numero di corrispondenze. L'ho adattato per HDMI e ho aggiunto anche l'interruttore 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

1

Immagino che le persone che guardano a questa domanda non siano quelle che vogliono usare GNOME, e quelle che usano GNOME non dovrebbero guardare a questa domanda, ma nell'interesse della completezza:

GNOME ha questa funzionalità integrata. Se modifichi il setup tramite gnome-control-center, gnome-settings-daemon lo ricorda (in .config/monitors.xml) e lo applica automaticamente quando un monitor è collegato o disconnesso.

Purtroppo la configurazione nel file monitors.xml non è ben documentata. Vedi la domanda qui . Anche gli strumenti di visualizzazione di gnome non hanno alcun mezzo per impostare il panning, il ridimensionamento per monitor e non fanno zoom indietro. Poiché molte persone utilizzano uno schermo per laptop HiDPI insieme a uno schermo DPI normale, gli strumenti non sono sufficienti per ottenere una soluzione praticabile.

Ho visto questo citato come un elemento della tabella di marcia per Wayland, quindi quando finalmente arriva potremmo vedere una correzione per i problemi menzionati. Fino ad allora su Gnome ho appena eseguito uno script di avvio dopo un ritardo nell'installazione manuale di xrandr.


1

Per semplificare, ad esempio, in Xfce, installare "arandr", che dovrebbe essere disponibile nei pacchetti distro. Configurare il display utilizzando "arandr", quindi salvarlo come "displayLayout", ad esempio. Arandr dovrebbe aggiungere per te l'estensione ".sh" in modo che possa essere utilizzato direttamente in "function connect ()" come scritto nello script "hotplug_monitor.sh" menzionato da iyrin sopra, ad esempio:

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

Per usare il meccanismo di disconnessione aggiungi nella parte superiore dello script appena sotto "#! / Bin / bash" in questo modo:

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

xrandr rileverà il display e passerà l'output a awk che lo filtrerà in base all'espressione regolare "connessa" seguita da una cifra che in sostanza è ciò che vogliamo. A mio avviso, non è necessario associare la risoluzione esatta nell'espressione regolare poiché il display principale viene indicato come "primario collegato" seguito da un numero, ovvero dalla risoluzione. Quindi awk "print $ 1" stamperà solo la prima colonna che è il nome del monitor esterno in questo caso e questo sarà memorizzato nella variabile PLUGGED_EXTERNAL. Quindi, al posto del nome visualizzato fisso "HDMI1" nello script $ PLUGGED_EXTERNAL si può usare in questo modo:

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

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

0

Modifica la mia risposta per semplificare la configurazione.

Installa autorandr per automatizzare il layout dello schermo in xrandr, prendi l'ultimo .deb da https://github.com/nalipaz/autorandr/releases ed esegui:

dpkg -i [file]

Impostazione autorandr con layout dello schermo memorizzati

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

Ad esempio, sul mio laptop senza alcun monitor collegato, ho installato arandr nel modo desiderato, quindi ho eseguito:

autorandr --save mobile

Quindi ho collegato il mio hdmi e riconfigurato arandr, quindi ho eseguito:

autorandr --save docked

Dopo aver impostato ciascuno dei layout che puoi eseguire (sostituisci "mobile" con il nome preferito precedente, ho usato mobile):

autorandr --default mobile

Ora che autorandr è tutto configurato, è possibile automatizzare il processo installando un pacchetto che eseguirà il polling per i display collegati e verrà eseguito autorandr --changeal rilevamento. Sì, so di udev e puoi configurarlo se funziona per te, ma nei miei test udev non ha funzionato per il mio hdmi in modo coerente. Funzionava solo 1 su ogni 20 prese / disconnesse o giù di lì, e talvolta si fermava del tutto.

Scarica l'ultimo .deb da qui: https://github.com/nalipaz/poll-xrandr/releases/ quindi installa con

dpkg -i [file]

Molto probabilmente è necessario eseguire più attività al completamento di autorandr --change, autorandr consente l'inserimento di questi comandi in un file chiamato ~ / .autorandr / postswitch. Fai come segue:

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

Ora modifica il file postswitch per avere qualcosa di simile al seguente:

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

Inoltre, probabilmente vorrai aggiungere autorandr e poll-xrandr alle tue startup, qualcosa come i seguenti due comandi:

autorandr --change &
poll-xrandr &

Scollega o collega un monitor e guarda la magia!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.