it-swarm-es.tech

Una herramienta para aplicar automáticamente la configuración de RandR cuando se conecta una pantalla externa

¿Existe alguna herramienta que le permita a uno:

  • recuerde la configuración actual de RandR (posición, orientación, resolución, etc.) por monitor,
  • ¿Aplicar automáticamente la última configuración válida conocida tan pronto como se enchufa la pantalla, sin necesidad de jugar con applets o xrandr (1)?

Las configuraciones tendrían que aplicarse por usuario, por pantalla.

Si no existe tal herramienta en la naturaleza, me gustaría armar una yo mismo, pero por lo que puedo ver, no hay forma de saber que se ha enchufado un monitor. ¿Tengo que sondear con xrandr -q de vez en cuando para descubrir que una salida estaba conectada o desconectada, ¿o hay una manera más eficiente de hacerlo? ¿Puede udev estar sintonizado para hacer exactamente eso?

58

Estoy usando esta secuencia de comandos simple (casera) que sigue sondeando RandR y cambia entre LVDS1 y VGA1 cuando VGA se conecta/desconecta. (Para [~ # ~] hdmi [~ # ~] salidas, en el siguiente archivo de script, cambie todos los VGA1 a HDMI1)

Es una solución sucia, pero funciona bien.

Está personalizado para mi configuración: lo más probable es que necesite cambiar los nombres de salida de RandR (LVDS1 y VGA1) y a diferencia de mí probablemente estará bien con su modo predeterminado RandR para 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

Pasos completos:

  1. Poner el script anterior (homemadeMonitor.sh) en su directorio preferido

  2. Haga que el archivo .sh sea ejecutable escribiendo el siguiente comando en la terminal

    chmod +x homemadeMonitor.sh

  3. Ejecute el archivo .sh

    ./homemadeMonitor.sh

20
peoro

Respondiendo a la parte "[a] de decir que un monitor ha sido enchufado" parte de la pregunta:

El soporte todavía varía bastante, pero con los núcleos recientes hay algún soporte para generar eventos udev cuando ocurre un hotplug de pantalla. Con el kernel 2.6.38 y el hardware ATI X1400, obtengo un evento la primera vez que conecto una pantalla VGA, pero no hay eventos en las desconexiones o reconexiones posteriores de la pantalla. El hardware Intel puede tener un mejor soporte. El controlador propietario de NVIDIA actualmente no es compatible con KMS; No he intentado buscar eventos de conexión en caliente en el hardware de NVIDIA, pero dudo que funcione.

Si quieres experimentar con udev, puedes probar los siguientes pasos:

  • actualizar al kernel más nuevo
  • asegúrese de que la configuración del modo kernel (KMS) esté habilitada. Si está habilitado, debe informarse en la salida del kernel. El mío dice [drm] radeon kernel modesetting enabled y [drm] initializing kernel modesetting
  • correr udevadm monitor --property y vea si se informan eventos cuando (des) conecta pantallas

Si está recibiendo eventos udev en hotplug de pantalla, puede activar un script con una regla udev como:

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

Nota: Esto ¡no funcionará si usa una GPU nVIDIA con el controlador binario propietario, ya que no usa KMS. Usted ¡no obtendrá cualquier evento udev.

21
Andy

Con respecto a una herramienta que puede almacenar perfiles de configuración de monitor por usuario y por pantalla, autorandr hará exactamente eso.

Mi laptop tiene una tarjeta NVIDIA, así que uso el back-end de disper en lugar de xrandr. Autorandr usará disper como back-end para administrar sus monitores si lo llama como autodisper. Sin embargo, para el resto de esta publicación, me referiré a ella como autorandr por coherencia.

Puede guardar perfiles con autorandr --save profile_name. Ejecutar autorandr por sí solo le dará una lista de perfiles e identificará cuál se detecta como la configuración actual.

Por ejemplo:

$ autorandr
laptop
syncmaster19 (detected)

Puede indicarle que cargue automáticamente el perfil apropiado para la configuración actual con autorandr --change. Este comando, junto con una regla udev para ejecutarlo cuando está conectado en caliente, haría lo que solicitó.

Como precaución adicional he agregado --default laptop a ese comando, que lo hará predeterminado a la pantalla de la computadora portátil si no hay un perfil guardado que coincida con la configuración actual. Entonces, el comando completo que uso para cambiar de pantalla es:

autorandr --change --default laptop

Desafortunadamente, mi máquina no da salida de udev cuando conecto mi monitor en caliente. Estoy usando los controladores propietarios de NVIDIA, así que eso no es sorprendente. Así que lo he vinculado a la tecla XF68Display (Fn-F8) por ahora, que es casi tan bueno.

19
Jack Senechal

Usé la regla de udev sugerida anteriormente junto con un script de Shell que se parece

#!/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 es esencial, así como la exportación DISPLAY, puede usar echo $DISPLAY para ver a qué número es igual. Utilizar xrandr -q para ver los monitores externos que tiene. La última declaración es solo para asegurarse de que nunca esté atascado sin una pantalla.

7
Cappie

Un pequeño programa que espera que el servidor X le notifique sobre la configuración cambiada del monitor, y luego ejecuta un comando dado (por ejemplo, el autorandr mencionado en otra respuesta) está disponible en: https: // bitbucket .org/portix/srandrd/overview

Esta parece ser una solución más limpia que usar udev (donde debe preocuparse por encontrar el servidor X correcto, etc.)

6
Joachim Breitner

Si debe hacer que detecte automáticamente la pantalla cuando está enchufado, parece que la solución más limpia es agregar una regla UDEV para ejecutar un script que contenga sus comandos xrandr. Aquí hay un ejemplo de la solución de un usuario 1 :

Monitorear (salida) eventos UDEV con udevadm
Este paso será el más importante para cada usuario. Correr udevadm monitor --environment --udev. Luego conecte su cable HDMI.

Regla UDEV
Basado en el resultado del comando anterior, el usuario creó esta regla UDEV en /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"

Tenga en cuenta las variables de entorno utilizadas para que xrandr se ejecute bajo el perfil de usuario.

script xrandr hotplug_monitor.sh

Es posible que desee ajustar las opciones de xrandr para satisfacer sus necesidades.

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

Para aquellos que, por cualquier razón, no desean tomar la ruta de conexión en caliente, aún es posible no sondear dentro de un script usando inotifywait:

 #!/bin/bash 
 
 SCREEN_LEFT = DP2 
 SCREEN_RIGHT = eDP1 
 START_DELAY = 5 
 
 renice +19 $$>/dev/null 
 
 sleep $ START_DELAY 
 
 OLD_DUAL = "dummy" 
 
 mientras [ 1]; do 
 DUAL = $ (cat /sys/class/drm/card0-DP-2/status)[.____.font>
 if ["$ OLD_DUAL"! = "$ DUAL"]; entonces 
 if ["$ DUAL" == "conectado"]; luego 
 echo 'Configuración de monitor dual' 
 xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT 
 Else 
 Echo 'Configuración de monitor único' 
 Xrandr --auto 
 Fi 
 
 OLD_DUAL = "$ DUAL" 
 fi 
 
 inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null 
 done 
 

Las encuestas con xrandr dieron serios problemas de uso en mi nueva computadora portátil (el mouse se detendría periódicamente).

3
Balzola

Para simplificar en Xfce, por ejemplo, instale "arandr", que debería estar disponible en sus paquetes de distribución. Configure su pantalla usando "arandr" y luego guárdela como "displayLayout" por ejemplo. Arandr debería agregarle la extensión ".sh" para que pueda usarse directamente en "function connect ()" como está escrito en el script "hotplug_monitor.sh" mencionado por iyrin anteriormente, por ejemplo:

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

Para usar el mecanismo de desconexión, agregue en la parte superior de la secuencia de comandos justo debajo de "#!/Bin/bash" de esta manera:

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

xrandr detectará la pantalla y pasará la salida a awk que la filtrará en función de la expresión regular "conectado" seguido de un dígito que, en esencia, es lo que queremos. En mi opinión, no es necesario hacer coincidir la resolución exacta en la expresión regular porque la pantalla principal se informa como "primaria conectada" seguida de un número, es decir, la resolución. Entonces awk "print $ 1" imprimirá solo la primera columna, que es el nombre del monitor externo en este caso y se almacenará en la variable PLUGGED_EXTERNAL. A continuación, en lugar del nombre para mostrar fijo "HDMI1" en el script, $ PLUGGED_EXTERNAL se puede usar así:

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

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

Supongo que las personas que miran esta pregunta no son aquellas que quieren usar GNOME, y las que usan GNOME no tendrían que mirar esta pregunta, sino en aras de la exhaustividad:

GNOME tiene esta funcionalidad incorporada. Si cambia la configuración a través de gnome-control-center, gnome-settings-daemon lo recuerda (en .config/monitors.xml) y lo aplica automáticamente cuando se conecta o desconecta un monitor.

Lamentablemente, la configuración en el archivo monitor.xml no está bien documentada. Ver pregunta aquí . Las herramientas de visualización de gnomos tampoco tienen medios para configurar la panorámica, la escala por monitor y no hacen alejamiento. Como muchas personas usan una pantalla de computadora portátil HiDPI junto con una pantalla DPI estándar, las herramientas no son suficientes para obtener una solución viable.

He visto esto mencionado como un elemento de hoja de ruta para Wayland aunque, cuando finalmente llegue, podríamos ver una solución para los problemas mencionados. Hasta entonces, en Gnome, acabo de ejecutar un script de inicio después de un retraso para configurar xrandr manualmente.

1
Joachim Breitner

Cuando utilicé la solución de peoro, obtuve un resultado adicional de xrandr, así que utilicé la opción -c para grep que cuenta el número de coincidencias. Lo adapté para HDMI y también agregué un interruptor de 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

Editando mi respuesta para simplificar la configuración.

Instale autorandr para automatizar el diseño de pantalla en xrandr, tome el último .deb de https://github.com/nalipaz/autorandr/releases y ejecute:

dpkg -i [file]

Configurar autorreferencia con diseños de pantalla almacenados

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

Como ejemplo, en mi computadora portátil sin ningún monitor conectado, configuré arandr de la manera que lo quería, luego ejecuté:

autorandr --save mobile

Luego enchufé mi hdmi y volví a configurar Arandr, luego ejecuté:

autorandr --save docked

Después de configurar cada uno de sus diseños, puede ejecutar (reemplace 'mobile' con el nombre favorito anterior, usé mobile):

autorandr --default mobile

Ahora que la configuración automática está configurada, puede automatizar el proceso instalando un paquete que sondeará las pantallas conectadas y ejecutará autorandr --change tras la detección. Sí, sé sobre udev y puedes configurarlo si funciona para ti, pero en mis pruebas, udev no funcionó para mi hdmi de manera consistente. Solo funcionó 1 de cada 20 enchufes/desenchufes más o menos, y a veces simplemente se detuvo por completo.

Descargue el último .deb desde aquí: https://github.com/nalipaz/poll-xrandr/releases/ luego instálelo con

dpkg -i [file]

Probablemente sea necesario que ejecute más tareas al completar autorandr --change, autorandr permite que estos comandos se inserten en un archivo llamado ~/.autorandr/postswitch. Haz lo siguiente:

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

Ahora edite el archivo postswitch para que tenga algo similar a lo siguiente:

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

Además, es probable que desee agregar autorandr y poll-xrandr a sus startups, algo así como los siguientes dos comandos:

autorandr --change &
poll-xrandr &

¡Desenchufa o conecta un monitor y mira la magia!

0
nicholas.alipaz