diff options
| -rwxr-xr-x | .local/bin/xrandr-screenScaler | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/.local/bin/xrandr-screenScaler b/.local/bin/xrandr-screenScaler new file mode 100755 index 0000000..7ac1803 --- /dev/null +++ b/.local/bin/xrandr-screenScaler @@ -0,0 +1,143 @@ +#!/bin/sh + +# POSIX-compliant xrandr screen scaling shell script +# Requires: xrandr, fzf, awk, sed, printf, cut, grep + +err() { printf "%s\n" "$*" >&2; exit 1; } + +for cmd in xrandr fzf awk sed grep cut printf; do + command -v "$cmd" >/dev/null 2>&1 || err "required command not found: $cmd" +done + +TMPDIR=${TMPDIR:-/tmp} +tmp_out="$TMPDIR/xrandr_outputs_$" +tmp_scales="$TMPDIR/xrandr_scales_$" +xrandr --query > "$tmp_out" || err "xrandr failed" + +awk ' +/ connected/ { + out=$1 + if (match($0, /[0-9]+x[0-9]+\+[0-9]+\+[0-9]+/)) { + res=substr($0, RSTART, RLENGTH) + sub(/\+.*/,"",res) + print out "\t" res + } else { + found=0 + # scan following indented lines for "*" indicating current mode + while (getline > 0) { + if ($0 ~ /^[ \t]/) { + if ($0 ~ /\*/) { + split($1,a,"+") + print out "\t" a[1] + found=1 + break + } + } else { + break + } + } + if (!found) print out "\tunknown" + } +} +' "$tmp_out" > "${tmp_out}.list" + +[ -s "${tmp_out}.list" ] || { rm -f "$tmp_out" "${tmp_out}.list"; err "no connected outputs found."; } + +chosen_line=$(awk -F'\t' '{printf "%s\t%s\n",$1,$2}' "${tmp_out}.list" | fzf --prompt="select output: " --with-nth=1,2 --tiebreak=index --exact) || { rm -f "$tmp_out" "${tmp_out}.list"; exit 1; } +out=$(printf '%s' "$chosen_line" | cut -f1) +cur_res=$(printf '%s' "$chosen_line" | cut -f2) + +cat > "$tmp_scales" <<'EOF' +4k to 1080p 3840x2160 1920x1080 +4k to 1440p 3840x2160 2560x1440 +4k to 1600p 3840x2160 2560x1600 +4k to 720p 3840x2160 1280x720 +4k to 768p 3840x2160 1366x768 +1440p to 1080p 2560x1440 1920x1080 +1440p to 720p 2560x1440 1280x720 +2560x1600 to 1080p 2560x1600 1920x1080 +1080p to 768p 1920x1080 1366x768 +1080p to 720p 1920x1080 1280x720 +1080p to 4k 1920x1080 3840x2160 +1080p to 1366x768 1920x1080 1366x768 +1600x900 to 1080p 1600x900 1920x1080 +1600x900 to 720p 1600x900 1280x720 +720p to 1080p 1280x720 1920x1080 +720p to 4k 1280x720 3840x2160 +720p to 1366x768 1280x720 1366x768 +1024x768 to 1080p 1024x768 1920x1080 +3440x1440 to 1080p 3440x1440 1920x1080 +3440x1440 to 1440p 3440x1440 2560x1440 +3440x1440 to 2560x1080 3440x1440 2560x1080 +3440x1440 to 1600p 3440x1440 2560x1600 +3440x1440 to 720p 3440x1440 1280x720 +3440x1440 to 1366x768 3440x1440 1366x768 +3840x1600 to 1080p 3840x1600 1920x1080 +3840x1600 to 1440p 3840x1600 2560x1440 +3840x1600 to 2560x1080 3840x1600 2560x1080 +2560x1080 to 1080p 2560x1080 1920x1080 +2560x1080 to 1440p 2560x1080 2560x1440 +2560x1080 to 1366x768 2560x1080 1366x768 +3200x1800 to 1080p 3200x1800 1920x1080 +3200x1800 to 1440p 3200x1800 2560x1440 +1366x768 to 720p 1366x768 1280x720 +1366x768 to 1024x768 1366x768 1024x768 +1366x768 to 1080p 1366x768 1920x1080 +1365x768 to 720p 1365x768 1280x720 +1280x800 to 1080p 1280x800 1920x1080 +1280x800 to 1366x768 1280x800 1366x768 +1280x800 to 1440p 1280x800 2560x1440 +1280x720 to 1080p 1280x720 1920x1080 +1152x864 to 1024x768 1152x864 1024x768 +800x600 to 1024x768 800x600 1024x768 +800x600 to 1080p 800x600 1920x1080 +800x480 to 720p 800x480 1280x720 +640x480 to 1080p 640x480 1920x1080 +1600x1200 to 1080p 1600x1200 1920x1080 +1600x1200 to 1280x1024 1600x1200 1280x1024 +1280x1024 to 1080p 1280x1024 1920x1080 +1280x1024 to 1366x768 1280x1024 1366x768 +1024x768 to 1280x800 1024x768 1280x800 +1024x768 to 1080p 1024x768 1920x1080 +1152x864 to 1024x768 1152x864 1024x768 +1400x1050 to 1080p 1400x1050 1920x1080 +1400x1050 to 1440p 1400x1050 2560x1440 +3840x2160 to 1600x900 3840x2160 1600x900 +3840x2160 to 1366x768 3840x2160 1366x768 +3840x2160 to 1280x800 3840x2160 1280x800 +3840x2160 to 1024x768 3840x2160 1024x768 +3200x1800 to 1600x900 3200x1800 1600x900 +1080p to 800x600 1920x1080 800x600 +1080p to 1024x768 1920x1080 1024x768 +1360x768 to 720p 1360x768 1280x720 +1360x768 to 1080p 1360x768 1920x1080 +1920x1200 to 1080p 1920x1200 1920x1080 +reset scaling - - +EOF + +# present options (strip comment lines). Use fzf with --exact to make matching +# stricter (slightly less fuzzy). +chosen_scale=$(grep -v '^#' "$tmp_scales" | awk -F'\t' '{printf "%s\t%s\t%s\n",$1,$2,$3}' \ + | fzf --prompt="select scaling option: " --with-nth=1,2,3 --exact --tiebreak=index --preview='echo {}') || { rm -f "$tmp_out" "${tmp_out}.list" "$tmp_scales"; exit 1; } + +label=$(printf '%s' "$chosen_scale" | cut -f1) +src=$(printf '%s' "$chosen_scale" | cut -f2) +tgt=$(printf '%s' "$chosen_scale" | cut -f3) + +if [ "$label" = "reset scaling" ]; then + scale_for_xrandr="1x1" +else + scale=$(awk -F'[x\t ]' -v s="$src" -v t="$tgt" ' + BEGIN{ + split(s,ss,"x"); split(t,tt,"x"); + if (ss[1]==0 || ss[2]==0) { print "1.000000,1.000000"; exit } + sx = tt[1]/ss[1]; sy = tt[2]/ss[2]; + printf("%.6f,%.6f", sx, sy); + }') + scale_for_xrandr=$(printf '%s' "$scale" | sed 's/,/x/') +fi + +printf 'applying: output=%s current=%s option=%s scale=%s\n' "$out" "$cur_res" "$label" "$scale_for_xrandr" +xrandr --output "$out" --scale "$scale_for_xrandr" --filter bilinear + +rm -f "$tmp_out" "${tmp_out}.list" "$tmp_scales" |
