Порой приходится довольно часто подключать/отключать дополнительный монитор от ноутбука, и не всегда в установленном дистрибутиве присутствует (если вообще есть) нормальное определение на данное действие. Попробуем исправить это упущение.
Итак, нам понадобится создать всего 2 файла для автоматического распознавания подключенного монитора. Сразу оговорюсь, что данный скрипт написан с целью ознакомления с подобной возможностью и поддерживает только один дополнительный выход, хотя никто не мешает дописать его для «трехголовой» карточки.
Начнем с выяснения названий выходов нашей видеокарты, для этого выполним команду xrandr
в консоли (у кого нет — ставим пакет x11-xserver-utils
). На выходе мы должны получить что-то вроде такого:
Screen 0: minimum 320 x 200, current 3200 x 1080, maximum 8192 x 8192 LVDS1 connected 1280x800+0+0 (normal left inverted right x axis y axis) 331mm x 207mm 1280x800 60.0*+ 1024x768 60.0 800x600 60.3 56.2 640x480 59.9 VGA1 connected 1920x1080+1280+0 (normal left inverted right x axis y axis) 477mm x 268mm 1920x1080 60.0*+ 1680x1050 60.0 1600x900 60.0 1280x1024 75.0 60.0 1440x900 59.9 1280x800 59.8 1152x864 75.0 1280x720 60.0 1024x768 75.1 70.1 60.0 832x624 74.6 800x600 72.2 75.0 60.3 56.2 640x480 72.8 75.0 66.7 60.0 720x400 70.1 TV1 unknown connection (normal left inverted right x axis y axis) 848x480 59.9 + 640x480 59.9 + 1024x768 59.9 800x600 59.9
Вот мы и получили наши имена выходов, а именно TV1
, LVDS1
и VGA1
.
Теперь напишем правило для UDEV, писать придется от рута. Создадим файл /etc/udev/rules.d/99-monitor-interrupt.rules
с таким содержимым:
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/sbin/auto-xrandr"
Теперь у нас есть правило, которое при подключении и/или отключении выполняет некий скрипт auto-xrandr
. Осталось создать последний (опять же от рута) файл /usr/local/sbin/auto-xrandr
со следующим содержанием:
#!/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin SOCK_PATH=/tmp/.X11-unix EXTERNAL_OUTPUT="VGA1" INTERNAL_OUTPUT="LVDS1" EXTERNAL_LOCATION="right" case "$EXTERNAL_LOCATION" in left|LEFT) EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT" ;; right|RIGHT) EXTERNAL_LOCATION="--right-of $INTERNAL_OUTPUT" ;; top|TOP|above|ABOVE) EXTERNAL_LOCATION="--above $INTERNAL_OUTPUT" ;; bottom|BOTTOM|below|BELOW) EXTERNAL_LOCATION="--below $INTERNAL_OUTPUT" ;; *) EXTERNAL_LOCATION="--left-of $INTERNAL_OUTPUT" ;; esac try_set_xrandr() { export DISPLAY=$1 export XAUTHORITY=$2/.Xauthority xrandr >>/dev/null 2>&1 [ $? -ne 0 ] && return 1 xrandr >>/tmp/udev.log 2>&1 xrandr | grep $EXTERNAL_OUTPUT | grep " connected " >>/dev/null 2>&1 if [ $? -eq 0 ] ; then xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION >/dev/null 2>&1 # Alternative command in case of trouble: # (sleep 2; xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION) & else xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --off >/dev/null 2>&1 fi } HOMES="" for HOME in `cat /etc/passwd | cut -d':' -f6` do [ ! -f ${HOME}/.Xauthority ] && continue HOMES="${HOME} ${HOMES}" done for SOCKET in ${SOCK_PATH}/X* do [ ! -S $SOCKET ] && continue LEN=`expr length $SOCKET` SOCK=":`expr substr $SOCKET $LEN 1`" for HOME in ${HOMES} do try_set_xrandr $SOCK $HOME [ $? -eq 1 ] && try_set_xrandr $SOCK.0 $HOME done done
Делаем этот файл исполняемым:
sudo chmod +x /usr/local/sbin/auto-xrandr
Теперь поясню зачем нам в начале статьи нужны были имена выходов видеокарты. Нам нужно выбрать основной (или внутренний для ноутбука) выход. В моём случае это LVDS1 (на ноутбуке), соответственно он и прописан в переменной INTERNAL_OUTPUT
. В EXTERNAL_OUTPUT
нужно прописать второй выход, к которому, собственно, и подключается второй монитор.
Теперь о расположении второго монитора, оно регулируется переменной EXTERNAL_LOCATION
, которая может принимать значения left
, right
, top
и bottom
(слева, справа, сверху или снизу соответственно от внутреннего монитора/выхода).
В переменной SOCK_PATH
содержится путь до локальных сокетов сервера X11, в моём случае это /tmp/.X11-unix
. В данной папке лежат файлики с именами X0, X1 и т.п., где окончание соответствует номеру X сервера. Бывает, что на одном компьютере запущено и два X сервера параллельно (как вариант, на 7 и на 8 терминале), соответственно, для обоих и приходится менять разрешения.
Теперь следующее пояснение по скрипту, xrandr в оном выполняется вне окружения, и ему не известны параметры авторизации, поэтому приходится перебирать всех пользователей и искать в их домашних папках файл Xauthority, дабы дать понять утилите что доступ до сервера у нас все же есть и мы сможем сменить настройки экрана.
Ну, и ещё одно дополнение, не всегда удается подключиться по короткому имени X дисплея (например, «:0»), поэтому иногда приходится обращаться по полному имени («:0.0»).