aboutsummaryrefslogtreecommitdiff
path: root/.local/bin/xrandr-screenScaler
diff options
context:
space:
mode:
Diffstat (limited to '.local/bin/xrandr-screenScaler')
-rwxr-xr-x.local/bin/xrandr-screenScaler143
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"