Skip to content

Instantly share code, notes, and snippets.

@mgbckr
Created February 1, 2023 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgbckr/b5063aebfd321bbfc1586d2db84121ae to your computer and use it in GitHub Desktop.
Save mgbckr/b5063aebfd321bbfc1586d2db84121ae to your computer and use it in GitHub Desktop.

Script to configure displays via EDID rather than outputs with xrandr

Sometime output designations change in xrandr. Particular when using a docking station (e.g., a Lenovo Thunderbolt 4 Dock). In those cases scripts that use output names to configure a display setup fail. This script provides function to use a screens.ini file (see example) with EDIDs rather than output names.

# get EDIDs for output names
bash screens.sh map

# configure displays according to `config.ini`
bash screens.sh set

Hints

Screens stay black

Things to try:

TODO

  • allow to switch between configs
  • auto config
  • fix that annyoing black screen bug (sometimes screens just stay black)
00ffffffffffff0010ac8c4255394241 --mode 0x58 --crtc 0 --rotate normal
00ffffffffffff0010ac7c424c544742 --mode 0x58 --crtc 0 --rotate normal --right-of 00ffffffffffff0010ac8c4255394241
00ffffffffffff0010ac7b424c314842 --mode 0x58 --crtc 1 --rotate right --right-of 00ffffffffffff0010ac7c424c544742
00ffffffffffff004c835a4100000000 --mode 0x61 --crtc 2 --rotate normal --right-of 00ffffffffffff0010ac7b424c314842
#!/bin/bash
function get_port_edid_map {
xrandr --props | awk '/DP.* connected/{PORT=$1} /EDID/{EDID=1; next} //{if (EDID==1) printf "%s\t%s\n", PORT, $1; EDID=0}'
}
function get_outputs {
echo "$(get_port_edid_map)" | cut -f 1
}
function get_edids {
echo "$(get_port_edid_map)" | cut -f 2
}
function edid_to_port {
port=$1
echo "$(get_port_edid_map)" | grep $port | cut -f 1
}
function replace_edid_with_port {
string=$1
#echo "$string"
for edid in $(get_edids); do
port=$(edid_to_port $edid)
#echo "Replace: $edid > $port"
string=$(echo "$string" | sed s/$edid/$port/g)
#echo "$string"
done
echo $string
}
function off {
MAIN_SCREEN=${1:-eDP-1}
MAIN_MODE=${2:-0x61}
for o in $(get_outputs); do
echo $o
xrandr --output $o --off
done
}
function main {
MAIN_SCREEN=${1:-eDP-1}
MAIN_MODE=${2:-0x61}
xrandr --output $MAIN_SCREEN --mode $MAIN_MODE
}
function reset {
off
sleep 5
main ${@}
}
# print modes: xrandr --verbose | grep MHz | sort --key 3 --numeric-sort --reverse | uniq
# seach modes: xrandr --verbose | egrep '^[^[:space:]]|241.500MHz'
function set_screens {
config=$(cat screens.ini)
echo "Checking whether EDIDs in config exist:"
echo "---------------------------"
while read line; do
echo "$line"
edid=$(echo "$line" | cut -d " " -f 1)
port=$(edid_to_port $edid)
if [[ "$port" == "" ]]; then
echo -e "ERROR: Invalid config. Unknown EDID: $edid"
return
fi
done <<< "${config}"
echo "---------------------------"
echo "Turning off all screens"
sleep 1
off
sleep 3
echo ""
echo "Turning screens back on:"
echo "---------------------------"
while read line; do
replaced=$(replace_edid_with_port "$line")
cmd="xrandr --output $replaced"
echo "$cmd"
$cmd
sleep 3
done <<< "${config}"
echo "---------------------------"
}
if [[ "$1" == "reset" ]]; then
reset ${@:2}
elif [[ "$1" == "set" ]]; then
set_screens
elif [[ "$1" == "map" ]]; then
get_port_edid_map
else
echo "Unknown command: $1"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment