, последнее обновление:
Содержание

XRandR - автодетект монитора

После покупки нового ноутбука (Thinkpad 13 2gen) у меня остро встал вопрос на тему подключения внешнего монитора, ибо очень хотелось расширить рабочее пространство. Так как вместо DE/WM я поставил себе i3 (чтобы удобно было работать на самом ноутбуке без мышки), то выбор у меня был небольшой - мучаться с ACPI/udev или сделать что-то другое. Не буду рассказывать про ACPI/udev подробно, просто скажу, что у меня не получилось.

Но вполне успешно написался скрипт, который запускается при логине и раз в секунду проверяет изменение конфигурации мониторов. Написан он, конечно, “на коленке”, однако позволяет выполнить главную задачу - сдетектить подключение монитора и настроить его. А за перемещение рабочих мест с окнами отвечает i3 :).

Итак, сам скрипт:

#!/bin/bash
 
# Monitor connection detector.
# Detects external monitor connections and perform some XRandR magic.
# Surely works on Linux. Might work on BSD.
# Just launch it on startup, it'll do the rest.
 
# THE CONFIGURATION.
# Debug configuration.
# Is it enabled?
DEBUG_ENABLED=0
# Debug log file location.
DEBUG_LOG_FILENAME="/tmp/mcd.log"
 
# Internal monitor name, according to xrandr.
INTERNAL_MONITOR="eDP1"
 
# External monitor, according to xrandr.
EXTERNAL_MONITOR="HDMI1"
 
# External monitor position regarding to internal.
# Valid values: "right" and "left"
EXTERNAL_MONITOR_POSITION="right"
 
# xrandr location.
XRANDR=$(which xrandr)
 
# Monitors states.
INTERNAL_MONITOR_STATE="connected"
EXTERNAL_MONITOR_STATE="disconnected"
 
# Logging function.
function log() {
    local msg=$@
 
    # This function should work only if debug mode is activated.
    if [[ $DEBUG_ENABLED -eq 1 ]]; then
        if [ ! -f "${DEBUG_LOG_FILENAME}" ]; then
            touch "${DEBUG_LOG_FILENAME}"
        fi
        echo `date` $msg
        echo `date` $msg >> $DEBUG_LOG_FILENAME
    fi
}
 
while true; do
    log "Checking monitor..."
 
    # Check if external monitor is connected.
    xrandr | grep ${EXTERNAL_MONITOR} | grep " connected " &> /dev/null
    xrandr_status=$?
    log "Status: ${xrandr_status}"
 
    # If monitor is connected - activate it and set neccessary properties.
    if [ ${xrandr_status} -eq 0 -a "${EXTERNAL_MONITOR_STATE}" == "disconnected" ]; then
        EXTERNAL_MONITOR_RESOLUTION=$(xrandr | grep HDMI1 -A1 | tail -n 1 | awk {' print $1 '})
        log "Detected ${EXTERNAL_MONITOR_NAME} monitor, activating and setting resolution: ${EXTERNAL_MONITOR_RESOLUTION}"
        xrandr --output "${EXTERNAL_MONITOR}" --mode "${EXTERNAL_MONITOR_RESOLUTION}" --${EXTERNAL_MONITOR_POSITION}-of ${INTERNAL_MONITOR}
        EXTERNAL_MONITOR_STATE="connected"
    fi
 
    # If monitor is disconnected - disable it.
    if [ ${xrandr_status} -eq 1 -a "${EXTERNAL_MONITOR_STATE}" == "connected" ]; then
        log "${EXTERNAL_MONITOR_NAME} disconnected."
        xrandr --output "${EXTERNAL_MONITOR}" --off
        EXTERNAL_MONITOR_STATE="disconnected"
    fi
    # Sleeping in the end.
    sleep 1
done

Основные переменные, которые интересуют - это INTERNAL_MONITOR, EXTERNAL_MONITOR и EXTERNAL_MONITOR_POSITION. Их настройте под себя, используя вывод xrandr.

После настройки скрипт нужно просто добавить в автозапуск. Проверен в боевых условиях, работает идеально.