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

54

Existe-t-il un outil permettant de:

  • mémoriser la configuration actuelle du RandR (position, orientation, résolution, etc.) sur chaque moniteur,
  • appliquer automatiquement la dernière bonne configuration connue dès que l’affichage est branché, sans qu’il soit nécessaire de jouer avec des applets ou xrandr (1)?

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

S'il n'y a pas un tel outil dans la nature, j'aimerais en créer un moi-même, mais pour autant que je sache, il n'y a aucun moyen de savoir qu'un moniteur a été branché. Dois-je interroger avec xrandr -q de temps en temps pour déterminer 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?

Yaroslav Fedevych
la source
Etes-vous sûr qu'il n'y a aucun moyen de savoir qu'un moniteur a été branché avec votre carte. Essayez de lancer udevadm monitor --propertydepuis le terminal et de brancher le moniteur. Avec ma carte, je vois un événement lorsqu’elle est branchée. Vous pourrez peut-être utiliser une règle + RUN dans udev et quelques scripts bash pour obtenir ce que vous voulez. Cependant, je ne sais pas comment vous pourriez mettre en œuvre cela par utilisateur à l’aide de udev.
Steven D
@ Steven: Votre commentaire devrait être une réponse. Ce n'est pas une réponse complète, mais cela fait des progrès significatifs. Si udev voit un événement matériel, il doit notifier hal qui envoie un événement dbus visible par code utilisateur.
Gilles 'SO- arrête d'être méchant'

Réponses:

19

J'utilise ce script simple (maison) qui continue à interroger RandR et bascule entre LVDS1 et VGA1 lorsque le VGA est connecté / déconnecté. (Pour les sorties HDMI , dans le fichier de script suivant, remplacez tout VGA1par HDMI1)

C'est une solution sale, mais cela fonctionne très bien.

Il est personnalisé pour ma configuration: vous aurez probablement besoin de changer les noms des sorties RandR ( LVDS1et VGA1) et contrairement à moi, vous utiliserez probablement le 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. Ouvrir le terminal en appuyant sur Ctrl+Alt+t
  2. Accédez au bon emplacement pour créer et stocker le script shell à commutation automatique. Exemple

    cd ./Desktop/

  3. Créez et éditez le fichier .sh avec l'éditeur de texte de votre choix (ici, j'ai utilisé pluma. Vous pouvez essayer nano, vim, etc.). Nommez-le à votre convenance. Exemple

    sudo pluma homemadeMonitor.sh

  4. Editez le fichier et copiez-collez le contenu du script mentionné ci-dessus (celui avec #! / Bin / bash)

  5. Rendre le fichier .sh exécutable en tapant la commande suivante dans le terminal

    sudo chmod +x homemadeMonitor.sh

  6. Exécuter le fichier .sh

    ./homemadeMonitor.sh

peoro
la source
Bon scénario! Merci, j'avais besoin de quelque chose comme ça. Je viens de le copier et de le configurer pour qu'il s'exécute automatiquement. Merci!
Linuxios
21

Répondant à la partie "de la manière" de dire qu'un moniteur a été branché ":

La prise en charge varie toujours un peu, mais avec les noyaux récents, il est possible de générer des événements udev lorsqu’un hotplug d’affichage se produit. Avec le noyau 2.6.38 et le matériel ATI X1400, je reçois un événement la première fois que je connecte un écran VGA, mais aucun événement lors des déconnexions ou des reconnexions ultérieures de l'écran. Le matériel Intel peut avoir un meilleur support. 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 voulez expérimenter avec udev, vous pouvez essayer les étapes suivantes:

  • mise à jour vers le nouveau noyau
  • assurez-vous que le paramètre de mode noyau (KMS) est activé. Si activé, cela devrait être rapporté dans la sortie de votre noyau. Le mien dit [drm] radeon kernel modesetting enabledet[drm] initializing kernel modesetting
  • exécuter udevadm monitor --propertyet voir si des événements sont rapportés lorsque vous (déconnectez) les affichages

Si vous obtenez des événements udev sur display hotplug, vous pouvez déclencher un script avec une règle udev telle que:

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

Remarque: cela ne fonctionnera pas si vous utilisez un GPU nVIDIA avec le pilote binaire propriétaire, car il n'utilise pas KMS. Vous n'obtenir aucun événement udev.

Andy
la source
19

En ce qui concerne un outil pouvant stocker des profils de configuration de moniteur utilisateur par utilisateur et par affichage, autorandr fera exactement cela. https://github.com/wertarbyte/autorandr .

Mon ordinateur portable est équipé d’une carte NVIDIA, j’utilise donc le serveur principal au lieu de xrandr: http://willem.engen.nl/projects/disper/ . Autorandr utilisera disper comme serveur pour gérer vos moniteurs si vous l'appelez comme autodisper. Pour le reste de cet article, j'y reviendrai par souci de autorandrcohérence.

Vous pouvez enregistrer des profils avec autorandr --save profile_name. Une exécution autorandrpar elle-même 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 indiquer 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 connectée à chaud, ferait ce que vous auriez demandé.

Par précaution supplémentaire, j’ai ajouté --default laptopà cette commande, qui sera modifiée par défaut sur l’affichage de l’ordinateur portable si aucun profil enregistré ne correspond à la configuration actuelle. Donc, la commande complète que j'utilise pour changer d'affichage est:

autorandr --change --default laptop

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

Jack Senechal
la source
1
autorandr était une perte de temps, une mauvaise documentation, des moniteurs aléatoires, aucune instruction d'installation / de désinstallation. Pourrait le résoudre en utilisantudev
Leo Gallucci
5
Juste au cas où, il y a une belle fourche réécrite dans Python maintenue de autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs
7

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'exportation DISPLAY, vous pouvez utiliser echo $DISPLAYpour voir à quel numéro correspond. Utilisez xrandr -qpour voir les moniteurs externes que vous avez. La dernière déclaration consiste simplement à vous assurer que vous n'êtes jamais bloqué sans écran.

Cappie
la source
6

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, la autorandrréponse mentionnée dans une autre réponse) est disponible à l' adresse : https://bitbucket.org/portix/srandrd/overview

Cela semble être une solution plus propre que d’utiliser udev(où vous devez vous préoccuper de trouver le bon serveur X, etc.)

Joachim Breitner
la source
5

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 tiré de la solution d'un utilisateur 1 :

Surveiller (sortir) les événements UDEV avecudevadm
Cette étape sera primordiale pour chaque utilisateur. Courez udevadm monitor --environment --udev. Ensuite, connectez votre câble HDMI.

Règle UDEV
En fonction du résultat de la commande ci-dessus, l'utilisateur a créé cette règle UDEV à l'adresse /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 afin que xrandr soit exécuté sous le profil utilisateur.

xrandr script hotplug_monitor.sh

Vous voudrez peut-être ajuster les options de xrandr selon 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
Iyrin
la source
3

Pour ceux qui, pour une raison quelconque, ne veulent pas prendre la route hotplug, il est toujours possible de ne pas interroger dans un script à l'aide de inotifywait:

#! / bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

dormir $ START_DELAY

OLD_DUAL = "dummy"

tandis que [1]; faire
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if ["$ OLD_DUAL"! = "$ DUAL"]; ensuite
        if ["$ DUAL" == "connecté"]; ensuite
            echo 'Configuration double moniteur'
            xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal - ci-dessous $ SCREEN_LEFT
        autre
            echo 'Configuration d'un seul moniteur'
            xrandr --auto
        Fi

        OLD_DUAL = "$ DUAL"
    Fi

    inotifywait -q -e ferme / sys / classe / drm / card0-DP-2 / statut> / dev / null
terminé

Les sondages avec xrandr ont posé de sérieux problèmes d’utilisabilité sur mon tout nouvel ordinateur portable (la souris ralentissait périodiquement).

Balzola
la source
1

Lors de l'utilisation de la solution peoro, xrandr m'a donné une sortie supplémentaire. J'ai donc utilisé l'option -c pour grep qui compte le nombre de correspondances. Je l'ai adapté pour HDMI et 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
Aaros
la source
1

Je suppose que les personnes qui consultent cette question ne sont pas celles qui veulent utiliser GNOME, et celles qui utilisent GNOME n'auraient pas à se pencher sur cette question, mais dans un souci de complétude:

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

Malheureusement, la configuration dans le fichier moniteurs.xml n'est pas bien documentée. Voir la question ici . L’outil d’affichage gnome n’a pas non plus la possibilité de configurer le panoramique et la mise à l’échelle par moniteur et ne fait pas de zoom arrière. Comme de nombreuses personnes utilisent un écran d'ordinateur portable HiDPI avec un écran DPI standard, les outils ne suffisent pas pour obtenir une solution viable.

J’ai vu cela mentionné comme élément de la feuille de route pour Wayland, mais quand cela se produira, nous pourrons peut-être trouver une solution aux problèmes mentionnés. Jusque-là, sur Gnome, je viens d’exécuter un script de démarrage après un délai d’installation manuelle de xrandr.

Joachim Breitner
la source
1

Pour simplifier Xfce par exemple, installez "arandr" qui devrait être disponible dans vos paquets 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 indiqué 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 transmettra la sortie à awk qui le filtrera en fonction de l'expression régulière "connected" suivie d'un chiffre qui correspond essentiellement à ce que nous voulons. À mon avis, il n'est pas nécessaire de faire correspondre la résolution exacte dans une expression régulière car l'affichage principal est signalé comme "primaire connecté" suivi d'un nombre, c'est-à-dire d'une résolution. Ensuite, awk "print $ 1" n’imprimera que la première colonne, qui est le nom du moniteur externe dans ce cas, et 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 suit:

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

xrandr | grep "$PLUGGED_EXTERNAL connected" &> /dev/null && connect || disconnect
utilisateur180381
la source
0

Modification de ma réponse pour simplifier la configuration.

Installez autorandr pour automatiser la présentation de l’écran dans xrandr, récupérez le dernier fichier .deb à l’ adresse https://github.com/nalipaz/autorandr/releases et exécutez:

dpkg -i [file]

Configuration automatique avec les dispositions d'écran stockées

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

Par exemple, sur mon ordinateur portable sans aucun moniteur connecté, j'ai configuré mon ordinateur comme je le voulais, puis j'ai lancé:

autorandr --save mobile

Puis branché mon hdmi et arandr reconfiguré, puis a couru:

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 tout configuré, vous pouvez automatiser le processus en installant un paquet qui interrogera les écrans connectés et s'exécutera autorandr --changedès la détection. Oui, je connais udev et vous pouvez le configurer si cela fonctionne pour vous, mais dans mes tests, udev ne fonctionnait pas pour mon HDMI de manière cohérente. Cela ne fonctionnait qu’à un sur 20 bouchons / débranchements ou presque, et parfois il s’arrêtait complètement.

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

dpkg -i [file]

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

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

Maintenant, éditez le fichier postswitch pour avoir quelque chose de similaire au suivant:

#!/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 observez la magie!

nicholas.alipaz
la source