-
Notifications
You must be signed in to change notification settings - Fork 2
/
changeMeWall.spell
executable file
·266 lines (243 loc) · 7.76 KB
/
changeMeWall.spell
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/bin/bash
# Changes the wallpaper to a random one in the `$WALLPAPERS` folder.
# (requires `feh`).
#
# Thanks [matilde](https://github.com/matildeopbravo) for the
# idea and help finding the more contrasting colors for dmenu
set -e
TEMPDIR="/tmp/$LOGNAME"
mkdir -p "$TEMPDIR"
CACHE="${XDG_CACHE_HOME:-~/.cache/}/changeMeWall"
mkdir -p "$CACHE"
show_help() {
exe="$(basename "$0")"
echo -e "Change wallpaper to a random one
\e[36mUsage:\e[0m $exe [OPTIONS...] [Walllpaper...]
\e[36mOptions:\e[0m
-f filter
Pick a wallpaper using grep over the filenames. Random matches will be picked
-s
Show an sxiv image picker. Mark the wallpapers with \`m\` and quit to set.
\e[1mnote:\e[0m Overrides wallpapers passed as arguments.
-w
Force wide screen. Usefull when passing a wallpaper as parameter
-l
List walls instead of picking one
-d
Pick a different wallpaper for each screen
-q | --fast
Skip picking colors from wallpaper for faster setting
\e[36mExamples:\e[0m
Pick a random wallpaper
$ $exe
Choose a specific one
$ $exe path/to/wall1 http://link/to/wall2 etc...
Pick a random one that has a word in it's name
$ $exe -f blue"
}
BRIGHTNESS_FILTER='
import sys
import colorsys
colours = []
for line in sys.stdin:
line = line.strip()
og_line = str(line)
if line.startswith("#"):
line = line[1:]
r = int(line[0:2], 16) / 255
g = int(line[2:4], 16) / 255
b = int(line[4:6], 16) / 255
hsl = colorsys.rgb_to_hls(r, g, b)
text = "#000000" if hsl[1] >= .49 else "#FFFFFF"
colours.append([og_line, (r, g, b), text])
chosen_colours = []
regected_colors = []
print("Rejecting colours with s < 0.20 or v < 0.30", file=sys.stderr)
for colour in colours:
og_line, (r, g, b), __ = colour
hsv = colorsys.rgb_to_hsv(r, g, b)
l, m = (regected_colors, "\033[31mR\033[0m") if hsv[1] < 0.2 or hsv[2] < 0.3 else (chosen_colours, "\033[32mC\033[0m")
l.append(colour)
print(
"{} {:02d}:".format(m, len(regected_colors) + len(chosen_colours)),
og_line,
"r: {:03}".format(r * 255),
"g: {:03}".format(g * 255),
"b: {:03}".format(b * 255),
"h: {:.2f} s: {:.2f} v: {:.2f}".format(*hsv),
file=sys.stderr
)
def rgb_distance(c0, c1):
_, rgb0, _ = c0
_, rgb1, _ = c1
return ((rgb0[0] - rgb1[0]) * (rgb0[0] - rgb1[0])
+ (rgb0[1] - rgb1[1]) * (rgb0[1] - rgb1[1])
+ (rgb0[2] - rgb1[2]) * (rgb0[2] - rgb1[2]))
if len(chosen_colours) < 3:
chosen_colours = chosen_colours + regected_colors
first = chosen_colours[0]
contrast = chosen_colours[1]
max_distance = rgb_distance(first, chosen_colours[1])
for c in chosen_colours[2:]:
d = rgb_distance(first, c)
if d > max_distance:
max_distance = d
contrast = c
second = chosen_colours[1 if contrast != chosen_colours[1] else 2]
for c, _, t in [first, second, contrast]: print(c, t)
'
[[ "$XDG_SESSION_TYPE" = wayland ]] && wayland=1
wide=0
while [ "$#" -gt 0 ]; do
case "$1" in
-f) # filter to pass to grep for wallpaper searching
filter="$2"
shift
;;
-s)
nsxiv=1
;;
-w)
wide=1
;;
-l)
list_mode=1
;;
-d | --different)
different=1
;;
--wait-for-colors)
wait_for_colors=1
;;
-h | --help)
show_help
exit 1
;;
-q | --fast)
fast=1
;;
-*)
echo "Invalid option '$1'"
exit 1
;;
*)
files+=("$1")
;;
esac
shift
done
if [[ "$nsxiv" ]]; then
if [[ "$filter" ]]; then
mapfile -t files < <(find -H "$WALLPAPERS" -type f |
grep -iP "/[^/]*${filter}[^/]*$" |
nsxiv -tio
)
else
mapfile -t files < <(nsxiv -to "$WALLPAPERS")
fi
elif [[ "${#files[@]}" = 0 ]]; then
mapfile -t files < <(find -H "$WALLPAPERS" -type f |
grep -iP "/[^/]*${filter}[^/]*$")
fi
[[ "${#files[@]}" = 0 ]] && exit
if [[ $list_mode ]]; then
printf "%s\n" "${files[@]}"
exit 0
fi
if [[ "$different" ]]; then
size=$(xrandr --query | grep ' connected' -c)
else
size=1
fi
mapfile -t files < <(printf "%s\n" "${files[@]}" | grep -v mtg | shuf -n "$size")
i=1
for file in "${files[@]}"; do
[ "$wide" -gt 0 ] && break
if [[ "$file" = *wide* ]]; then
wide=$i
else
aspect_ratio="$(convert "$file" -format '%[fx:w/h]' info:)"
wide=$(echo "$aspect_ratio" | awk '$0 >= 2.5 {found=1}
END {if(found) {print '$i'} else {print "0"}}')
i=$((i + 1))
fi
done
unset i
[ "$wide" -gt 0 ] && files=("${files[$((wide - 1))]}")
[ "$fast" ] || {
cached_colors="$CACHE/${files[0]//\//%}"
echo "Cache is: $cached_colors"
if [[ -f "$cached_colors" ]]; then
mapfile -t colors < "$cached_colors"
else
mapfile -t colors < <(
convert "${files[0]}" +dither -colors 10 histogram: |
sed -n '/comment={/,/^}/p' |
sed -E 's/comment=\{\s*|\}|^\s*//g' |
awk '/[0-9]e\+[0-9]/ { split($0, s, "e+"); base=s[1]; split(s[2], ss, ":"); exponent=ss[1]; print((base * (10^exponent)) ":" ss[2]); }
$0 !~ /[0-9]e\+[0-9]/ {print}' |
sort -nr |
grep -aoP '#[a-fA-F0-9]{6}' |
python3 -c "$BRIGHTNESS_FILTER" |
head -3
)
printf "%s\n" "${colors[@]}" > "$cached_colors"
fi
echo "Picking ${colors[*]}"
# Dmenu colors
printf "%s\n" "${colors[@]}" >| "$TEMPDIR/wall_colors"
set -x
if [[ "$wayland" ]]; then
printf "%s\n" "${colors[@]}"
if pgrep river 2>/dev/null; then
function convert { c="${1/\#/0x}"; echo "${c% *}"; }
riverctl border-color-focused "$(convert "${colors[0]}")"
riverctl border-color-unfocused "$(convert "${colors[2]}")"
elif pgrep Hyprland 2>/dev/null; then
function convert { c="${1#\#}"; echo "${c% *}"; }
hyprctl keyword general:col.active_border "rgb($(convert "${colors[0]}"))"
hyprctl keyword general:col.inactive_border "rgb($(convert "${colors[2]}"))"
fi
else
if command -v herbstclient &>/dev/null; then
herbstclient attr theme.active.color "${colors[0]% *}"
herbstclient attr theme.normal.color "${colors[2]% *}"
herbstclient attr settings.frame_border_active_color "${colors[0]% *}"
herbstclient attr settings.frame_border_normal_color "${colors[1]% *}"
fi &
fi
# Lamp colors
if [[ "$(hostname)" = tolaria ]] || nmcli -t dev | grep -q 'ZON.*2010' ; then
#shellcheck disable=2029
set +e
[ -e "$TEMPDIR/mood_light" ] ||
ssh mendess@mendess.xyz -o BatchMode=yes \
"python ~/bulb/color.py \\${colors[0]% *} --flow --sleep"
set -e
fi
wait
set +x
} 2>&1 | color_picker -f &
printf "Setting: %s\n" "${files[@]}" | tee "$TEMPDIR/last-wall"
[[ "$wait_for_colors" ]] && wait
if [ "$wayland" ]; then
set -x
for i in $(seq 0 ${#files[@]}); do
if [[ "${files[$i]}" ]] && ! [[ -e ${files[$i]} ]]; then
f=$(mktemp)
wget "${files[$i]}" -O "$f"
files[$i]="$f"
fi
done
swww img "${files[@]}" \
-t simple \
--transition-step 2
set +x
else
if [ "$wide" -gt 0 ]; then
feh --no-fehbg --bg-fill --no-xinerama "${files[@]}"
else
feh --no-fehbg --bg-fill "${files[@]}"
fi
fi
[[ "$wait_for_colors" ]] || wait