Uma ferramenta para aplicar automaticamente a configuração do RandR quando o monitor externo é conectado

54

existe uma ferramenta que permite:

  • lembre-se da configuração atual do RandR (posição, orientação, resolução etc.), por monitor,
  • aplicar automaticamente a última configuração válida assim que o monitor for conectado, sem a necessidade de mexer com applets ou xrandr (1)?

As configurações teriam que ser aplicadas por usuário, por exibição.

Se não houver essa ferramenta na natureza, eu gostaria de juntar uma, mas, até onde posso ver, não há como saber se um monitor foi conectado. Preciso pesquisar com xrandr -q de vez em quando para descobrir que uma saída foi conectada ou desconectada, ou existe uma maneira mais eficiente de fazer isso? O udev pode ser ajustado para fazer exatamente isso?

Yaroslav Fedevych
fonte
Tem certeza de que não há como saber se um monitor foi conectado à sua placa. Tente executar a udevadm monitor --propertypartir do terminal e conectar o monitor. Com o meu cartão, vejo um evento quando ele está conectado. Você pode usar uma regra + RUN no udev e alguns scripts do bash para obter o que deseja. No entanto, não tenho certeza de como você seria capaz de implementar isso por usuário usando o udev.
Steven D
@ Steven: Seu comentário deve ser uma resposta. Não é uma resposta completa, mas faz um progresso significativo. Se o udev vir um evento de hardware, ele deverá notificar hal, que envia um evento dbus que pode ser visto pelo código do usuário.
Gilles 'SO- stop be evil'

Respostas:

19

Estou usando esse script simples (caseiro) que mantém a pesquisa RandR e alterna entre LVDS1 e VGA1 quando o VGA é conectado / desconectado. (Para saídas HDMI , no arquivo de script a seguir, altere todas as opções VGA1para HDMI1)

É uma solução suja, mas está funcionando bem.

Ele é personalizado para a minha configuração: você provavelmente precisará alterar os nomes de saída do RandR ( LVDS1e VGA1) e, diferentemente de mim, provavelmente ficará bem com o modo padrão do 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

Etapas completas:

  1. Abra o Terminal pressionando Ctrl+Alt+t
  2. Navegue para um bom local para criar e armazenar o script de shell de comutação automática. Exemplo

    cd ./Desktop/

  3. Crie e edite o arquivo .sh com o editor de texto desejado (aqui, usei o pluma. Você pode experimentar o nano, vim, etc.). Nomeie-o para sua conveniência. Exemplo

    sudo pluma homemadeMonitor.sh

  4. Edite o arquivo e copie e cole tudo do script mencionado acima (aquele com #! / Bin / bash)

  5. Torne o arquivo .sh executável, digitando o seguinte comando no terminal

    sudo chmod +x homemadeMonitor.sh

  6. Execute o arquivo .sh

    ./homemadeMonitor.sh

peoro
fonte
Bom roteiro! Obrigado, eu precisava de algo assim. Apenas copiei e configurei para executar automaticamente. Obrigado!
Linuxios 31/01
21

Respondendo à parte "[a] para saber se um monitor foi conectado" parte da pergunta:

O suporte ainda varia bastante, mas com os kernels recentes, existe algum suporte para gerar eventos do udev quando ocorre um hotplug de exibição. Com o kernel 2.6.38 e o hardware ATI X1400, recebo um evento na primeira vez em que conecto um monitor VGA, mas não há eventos nas desconexões ou reconexões subsequentes do monitor. O hardware Intel pode ter um suporte melhor. O driver proprietário da NVIDIA atualmente não suporta KMS; Não tentei procurar eventos de hotplug no hardware da NVIDIA, mas duvido que funcionasse.

Se você quiser experimentar o udev, tente as seguintes etapas:

  • atualizar para o kernel mais recente
  • verifique se a configuração do modo kernel (KMS) está ativada. Se ativado, deve ser relatado na saída do seu kernel. Mina diz [drm] radeon kernel modesetting enablede[drm] initializing kernel modesetting
  • execute udevadm monitor --propertye veja se os eventos são relatados quando você (des) conecta os monitores

Se você estiver recebendo eventos do udev no hotplug de exibição, poderá disparar um script com uma regra do udev como:

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

Nota: Isso não funcionará se você usar uma GPU nVIDIA com o driver binário proprietário, pois ele não usa o KMS. Você não receberá nenhum evento do udev.

Andy
fonte
19

Em relação a uma ferramenta que pode armazenar perfis de configuração de monitor por usuário e por monitor, o autorandr fará exatamente isso. https://github.com/wertarbyte/autorandr .

Meu laptop possui uma placa NVIDIA, então eu uso o disper backend em vez do xrandr: http://willem.engen.nl/projects/disper/ . O Autorandr usará o disper como back-end para gerenciar seus monitores, se você chamá-lo como autodisper. Para o restante deste post, porém, vou me referir a ele como autorandrconsistência.

Você pode salvar perfis com autorandr --save profile_name. A execução autorandrpor si só fornecerá uma lista de perfis e identificará qual deles é detectado como a configuração atual.

Por exemplo:

$ autorandr
laptop
syncmaster19 (detected)

Você pode pedir para carregar automaticamente o perfil apropriado para a configuração atual autorandr --change. Este comando, emparelhado com uma regra do udev para executá-lo quando estiver com hotplug, faria o que você solicitou.

Como precaução adicional, acrescentei --default laptopesse comando, que o tornará padrão na tela do laptop se não houver um perfil salvo que corresponda à configuração atual. Portanto, o comando completo que eu uso para alternar as telas é:

autorandr --change --default laptop

Infelizmente, minha máquina não fornece nenhuma saída udev quando eu conecto meu monitor. Estou usando os drivers proprietários da NVIDIA, o que não é surpreendente. Então, vinculei-o à tecla XF68Display (Fn-F8) por enquanto, o que é quase tão bom.

Jack Senechal
fonte
11
O autorandr foi uma perda de tempo, mal documentado, pisca aleatoriamente no monitor, sem instruções de instalação / desinstalação. Poderia resolver isso usandoudev
Leo Gallucci
5
Apenas no caso, há uma boa mantida reescrito-in-Python garfo autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs
7

Eu usei a regra udev sugerida acima, juntamente com um script de shell que se parece com

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

A parte Xauthority é essencial, assim como a exportação DISPLAY. Você pode usar o eco $DISPLAYpara ver qual número é igual. Use xrandr -qpara ver os monitores externos que você possui. A última declaração else é apenas para garantir que você nunca fique preso sem uma exibição.

Cappie
fonte
6

Um pequeno programa que aguarda o servidor X notificá-lo sobre a configuração alterada do monitor e executa um determinado comando (por exemplo, o autorandrmencionado em outra resposta) está disponível em: https://bitbucket.org/portix/srandrd/overview

Esta parece ser uma solução mais limpa que a utilização udev(onde você precisa se preocupar em encontrar o servidor X certo etc.)

Joachim Breitner
fonte
5

Se você precisar que ele detecte automaticamente a tela quando estiver conectada, parece que a solução mais limpa é adicionar uma regra UDEV para executar um script contendo seus comandos xrandr. Aqui está um exemplo da solução 1 de um usuário :

Monitore (Udev) os eventos UDEV comudevadm
Esta etapa será mais importante para cada usuário. Corra udevadm monitor --environment --udev. Em seguida, conecte seu cabo HDMI.

Regra UDEV
Com base na saída do comando acima, o usuário criou esta regra UDEV em /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"

Observe as variáveis ​​de ambiente usadas para que o xrandr seja executado no perfil do usuário.

Script xrandr hotplug_monitor.sh

Convém ajustar as opções do xrandr para atender às suas necessidades.

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

Para quem, por qualquer motivo, não quiser seguir a rota de hotplug, ainda é possível não pesquisar em um script usando o inotifywait:

#! / bin / bash

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

dormir $ START_DELAY

OLD_DUAL = "fictício"

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

    if ["$ OLD_DUAL"! = "$ DUAL"]; então
        se ["$ DUAL" == "conectado"]; então
            eco 'Configuração do monitor duplo'
            xrandr - saída $ SCREEN_LEFT - automático - rotação normal --pos 0x0 - saída $ SCREEN_RIGHT - automático - rotação normal - abaixo $ SCREEN_LEFT
        outro
            eco 'Configuração de monitor único'
            xrandr --auto
        fi

        OLD_DUAL = "$ DUAL"
    fi

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

A pesquisa com o xrandr causou sérios problemas de usabilidade no meu novo laptop (o mouse parava periodicamente).

Balzola
fonte
1

Ao usar a solução peoro, obtive uma saída extra do xrandr, então usei a opção -c para grep, que conta o número de correspondências. Eu o adaptei para HDMI e adicionei um interruptor de áudio:

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

Acho que as pessoas que olham para essa pergunta não são aquelas que desejam usar o GNOME, e as que usam o GNOME não precisariam olhar para essa pergunta, mas no interesse da integridade:

O GNOME tem essa funcionalidade embutida. Se você alterar a configuração via gnome-control-center, o gnome-settings-daemon se lembra (in .config/monitors.xml) e a aplica automaticamente quando um monitor é conectado ou desconectado.

Infelizmente, a configuração no arquivo monitors.xml não está bem documentada. Veja a pergunta aqui . As ferramentas de exibição do gnome também não têm como configurar o panorama, a escala por monitor e não diminuem o zoom. Como muitas pessoas estão usando uma tela de laptop HiDPI juntamente com uma tela DPI normal, as ferramentas não são suficientes para obter uma solução viável.

Eu já vi isso mencionado como um item de roteiro para Wayland; portanto, quando finalmente chegar, poderemos ver uma correção para os problemas mencionados. Até então, no Gnome, acabei de executar um script de inicialização após um atraso para configurar o xrandr manualmente.

Joachim Breitner
fonte
1

Para simplificar no Xfce, por exemplo, instale "arandr", que deve estar disponível nos seus pacotes de distribuição. Configure sua exibição usando "arandr" e salve-a como "displayLayout", por exemplo. O Arandr deve adicionar para você a extensão ".sh" para que possa ser usada diretamente na "função connect ()" conforme escrita no script "hotplug_monitor.sh" mencionado por iyrin acima, por exemplo:

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

Para usar o mecanismo de desconexão, adicione na parte superior do script logo abaixo "#! / Bin / bash" da seguinte forma:

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

O xrandr detectará a exibição e passará a saída para o awk, que será filtrada com base na expressão regular "conectado", seguida de um dígito que, em essência, é o que queremos. Na minha opinião, não é necessário corresponder à resolução exata na expressão regular, porque a exibição primária é relatada como "primária conectada", seguida de número, ou seja, resolução. Em seguida, o awk "print $ 1" imprimirá apenas a primeira coluna, que é o nome do monitor externo nesse caso e será armazenada na variável PLUGGED_EXTERNAL. Em seguida, em vez do nome de exibição fixo "HDMI1" no script $ PLUGGED_EXTERNAL, pode ser usado assim:

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

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

Editando minha resposta para facilitar a configuração.

Instale o autorandr para automatizar o layout da tela no xrandr, pegue o .deb mais recente em https://github.com/nalipaz/autorandr/releases e execute:

dpkg -i [file]

Configurar autorandr com layouts de tela armazenados

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

Por exemplo, no meu laptop sem nenhum monitor conectado, eu configuro a maneira que quero e, em seguida, executei:

autorandr --save mobile

Em seguida, conectei meu hdmi e o arandr reconfigurado, depois executei:

autorandr --save docked

Depois de configurar cada um dos seus layouts, você pode executar (substituir 'mobile' pelo nome favorito anterior, usei mobile):

autorandr --default mobile

Agora que o autorandr está pronto, você pode automatizar o processo instalando um pacote que pesquisará os monitores conectados e executará autorandr --changeapós a detecção. Sim, eu sei sobre o udev e você pode configurá-lo se ele funcionar para você, mas nos meus testes o udev não funcionou para o meu hdmi de forma consistente. Ele funcionou apenas 1 em cada 20 plugues / desconectos, e às vezes parou completamente.

Faça o download do mais recente .deb aqui: https://github.com/nalipaz/poll-xrandr/releases/ e instale com

dpkg -i [file]

Provavelmente é necessário que você execute mais tarefas após a conclusão do autorandr --change, autorandr permite que esses comandos sejam inseridos em um arquivo chamado ~ / .autorandr / postswitch. Faça o seguinte:

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

Agora edite o arquivo postswitch para ter algo semelhante ao seguinte:

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

Além disso, você provavelmente desejará adicionar autorandr e poll-xrandr às suas startups, algo como os dois comandos a seguir:

autorandr --change &
poll-xrandr &

Desconecte ou conecte um monitor e observe a mágica!

nicholas.alipaz
fonte