blob: 0bc5c67cd744482d37ebbd566b3e0a204e0df9a3 (
plain)
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
144
145
146
147
148
149
150
151
152
153
154
155
|
#!/usr/bin/env bash
# Copyright 2019 Luke Shumaker
sanitize() {
[[ $? == 0 ]] || return $?
printf '%g\n' "$@"
}
calc() {
[[ $? == 0 ]] || return $?
sanitize "$(bc <<<"scale=6; $1")"
}
round() {
[[ $? == 0 ]] || return $?
printf '%.f\n' "$@"
}
roundup_by() {
[[ $? == 0 ]] || return $?
awk -v by="$2" 'function ceil(x) { return (x == int(x)) ? x : int(x)+1 } { print ceil($1/96)*96 }' <<<"$1"
}
max() {
[[ $? == 0 ]] || return $?
awk -v a="$1" -v b="$2" '{ print (a > b) ? a : b }' <<<''
}
errusage() {
if (( $# > 0 )); then
printf '%s: %s\n' "${0##*/}" "$(printf "$@")" >&2
fi
printf "Try '%s --help' for more information.\n" "${0##*/}" >&2
exit 2
}
usage() {
printf 'Usage: %s [OPTIONS]\n' "${0##*/}"
printf "Adjust DPI settings to reflect each output's current mode\n"
printf "(pixel resolution) and self-reported physical dimensions (mm).\n"
echo
printf 'OPTIONS:\n'
printf ' -h, --help Show this message\n'
printf ' -n, --dry-run Print what would be done, without doing it\n'
printf ' --render-dpi=<auto|auto-hwonly|DPI|XDPIxYDPI>\n'
printf ' Specify what DPI applications should render\n'
printf ' at (default: auto)\n'
printf ' --device-geometry=OUTPUT=<X>x<Y>[x<Z>]\n'
printf ' Override the hardware-reported physical\n'
printf ' dimensions for the X11 output OUTPUT; see\n'
printf ' `get-dpi --help`\n'
}
set -euE -o pipefail
args=$(getopt -n "${0##*/}" -o 'hn' -l 'help,dry-run,render-dpi:,device-geometry:' -- "$@") || errusage
eval "set -- $args"
arg_dry_run=false
arg_render_dpi=auto
get_dpi_args=()
while (( $# > 0 )); do
case "$1" in
-h|--help)
usage
exit 0
;;
-n|--dry-run)
arg_dry_run=true
shift
;;
--render-dpi)
arg_render_dpi=$2
case "$2" in
auto|auto-hwonly)
arg_render_dpi=$2
;;
*)
if ! arg_render_dpi="$(sanitize "${2%%x*}" 2>/dev/null)x$(sanitize "${2#*x}" 2>/dev/null)"; then
errusage 'Invalid --render-dpi=%q' "$2"
fi
;;
esac
shift 2
;;
--device-geometry)
get_dpi_args+=("$1=$2")
shift 2
;;
--)
shift
break
;;
esac
done
if (( $# > 0 )); then
errusage
fi
dpis="$(get-dpi "${get_dpi_args[@]}")"
if [[ $arg_render_dpi == auto ]] || [[ $arg_render_dpi == auto-hwonly ]]; then
arg_render_xdpi=96
arg_render_ydpi=96
while read -r source item dpi; do
if [[ $arg_render_dpi == auto-hwonly ]] && [[ $source != X11-RandR-hw ]]; then
continue
fi
arg_render_xdpi=$(max "$(round "${dpi%%x*}")" "$arg_render_xdpi")
arg_render_ydpi=$(max "$(round "${dpi#*x}")" "$arg_render_ydpi")
done <<<"$dpis"
# GDK 3 only supports integer up-scale factors, because
# they're morons. Round arg_render_dpi up to a multiple of '96'.
arg_render_xdpi=$(roundup_by "$arg_render_xdpi" 96)
arg_render_ydpi=$(roundup_by "$arg_render_ydpi" 96)
else
arg_render_xdpi=${arg_render_dpi%%x*}
arg_render_ydpi=${arg_render_dpi#*x}
fi
(
echo 'xrandr \'
printf ' --dpi %q \\\n' "${arg_render_xdpi}x${arg_render_ydpi}"
while read -r source item dpi; do
if [[ $source != X11-RandR-hw ]]; then
continue
fi
hw_xdpi="$(sanitize "${dpi%%x*}")"
hw_ydpi="$(sanitize "${dpi#*x}")"
fb_xdpi="$(calc "$arg_render_xdpi/$hw_xdpi")"
fb_ydpi="$(calc "$arg_render_ydpi/$hw_ydpi")"
printf ' --output %q --scale %q \\\n' "$item" "${fb_xdpi}x${fb_ydpi}"
done <<<"$dpis"
echo
printf "xrdb -merge <<<'Xft.dpi: %s'\n" "${arg_render_xdpi}x${arg_render_ydpi}"
echo
GDK_SCALE="$(calc "(${arg_render_xdpi}+${arg_render_ydpi})/2 /96")"
printf 'export GDK_SCALE=%q\n' "$GDK_SCALE"
# You're not "supposed" to set XRDB Xft.dpi if GDK_SCALE is
# set. Undo Xft.dpi for GDK applications.
GDK_DPI_SCALE="$(calc "1/$GDK_SCALE")"
printf 'export GDK_DPI_SCALE=%q\n' "$GDK_DPI_SCALE"
echo systemctl --user import-environment GDK_SCALE GDK_DPI_SCALE
) | (
if $arg_dry_run; then
cat
else
bash -v
fi
)
|