it-swarm-pt.tech

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

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?

58
Yaroslav Fedevych

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 seguinte arquivo de script, altere todas as VGA1 para HDMI1)

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

É personalizado para a minha configuração: você provavelmente precisará alterar os nomes de saída do RandR (LVDS1 e VGA1) e diferente de mim você provavelmente ficará bem com o seu modo padrão 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. Coloque o script acima (homemadeMonitor.sh) no diretório de sua preferência

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

    chmod +x homemadeMonitor.sh

  3. Execute o arquivo .sh

    ./homemadeMonitor.sh

20
peoro

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 da Intel pode ter um suporte melhor. O driver proprietário da NVIDIA atualmente não suporta o 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. A minha diz [drm] radeon kernel modesetting enabled e [drm] initializing kernel modesetting
  • corre udevadm monitor --property e 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 não usa KMS. Você não receberá nenhum evento do udev.

21
Andy

Em relação a uma ferramenta que pode armazenar perfis de configuração de monitor por usuário e por exibição, autorandr fará exatamente isso.

Meu laptop tem uma placa NVIDIA, então uso o disper back-end em vez do xrandr. O Autorandr usará o disper como back-end para gerenciar seus monitores se você o chamar como autodisper. No restante deste post, porém, vou me referir a ele como autorandr para obter consistência.

Você pode salvar perfis com autorandr --save profile_name. Executar autorandr por 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 com 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, eu anexei --default laptop para esse comando, que o tornará padrão para a 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.

19
Jack Senechal

Eu usei a regra udev sugerida acima, juntamente com um script do 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 echo $DISPLAY para ver qual número é igual. Usar xrandr -q para ver os monitores externos que você possui. A última declaração else é apenas para garantir que você nunca fique preso sem uma exibição.

7
Cappie

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

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

6
Joachim Breitner

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 de um usuário 1 :

Monitore (UdeV) eventos UDEV com udevadm
Esta etapa será mais importante para cada usuário. Corre 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
5
iyrin

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 
 
 sleep $ START_DELAY 
 
 OLD_DUAL = "fictício" 
 
 enquanto [ 1]; do 
 DUAL = $ (cat /sys/class/drm/card0-DP-2/status)[.____.}
 if ["$ OLD_DUAL"! = "$ DUAL"]; então 
 se ["$ DUAL" == "conectado"]; então 
 echo 'Configuração do monitor duplo' 
 xrandr - saída $ SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $ SCREEN_RIGHT --auto --rotate normal - abaixo $ TELA_LEFT 
 Else 
 Ecoa '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 
 concluído 
 

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

3
Balzola

Para simplificar no Xfce, por exemplo, instale "arandr", que deve estar disponível em seus pacotes de distribuição. Configure sua exibição usando "arandr" e salve-a como "displayLayout", por exemplo. O Arandr deve adicionar a extensão ".sh" para que ela 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 principal é relatada como "primária conectada" seguida pelo 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 isso será armazenado 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
1
user180381

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 lembrará (em .config/monitors.xml) e aplica-o 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 embora, quando finalmente chegue, 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.

1
Joachim Breitner

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

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]

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

autorandr --save mobile

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

autorandr --save docked

Depois de configurar cada um dos seus layouts, você pode executar (substituir 'mobile' pelo nome preferido 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 --change na 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 de 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!

0
nicholas.alipaz