Una herramienta para aplicar automáticamente la configuración RandR cuando la pantalla externa está conectada


54

¿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 conecte 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 decir 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 forma más eficiente de hacerlo? ¿Puede udev estar sintonizado para hacer exactamente eso?


¿Está seguro de que no hay forma de saber que se ha enchufado un monitor con su tarjeta? Intente ejecutar udevadm monitor --propertydesde el terminal y enchufar el monitor. Con mi tarjeta, veo un evento cuando está enchufado. Puede usar una regla + RUN en udev y algunas secuencias de comandos bash para obtener lo que desea. Sin embargo, no estoy seguro de cómo podría implementar esto por usuario utilizando udev.
Steven D

@ Steven: Tu comentario debería ser una respuesta. No es una respuesta completa, pero hace un progreso significativo. Si udev ve un evento de hardware, debe notificar a hal que envía un evento dbus que puede verse por código de usuario.
Gilles 'SO- deja de ser malvado'

Respuestas:


19

Estoy usando este script simple (casero) que sigue sondeando RandR y cambia entre LVDS1 y VGA1 cuando VGA se conecta / desconecta. (Para salidas HDMI , en el siguiente archivo de script, cambie todo VGA1a 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 ( LVDS1y VGA1) y, a diferencia de mí , probablemente estará bien con su modo predeterminado de 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. Abra la Terminal presionando Ctrl+Alt+t
  2. Navegue a una buena ubicación para crear y almacenar el script de shell de cambio automático. Ejemplo

    cd ./Desktop/

  3. Cree y edite el archivo .sh con su editor de texto deseado (aquí, usé pluma. Puede probar nano, vim, etc.). Nómbralo a tu conveniencia. Ejemplo

    sudo pluma homemadeMonitor.sh

  4. Edite el archivo y copie y pegue todo desde el script mencionado anteriormente (el que tiene #! / Bin / bash)

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

    sudo chmod +x homemadeMonitor.sh

  6. Ejecute el archivo .sh

    ./homemadeMonitor.sh


Buen guion! Gracias, necesitaba algo como esto. Acabo de copiarlo y configurarlo para que se ejecute automáticamente. ¡Gracias!
Linuxios

21

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 de 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 enabledy[drm] initializing kernel modesetting
  • ejecutar udevadm monitor --propertyy ver 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 obtener ningún evento udev.


19

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

Mi computadora portátil tiene una tarjeta NVIDIA, por lo que uso el back-end disper en lugar de xrandr: http://willem.engen.nl/projects/disper/ . 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 autorandrpor coherencia.

Puede guardar perfiles con autorandr --save profile_name. Ejecutar autorandrsolo 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, agregué --default laptopese comando, que lo hará predeterminado para 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. Por lo tanto, lo he vinculado a la tecla XF68Display (Fn-F8) por ahora, que es casi tan bueno.


1
autorandr fue una pérdida de tiempo, mal documentado, parpadeos aleatorios del monitor, sin instrucciones de instalación / desinstalación. Podría resolverlo usandoudev
Leo Gallucci

55
Por si acaso, hay una buena bifurcación reescrita en Python de autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs

7

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

#!/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 $DISPLAYpara ver a qué número es igual. Use xrandr -qpara ver los monitores externos que tiene. La última declaración es solo para asegurarse de que nunca esté atascado sin una pantalla.


6

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 autorandrmencionado 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.)


5

Si debe hacer que detecte automáticamente la pantalla cuando se enchufa, 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 1 de un usuario :

Monitoree (salida) eventos UDEV conudevadm
Este paso será el más importante para cada usuario. Ejecutar udevadm monitor --environment --udev. Luego conecta tu cable HDMI.

Regla UDEV
Según 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

3

Para aquellos que, por cualquier razón, no quieren 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

dormir $ START_DELAY

OLD_DUAL = "ficticio"

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

    if ["$ OLD_DUAL"! = "$ DUAL"]; entonces
        si ["$ DUAL" == "conectado"]; entonces
            echo 'Configuración de monitor dual'
            xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal --abajo $ SCREEN_LEFT
        más
            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
hecho

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


1

Cuando utilicé la solución de peoro, obtuve algunos resultados adicionales 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

Supongo que las personas que miran esta pregunta no son las 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 (dentro .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.

Sin embargo, he visto esto mencionado como un elemento de hoja de ruta para Wayland, así que 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

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 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

0

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 forma en que lo quiero y 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 marca automática está configurada, puede automatizar el proceso instalando un paquete que sondeará las pantallas conectadas y se ejecutará autorandr --changetras 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/ e instálelo con

dpkg -i [file]

Es probable que sea necesario que ejecute más tareas al finalizar 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!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.