web-dev-qa-db-fra.com

Un outil pour appliquer automatiquement la configuration RandR lorsqu'un écran externe est branché

existe-t-il un outil qui permet de:

  • mémoriser la configuration actuelle de RandR (position, orientation, résolution, etc.) par moniteur,
  • appliquer automatiquement la dernière bonne configuration connue dès que l'écran est branché, sans avoir besoin de fouiner avec des applets ou xrandr (1)?

Les configurations devraient être appliquées par utilisateur et par écran.

S'il n'y a pas un tel outil dans la nature, j'aimerais en créer un moi-même, mais autant que je sache, il n'y a aucun moyen de dire qu'un moniteur a été branché. Dois-je interroger avec xrandr -q de temps en temps pour comprendre qu'une sortie a été connectée ou déconnectée, ou existe-t-il un moyen plus efficace de le faire? Udev peut-il être réglé pour faire exactement cela?

58
Yaroslav Fedevych

J'utilise ce script simple (fait maison) qui continue d'interroger RandR et bascule entre LVDS1 et VGA1 lorsque VGA est connecté/déconnecté. (Pour les sorties [~ # ~] hdmi [~ # ~] , dans le fichier de script suivant, modifiez toutes les VGA1 à HDMI1)

C'est une sale solution, mais ça marche très bien.

Il est personnalisé pour ma configuration: vous devrez probablement modifier les noms de sortie RandR (LVDS1 et VGA1) et contrairement à moi vous serez probablement d'accord avec votre mode par défaut RandR pour 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

Étapes complètes:

  1. Mettre au-dessus du script (homemadeMonitor.sh) dans votre répertoire préféré

  2. Rendez le fichier .sh exécutable en tapant la commande suivante dans le terminal

    chmod +x homemadeMonitor.sh

  3. Exécutez le fichier .sh

    ./homemadeMonitor.sh

20
peoro

Répondant à la "[une] façon de dire qu'un moniteur a été branché" une partie de la question:

La prise en charge varie encore un peu, mais avec les noyaux récents, il existe une certaine prise en charge pour la génération d'événements udev lorsqu'un hotplug d'affichage se produit. Avec le noyau 2.6.38 et le matériel ATI X1400, j'obtiens un événement la première fois que je connecte un écran VGA mais aucun événement lors des déconnexions ou reconnexions ultérieures de l'écran. Le matériel Intel peut avoir une meilleure prise en charge. Le pilote propriétaire NVIDIA ne prend actuellement pas en charge KMS; Je n'ai pas essayé de rechercher des événements hotplug sur du matériel NVIDIA, mais je doute que cela fonctionne.

Si vous souhaitez expérimenter avec udev, vous pouvez essayer les étapes suivantes:

  • mise à jour vers le dernier noyau
  • assurez-vous que le paramètre du mode noyau (KMS) est activé. S'il est activé, il doit être signalé dans la sortie de votre noyau. Le mien dit [drm] radeon kernel modesetting enabled et [drm] initializing kernel modesetting
  • courir udevadm monitor --property et voir si des événements sont signalés lorsque vous vous (déconnectez) affichez

Si vous obtenez des événements udev sur l'affichage hotplug, vous pouvez déclencher un script avec une règle udev comme:

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

Remarque: Cela fonctionnera pas si vous utilisez un GPU nVIDIA avec le pilote binaire propriétaire, car il n'utilise pas KMS. Vous pas obtiendrez tous les événements udev.

21
Andy

Concernant un outil qui peut stocker des profils de configuration de moniteur par utilisateur et par affichage, autorandr fera exactement cela.

Mon ordinateur portable a une carte NVIDIA, donc j'utilise le backend disper au lieu de xrandr. Autorandr utilisera disper comme backend pour gérer vos moniteurs si vous l'appelez comme autodisper. Pour le reste de cet article, je vais l'appeler autorandr pour des raisons de cohérence.

Vous pouvez enregistrer des profils avec autorandr --save profile_name. L'exécution de autorandr seule vous donnera alors une liste de profils et identifiera celui qui est détecté comme configuration actuelle.

Par exemple:

$ autorandr
laptop
syncmaster19 (detected)

Vous pouvez lui dire de charger automatiquement le profil approprié pour la configuration actuelle avec autorandr --change. Cette commande, associée à une règle udev pour l'exécuter lorsqu'elle est branchée à chaud, ferait ce que vous avez demandé.

Par mesure de précaution supplémentaire, j'ai ajouté --default laptop à cette commande, ce qui rendra l'affichage par défaut de l'ordinateur portable s'il n'y a pas de profil enregistré qui correspond à la configuration actuelle. Donc, la commande complète que j'utilise pour changer d'écran est:

autorandr --change --default laptop

Malheureusement, ma machine ne donne aucune sortie udev lorsque je branche mon moniteur à chaud. J'utilise les pilotes propriétaires NVIDIA, ce n'est donc pas surprenant. Je l'ai donc lié à la touche XF68Display (Fn-F8) pour l'instant, ce qui est presque aussi bon.

19
Jack Senechal

J'ai utilisé la règle udev suggérée ci-dessus avec un script Shell qui ressemble à

#!/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 partie Xauthority est essentielle ainsi que l'export DISPLAY, vous pouvez utiliser echo $DISPLAY pour voir à quel nombre il est égal. Utilisation xrandr -q pour voir les moniteurs externes dont vous disposez. La dernière instruction else est juste pour vous assurer que vous n'êtes jamais coincé sans écran.

7
Cappie

Un petit programme qui attend que le serveur X l'informe de la modification de la configuration du moniteur, puis exécute une commande donnée (par exemple, le autorandr mentionné dans une autre réponse) est disponible sur: https: // bitbucket .org/portix/srandrd/overview

Cela semble être une solution plus propre que l'utilisation de udev (où vous devez vous soucier de trouver le bon serveur X, etc.)

6
Joachim Breitner

Si vous devez le faire détecter automatiquement l'affichage lorsqu'il est branché, il semble que la solution la plus propre consiste à ajouter une règle UDEV pour exécuter un script contenant vos commandes xrandr. Voici un exemple de la solution d'un utilisateur 1 :

Surveiller (sortie) les événements UDEV avec udevadm
Cette étape sera la plus importante pour chaque utilisateur. Courir udevadm monitor --environment --udev. Connectez ensuite votre câble HDMI.

Règle UDEV
Sur la base de la sortie de la commande ci-dessus, l'utilisateur a créé cette règle UDEV à /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"

Notez les variables d'environnement utilisées pour que xrandr soit exécuté sous le profil utilisateur.

Script xrandr hotplug_monitor.sh

Vous souhaiterez peut-être ajuster les options de xrandr en fonction de vos besoins.

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

Pour ceux qui, pour une raison quelconque, ne veulent pas emprunter la route hotplug, il est toujours possible de ne pas interroger dans un script en utilisant inotifywait:

 #!/bin/bash 
 
 SCREEN_LEFT = DP2 
 SCREEN_RIGHT = eDP1 
 START_DELAY = 5 
 
 renice +19 $$>/dev/null 
 
 sleep $ START_DELAY 
 
 OLD_DUAL = "factice" 
 
 pendant que [ 1 ]; do 
 DUAL = $ (cat /sys/class/drm/card0-DP-2/status)[.____. diplomatique .____.] if ["$ OLD_DUAL"! = "$ DUAL"]; alors 
 si ["$ DUAL" == "connecté"]; puis 
 echo 'Configuration double moniteur' 
 xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT 
 Else 
 Echo 'Configuration moniteur unique' 
 Xrandr --auto 
 Fi 
 
 OLD_DUAL = "$ DUAL" 
 fi 
 
 inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null 
 done 
 

L'interrogation avec xrandr a donné de sérieux problèmes d'utilisation sur mon tout nouvel ordinateur portable (la souris se bloquait périodiquement).

3
Balzola

Pour simplifier dans Xfce par exemple, veuillez installer "arandr" qui devrait être disponible dans vos packages de distribution. Configurez votre affichage en utilisant "arandr" puis enregistrez-le sous "displayLayout" par exemple. Arandr devrait ajouter pour vous l'extension ".sh" afin qu'elle puisse être directement utilisée dans "function connect ()" comme écrit dans le script "hotplug_monitor.sh" mentionné par iyrin ci-dessus, par exemple:

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

Pour utiliser le mécanisme de déconnexion, ajoutez en haut du script juste en dessous de "#!/Bin/bash" comme ceci:

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

xrandr détectera l'affichage et passera la sortie à awk qui le filtrera en fonction de l'expression régulière "connecté" suivie d'un chiffre qui est essentiellement ce que nous voulons. À mon avis, il n'est pas nécessaire de faire correspondre la résolution exacte dans l'expression régulière car l'affichage principal est signalé comme "primaire connecté" suivi du nombre, c'est-à-dire de la résolution. Ensuite, awk "print $ 1" n'imprimera que la première colonne qui est le nom du moniteur externe dans ce cas et cela sera stocké dans la variable PLUGGED_EXTERNAL. Suivant au lieu du nom d'affichage fixe "HDMI1" dans le script $ PLUGGED_EXTERNAL peut être utilisé comme ceci:

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

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

Je suppose que les personnes qui regardent cette question ne sont pas celles qui veulent utiliser GNOME, et celles qui utilisent GNOME n'auraient pas à regarder cette question, mais dans un souci d'exhaustivité:

GNOME a cette fonctionnalité intégrée. Si vous modifiez la configuration via gnome-control-center, gnome-settings-daemon s'en souvient (dans .config/monitors.xml) et l'applique automatiquement lorsqu'un moniteur est branché ou débranché.

Malheureusement, la configuration du fichier moniteurs.xml n'est pas bien documentée. Voir question ici . L'outil d'affichage gnome n'a également aucun moyen de configurer le panoramique, la mise à l'échelle par moniteur et il ne fait pas de zoom arrière. Comme beaucoup de gens utilisent un écran d'ordinateur portable HiDPI avec un écran DPI ordinaire, les outils ne sont pas suffisants pour obtenir une solution viable.

J'ai vu cela mentionné comme un élément de la feuille de route pour Wayland bien que quand cela arrivera finalement, nous pourrions voir un correctif pour les problèmes mentionnés. Jusque-là, sur Gnome, je lance juste un script de démarrage après un délai pour configurer manuellement xrandr.

1
Joachim Breitner

Lors de l'utilisation de la solution de peoro, j'ai obtenu une sortie supplémentaire de xrandr, j'ai donc utilisé l'option -c pour grep qui compte le nombre de correspondances. Je l'ai adapté pour HDMI et j'ai également ajouté un commutateur 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
Aaros

Modification de ma réponse pour la rendre plus simple à configurer.

Installez autorandr pour automatiser la disposition de l'écran dans xrandr, récupérez le dernier .deb de https://github.com/nalipaz/autorandr/releases et exécutez:

dpkg -i [file]

Configurer autorandr avec des dispositions d'écran enregistrées

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

Par exemple, sur mon ordinateur portable sans aucun moniteur branché, j'ai configuré arandr comme je le veux, puis j'ai exécuté:

autorandr --save mobile

Ensuite, j'ai branché mon HDMI et mon arandr reconfiguré, puis j'ai exécuté:

autorandr --save docked

Après avoir configuré chacune de vos mises en page, vous pouvez exécuter (remplacer "mobile" par le nom préféré précédent, j'ai utilisé mobile):

autorandr --default mobile

Maintenant que autorandr est entièrement configuré, vous pouvez automatiser le processus en installant un package qui interrogera les écrans connectés et exécutera autorandr --change lors de la détection. Oui, je connais udev et vous pouvez le configurer si cela fonctionne pour vous, mais lors de mes tests, udev n'a pas fonctionné de manière cohérente pour mon hdmi. Cela ne fonctionnait que 1 sur 20 plugs/unplugs ou plus, et parfois, il s'arrêtait complètement.

Téléchargez le dernier .deb d'ici: https://github.com/nalipaz/poll-xrandr/releases/ puis installez avec

dpkg -i [file]

Il est très probablement nécessaire que vous exécutiez plus de tâches à la fin de autorandr --change, autorandr permet d'insérer ces commandes dans un fichier appelé ~/.autorandr/postswitch. Procédez comme suit:

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

Modifiez maintenant le fichier postswitch pour qu'il ressemble à ce qui suit:

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

De plus, vous voudrez probablement ajouter autorandr et poll-xrandr à vos startups, quelque chose comme les deux commandes suivantes:

autorandr --change &
poll-xrandr &

Débranchez ou branchez un moniteur et regardez la magie!

0
nicholas.alipaz