#!/usr/bin/env bash # Copyright 2019 Luke Shumaker # # Adjusts the xrandr 1.2, xrandr 1.3, and xrdb DPI settings according # to each output's current mode (pixel resolution) and self-reported # physical dimensions (mm). # env-var: MAX_DPI: integer # env-var: DRY_RUN: empty=false / non-empty=true ( # Phase 1: Probe outputs export LC_ALL=C xrandr | sed -rn -e 's@(.*) connected( .*)? ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)( .*)? ([0-9]+)mm x ([0-9]+)mm( .*)?@\1 \3 \4 \8 \9@p' -e 's@^ ([0-9]+)x([0-9]+)i? .*\*.*@ \1 \2@p' | sed '/^\S/{ N; s/\n//; }' # 1 2 3 4 5 6 7 8 9 10 1 2 # `-outputName | `-fb_xpx `-fb_ypx `-fb_xoff `-fb_yoff `- hw_xmm `- hw_ymm | `-hw_xpx `-hw_ypx # `-discard `- discard `- discard ) | ( # Phase 2: Translate that to a set of actions to perform max_xdpi=${MAX_DPI:-96} max_ydpi=${MAX_DPI:-96} dpi=$(xrdb -query|sed -n 's/^Xft\.dpi:\s*//p') xdpi=${dpi%%x*} ydpi=${dpi#*x} if (( xdpi > max_xdpi )); then max_xdpi=$xdpi fi if (( ydpi > max_ydpi )); then max_ydpi=$ydpi fi declare -A outputs while read -r output fb_xpx fb_ypx hw_xmm hw_ymm hw_xpx hw_ypx; do hw_xdpi=$(bc <<<"($hw_xpx*25.4)/$hw_xmm") hw_ydpi=$(bc <<<"($hw_ypx*25.4)/$hw_ymm") fb_xdpi=$(bc <<<"($fb_xpx*25.4)/$hw_xmm") fb_ydpi=$(bc <<<"($fb_ypx*25.4)/$hw_ymm") if (( hw_xdpi > max_xdpi )); then max_xdpi=$hw_xdpi fi if (( hw_ydpi > max_ydpi )); then max_ydpi=$hw_ydpi fi if (( fb_xdpi > max_xdpi )); then max_xdpi=$fb_xdpi fi if (( fb_ydpi > max_ydpi )); then max_ydpi=$fb_ydpi fi outputs["$output"]="$hw_xdpi $hw_ydpi" done echo 'xrandr \' printf ' --dpi %q \\\n' "${max_xdpi}x${max_ydpi}" for output in "${!outputs[@]}"; do read -r xdpi ydpi <<<"${outputs[$output]}" printf ' --output %q --scale %q \\\n' "$output" "$(bc <<<"scale=5; $max_xdpi/$xdpi")x$(bc <<<"scale=5; $max_ydpi/$ydpi")" done echo printf "xrdb -merge <<<'Xft.dpi: %s'\n" "${max_xdpi}x${max_ydpi}" ) | ( # Phase 3: Apply those actions if [[ -z "$DRY_RUN" ]]; then bash -v else cat fi )