it-swarm-ru.tech

Инструмент для автоматического применения конфигурации RandR, когда подключен внешний дисплей

есть ли инструмент, который позволяет:

  • запоминать текущую конфигурацию RandR (положение, ориентация, разрешение и т. д.) для каждого монитора,
  • автоматически применить последнюю удачную конфигурацию, как только дисплей будет подключен, без необходимости возиться с апплетами или xrandr (1)?

Конфигурации должны быть применены для каждого пользователя, для каждого дисплея.

Если такого инструмента нет в дикой природе, я бы хотел собрать его сам, но, насколько я вижу, я не могу сказать, что монитор подключен. Нужно ли опрашивать xrandr -q? время от времени, чтобы выяснить, что выход был подключен или отключен, или есть более эффективный способ сделать это? Можно ли настроить Udev именно на это?

58
Yaroslav Fedevych

Я использую этот простой (самодельный) скрипт, который опрашивает RandR и переключается между LVDS1 и VGA1, когда VGA подключается/отключается. (Для [~ # ~] hdmi [~ # ~] в следующем файле сценария измените все VGA1 до HDMI1)

Это грязное решение, но оно работает просто отлично.

Он настроен для моей настройки: вам, скорее всего, придется изменить выходные имена RandR (LVDS1 а также VGA1) и в отличие от меня вам, вероятно, будет хорошо с вашим стандартным режимом RandR для 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

Полные шаги:

  1. Поставьте вышеприведенный скрипт (homemadeMonitor.sh) в выбранный вами каталог

  2. Сделайте исполняемый файл .sh набрав следующую команду в терминале

    chmod +x homemadeMonitor.sh

  3. Запустите файл .sh

    ./homemadeMonitor.sh

20
peoro

Отвечая на "[a] способ узнать, что монитор был подключен" часть вопроса:

Поддержка по-прежнему немного варьируется, но в последних ядрах есть некоторая поддержка для генерации событий udev, когда происходит горячее подключение дисплея. С ядром 2.6.38 и оборудованием ATI X1400 я получаю событие при первом подключении VGA-дисплея, но никаких событий при последующих отключениях или повторных подключениях дисплея не происходит. аппаратное обеспечение Intel может иметь лучшую поддержку. Собственный драйвер NVIDIA в настоящее время не поддерживает KMS; Я не пробовал искать события горячей замены на оборудовании NVIDIA, но я сомневаюсь, что это сработает.

Если вы хотите поэкспериментировать с udev, попробуйте выполнить следующие действия:

  • обновить до новейшего ядра
  • убедитесь, что настройка режима ядра (KMS) включена. Если включено, об этом следует сообщать в выводе вашего ядра. Мой говорит [drm] radeon kernel modesetting enabled а также [drm] initializing kernel modesetting
  • запустить udevadm monitor --property и ​​посмотрите, будут ли сообщения о событиях, когда вы отключаете дисплеи

Если вы получаете события udev на дисплее hotplug, вы можете запустить скрипт с правилом udev, например:

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

Примечание: Это будет не сработает, если вы используете графический процессор nVIDIA с проприетарным двоичным драйвером, поскольку он не использует KMS. Вы будете нет получать любые события udev.

21
Andy

Что касается инструмента, который может хранить профили конфигурации монитора для каждого пользователя и для каждого дисплея, autorandr сделает именно это.

В моем ноутбуке есть карта NVIDIA, поэтому я использую дисперсный бэкэнд вместо xrandr. Autorandr будет использовать disper в качестве бэкэнда для управления вашими мониторами, если вы называете его как autodisper. Для остальной части этого поста я буду ссылаться на это как autorandr для согласованности.

Вы можете сохранить профили с помощью autorandr --save profile_name. Запуск autorandr сам по себе даст вам список профилей и определит, какой из них обнаружен в качестве текущей конфигурации.

Например:

$ autorandr
laptop
syncmaster19 (detected)

Вы можете настроить автоматическую загрузку соответствующего профиля для текущей конфигурации с помощью autorandr --change. Эта команда в сочетании с правилом udev для запуска, когда он подключен в горячем режиме, будет делать то, что вы просили.

В качестве дополнительной меры предосторожности я добавил --default laptop к этой команде, которая по умолчанию будет отображать экран ноутбука, если нет сохраненного профиля, соответствующего текущей конфигурации. Таким образом, полная команда, которую я использую для переключения дисплеев:

autorandr --change --default laptop

К сожалению, моя машина не выдает вывод udev, когда я подключаю монитор к горячему подключению. Я использую проприетарные драйверы NVIDIA, так что это не удивительно. Поэтому я связал его с ключом XF68Display (Fn-F8), что почти так же хорошо.

19
Jack Senechal

Я использовал предложенное выше правило udev вместе со сценарием Shell, который выглядит как

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

Часть Xauthority важна, так же как и экспорт DISPLAY, вы можете использовать echo $DISPLAY чтобы узнать, какому числу он равен. Используйте xrandr -q чтобы увидеть внешние мониторы, которые у вас есть. Последнее утверждение просто, чтобы убедиться, что вы никогда не застряли без дисплея.

7
Cappie

Небольшая программа, которая ждет, пока X-сервер уведомит ее об измененной конфигурации монитора, а затем выполнит заданную команду (например, autorandr, упомянутый в другом ответе), доступна по адресу: https: // bitbucket .org/portix/srandrd/обзор

Похоже, это более чистое решение, использующее udev (где вам нужно беспокоиться о поиске подходящего X-сервера и т.д.)

6
Joachim Breitner

Если вам нужно, чтобы он автоматически обнаруживал отображение при подключении, кажется, что самое чистое решение - добавить правило UDEV для запуска сценария, содержащего ваши команды xrandr. Вот пример решения одного пользователя 1 :

Отслеживать (выводить) события UDEV с помощью udevadm
Этот шаг будет наиболее важным для каждого пользователя. Запустить udevadm monitor --environment --udev. Затем подключите кабель HDMI.

Правило UDEV
Основываясь на выводе вышеприведенной команды, пользователь создал это правило UDEV в /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"

Обратите внимание на используемые переменные среды, поэтому xrandr будет запускаться под профилем пользователя.

скрипт xrandr hotplug_monitor.sh

Вы можете настроить параметры xrandr в соответствии с вашими потребностями.

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

Для тех, кто по какой-либо причине не хочет идти по маршруту горячего подключения, все еще возможно не опрашивать в скрипте с использованием inotifywait:

 #!/Bin/Баш 
 
 SCREEN_LEFT = DP2 
 SCREEN_RIGHT = eDP1 
 START_DELAY = 5 
 
 renice +19 $$>/dev/null 
 
 sleep $ START_DELAY 
 
 OLD_DUAL = "dummy" 
 
 while [ 1]; do 
 DUAL = $ (cat /sys/class/drm/card0-DP-2/status)

 if ["$ OLD_DUAL"! = "$ DUAL"]; затем 
 if ["$ DUAL" == "подключен"]; затем 
 echo 'Настройка двух мониторов' 
 xrandr --output $ SCREEN_LEFT --auto --rotate normal --pos 0x0 - output $ SCREEN_RIGHT --auto --rotate normal --below $ SCREEN_LEFT 
 Else 
 Echo 'Настройка одного монитора' 
 Xrandr --auto 
 Fi 
 
 OLD_DUAL = "$ DUAL" 
 fi 
 
 inotifywait -q -e close/sys/class/drm/card0-DP-2/status>/dev/null 
 сделано 
 

Опрос xrandr дал серьезные проблемы с юзабилити на моем новом ноутбуке (мышь периодически зависала).

3
Balzola

Для упрощения, например, в Xfce, пожалуйста, установите "arandr", который должен быть доступен в ваших дистрибутивах. Сконфигурируйте ваш дисплей, используя "arandr", затем сохраните его, например, как "displayLayout". Арандр должен добавить для вас расширение ".sh", чтобы его можно было напрямую использовать в "функции connect ()", как написано в сценарии "hotplug_monitor.sh", упомянутом выше iyrin, например:

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

Чтобы использовать механизм отключения, добавьте вверху скрипта чуть ниже "#!/Bin/bash" примерно так:

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

xrandr обнаружит дисплей и передаст вывод в awk, который отфильтрует его по регулярному выражению "connected", за которым следует цифра, которая, по сути, и есть то, что нам нужно. По моему мнению, нет необходимости совпадать с точным разрешением в регулярном выражении, потому что основной дисплей отображается как "подключенный основной", за которым следует число, то есть разрешение. Тогда awk "print $ 1" будет печатать только первый столбец, который в этом случае является именем внешнего монитора, и это будет сохранено в переменной PLUGGED_EXTERNAL. Далее вместо фиксированного отображаемого имени "HDMI1" в скрипте $ PLUGGED_EXTERNAL можно использовать так:

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

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

Я думаю, что люди, которые смотрят на этот вопрос, не те, кто хочет использовать GNOME, и те, кто использует GNOME, не должны были бы смотреть на этот вопрос, но в интересах полноты:

GNOME имеет эту встроенную функциональность. Если вы измените настройку через gnome-control-center, gnome-settings-daemon запомнит это (в .config/monitors.xml) и автоматически применяет его при подключении или отключении монитора.

К сожалению, конфигурация в файле monitors.xml плохо документирована. Смотрите вопрос здесь . Инструменты отображения гномов также не имеют возможности настройки панорамирования, масштабирования для каждого монитора и не уменьшают масштаб. Поскольку многие люди используют экран ноутбука HiDPI вместе с обычным экраном DPI, инструментов недостаточно, чтобы получить работоспособное решение.

Я видел это упомянуто как элемент дорожной карты для Wayland хотя, когда это наконец произойдет, мы можем увидеть исправление упомянутых проблем. До тех пор в Gnome я просто запускаю скрипт запуска после задержки, чтобы настроить xrandr вручную.

1
Joachim Breitner

При использовании решения peoro я получил дополнительный вывод от xrandr, поэтому я использовал опцию -c для grep, которая подсчитывает количество совпадений. Я адаптировал его для HDMI и добавил аудио переключатель:

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

Редактирование моего ответа, чтобы упростить настройку.

Установите autorandr для автоматизации макета экрана в xrandr, загрузите последнюю версию .deb из https://github.com/nalipaz/autorandr/releases и запустите:

dpkg -i [file]

Настройка авторандра с сохраненными макетами экрана

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

Например, на моем ноутбуке без подключенных мониторов я настроил arandr так, как хочу, затем запустил:

autorandr --save mobile

Затем подключил мой hdmi и перенастроил arandr, затем запустил:

autorandr --save docked

После настройки каждого макета, который вы можете запустить (замените "mobile" на предыдущее предпочтительное имя, я использовал mobile):

autorandr --default mobile

Теперь, когда autorandr полностью настроен, вы можете автоматизировать процесс, установив пакет, который будет запрашивать подключенные дисплеи и запускать autorandr --change при обнаружении. Да, я знаю об udev, и вы можете настроить его, если он работает для вас, но в моем тестировании udev не работал для моего hdmi последовательно. Это работало только 1 из каждых 20 штепселей/отключений или около того, и иногда это просто останавливалось вообще.

Загрузите последнюю версию .deb здесь: https://github.com/nalipaz/poll-xrandr/releases/ и установите с

dpkg -i [file]

Скорее всего, необходимо выполнить больше задач после завершения autorandr --change, autorandr позволяет вставлять эти команды в файл ~/.autorandr/postswitch. Сделайте следующее:

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

Теперь отредактируйте файл postswitch, чтобы он был похож на следующее:

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

Кроме того, вы, вероятно, захотите добавить autorandr и poll-xrandr в свои стартапы, что-то вроде следующих двух команд:

autorandr --change &
poll-xrandr &

Отключите или подключите монитор и наблюдайте за волшебством!

0
nicholas.alipaz