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

54

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

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

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

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

Ярослав Федевич
источник
Вы уверены, что нет способа узнать, что к вашей карте подключен монитор? Попробуйте запустить udevadm monitor --propertyиз терминала и подключить монитор. С моей картой я вижу событие, когда она подключена. Возможно, вы сможете использовать правило + RUN в udev и некоторые сценарии bash, чтобы получить то, что вы хотите. Тем не менее, я не уверен, как вы сможете реализовать это для каждого пользователя с помощью udev.
Стивен Д
@ Steven: Ваш комментарий должен быть ответом. Это не полный ответ, но он делает значительные успехи. Если udev видит аппаратное событие, оно должно уведомить hal, который отправляет событие dbus, которое видно по пользовательскому коду.
Жиль "ТАК ... перестать быть злым"

Ответы:

19

Я использую этот простой (самодельный) скрипт, который опрашивает 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. Откройте терминал, нажав Ctrl+Alt+t
  2. Перейдите в подходящее место, чтобы создать и сохранить сценарий оболочки с автоматическим переключением. пример

    cd ./Desktop/

  3. Создайте и отредактируйте файл .sh с помощью желаемого текстового редактора (здесь я использовал pluma. Вы можете попробовать nano, vim и т. Д.). Назовите это для вашего удобства. пример

    sudo pluma homemadeMonitor.sh

  4. Отредактируйте файл и скопируйте и вставьте все из вышеупомянутого скрипта (тот, что с #! / Bin / bash)

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

    sudo chmod +x homemadeMonitor.sh

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

    ./homemadeMonitor.sh

peoro
источник
Хороший сценарий! Спасибо, мне нужно было что-то подобное. Я просто скопировал его и настроил на автоматический запуск. Спасибо!
Linuxios
21

Отвечая на «[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.

Энди
источник
19

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

В моем ноутбуке установлена ​​карта NVIDIA, поэтому вместо xrandr я использую серверную часть с дисперсией: http://willem.engen.nl/projects/disper/ . 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), что почти так же хорошо.

Джек Сенечал
источник
1
autorandr был пустой тратой времени, плохо документирован, случайные мигания монитора, никаких инструкций по установке / удалению. Могли бы решить это с помощьюudev
Leo Gallucci
5
На всякий случай, есть хороший благоустроенный переписать в Python-развилок autorandr: github.com/phillipberndt/autorandr
Olegs Jeremejevs
7

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

#!/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для просмотра внешних мониторов, которые у вас есть. Последнее утверждение просто чтобы убедиться, что вы никогда не застряли без дисплея.

Cappie
источник
6

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

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

Иоахим Брейтнер
источник
5

Если вам нужно, чтобы он автоматически обнаруживал отображение при подключении, кажется, что самое чистое решение - добавить правило 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
iyrin
источник
3

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

#! / Bin / Баш

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

спать $ START_DELAY

OLD_DUAL = "фиктивный"

пока [1]; делать
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if ["$ OLD_DUAL"! = "$ DUAL"]; тогда
        if ["$ DUAL" == "connected"]; тогда
            echo 'Настройка двух мониторов'
            xrandr --output $ SCREEN_LEFT --auto - вращать в нормальном режиме --pos 0x0 --output $ SCREEN_RIGHT --auto - вращать в обычном режиме - ниже $ SCREEN_LEFT
        еще
            echo 'Настройка одного монитора'
            xrandr --auto
        фи

        OLD_DUAL = "$ DUAL"
    фи

    inotifywait -q -e close / sys / class / drm / card0-DP-2 / status> / dev / null
сделанный

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

Balzola
источник
1

При использовании решения 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
Aaros
источник
1

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

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

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

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

Иоахим Брейтнер
источник
1

Для упрощения, например, в 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
user180381
источник
0

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

Установите 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 &

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

nicholas.alipaz
источник