1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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"
|