├── README.md
├── feh-blur
└── untitled.gif
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | feh-blur-wallpaper
12 |
13 |
14 |
15 | kiddae's fork : Blur your desktop wallpaper when windows are open (Linux)
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Blurs your desktop wallpaper when windows are open.
25 | This is a fork, with added support for minimized/activated windows: if you minimize your windows in openbox for example, your wallpaper also blurs!
26 | Runs as a service, blurring any wallpaper set by [feh].
27 | Works great with [i3wm], but should work with any Linux window manager! 🎉
28 |
29 | ## Usage
30 |
31 | Run `feh-blur`. (Tip: optionally, you can pass `-d` to it to run it in the background.)
32 |
33 | ```sh
34 | # Step 1: run the feh-blur service
35 | $ feh-blur
36 |
37 | >> Monitoring changes
38 | feh-blur will now blur any wallpapers set using 'feh'.
39 |
40 | >> Found wallpaper
41 | /home/rsc/wallpapers/unsplash.jpg
42 | Generating blurred images... done.
43 | ```
44 |
45 | Set a wallpaper using [feh]. You can do this before starting feh-blur, or while feh-blur is running.
46 |
47 | ```
48 | feh --bg-fill "/path/to/yourwallpaper.jpg"
49 | ```
50 |
51 | See `feh-blur --help` for full usage options.
52 |
53 | ```
54 | Usage: feh-blur [-v|--verbose]
55 |
56 | Options:
57 | -b, --blur N set blur strength to N (4...128, default 32)
58 | --darken N darken image by N (4...100, default 32)
59 | --lighten N lengthen image by N (4...100, default 0)
60 | -c, --uncontrast reduce contrast
61 | --save-image PATH save blurred image to PATH
62 | --no-animate skip fading animation
63 |
64 | Daemon options:
65 | -d, --daemon run in background
66 | -s, --stop stop previously-ran daemon
67 |
68 | Other options:
69 | -v, --verbose show more messages
70 | -q, --quiet supress messages
71 | ```
72 |
73 | ## Installation
74 |
75 | Install [feh-blur](./feh-blur) somewhere. You may also need some dependencies, install them using your Linux distro's appropriate package manager.
76 |
77 | ```sh
78 | # Arch Linux
79 | sudo pacman -S wmctrl graphicsmagick feh
80 |
81 | # Ubuntu and alike
82 | sudo apt install wmctrl graphicsmagick feh
83 | ```
84 |
85 | ## Prior art
86 |
87 | Based on [ganifladi/blurme](https://github.com/ganifladi/blurme). feh-blur-wallpaper has been written from the ground up, using some parts of blurme as reference.
88 |
89 | ## Thanks
90 |
91 | **feh-wallpaper-blur** © 2019, Rico Sta. Cruz. Released under the [MIT] License.
92 | Authored and maintained by Rico Sta. Cruz with help from contributors ([list][contributors]).
93 |
94 | > [ricostacruz.com](http://ricostacruz.com) ·
95 | > GitHub [@rstacruz](https://github.com/rstacruz) ·
96 | > Twitter [@rstacruz](https://twitter.com/rstacruz)
97 |
98 | [](https://github.com/rstacruz)
99 | [](https://twitter.com/rstacruz)
100 |
101 | [mit]: http://mit-license.org/
102 | [contributors]: http://github.com/rstacruz/feh-wallpaper-blur/contributors
103 | [feh]: https://wiki.archlinux.org/index.php/feh
104 | [i3wm]: https://i3wm.org/
105 |
--------------------------------------------------------------------------------
/feh-blur:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://github.com/rstacruz/feh-blur
3 |
4 | if [[ "$1" != "--worker" ]]; then
5 | # Where to write stuff
6 | export CACHE_DIR="/tmp/feh-blur.$$"
7 |
8 | # How much to blur (--blur N)
9 | export BLUR_STRENGTH="32"
10 |
11 | # Contrast (--uncontrast)
12 | export REDUCE_CONTRAST="0"
13 |
14 | # How much to dim (--dim N)
15 | export DIM_STRENGTH="32"
16 |
17 | # Dimmer
18 | export DIM_COLOR="#000"
19 |
20 | # Where to write the final blurred image (--save-image PATH)
21 | export BLUR_IMAGE_SAVE_LOCATION=""
22 |
23 | # Interval between frames in an animation
24 | export ANIMATION_INTERVAL=0.005
25 |
26 | # Fade in and out?
27 | export ANIMATE_FADE=1
28 |
29 | # Interval to check with wmctrl
30 | export POLL_INTERVAL=0.3
31 |
32 | # The verbosity. --verbose sets this to 2, and --quiet sets it to 0.
33 | export VERBOSE=1
34 | fi
35 |
36 | # The name of this program
37 | export BIN="$(basename "$0")"
38 |
39 | # Expression for proc grepping
40 | PROC_EXPR="bash.*$(basename "$0")"
41 |
42 | # Run mode. -d sets this to background (daemon) mode.
43 | # Values: background | foreground | noop
44 | MODE=foreground
45 |
46 | # Guard so that do_cleanup will only be invoked once.
47 | CLEANING_UP=0
48 |
49 | # Image extension to use. 'ppm' is used because it's faster to read/write to, I
50 | # think.
51 | EXT="ppm"
52 |
53 | # The original source.
54 | wall_original="$CACHE_DIR/original.$EXT"
55 |
56 | # Echo some info. Only if verbose=1
57 | info () {
58 | if [[ "$VERBOSE" -gt 0 ]]; then
59 | echo " $1"
60 | fi
61 | }
62 |
63 | head () {
64 | if [[ "$VERBOSE" -gt 0 ]]; then
65 | echo ""
66 | echo -e " \033[31m>>\033[32m $1\033[0m"
67 | fi
68 | }
69 |
70 | # Log some debug info
71 | debug () {
72 | if [[ "$VERBOSE" -gt 1 ]]; then
73 | echo " - $1"
74 | fi
75 | }
76 |
77 | # Generate a bunch of images
78 | generate_blurred_images () {
79 | mkdir -p "$CACHE_DIR"
80 | local source="$1"
81 | local original="$CACHE_DIR/original.$EXT"
82 |
83 | gm convert "$source" -resize 1920x "$original"
84 |
85 | head "Found wallpaper"
86 | info "$source"
87 | info "Generating blurred images..."
88 |
89 | local fx1=""
90 | local fx2=""
91 | local fx3=""
92 |
93 | if [[ "$BLUR_STRENGTH" != "0" ]]; then
94 | fx1="$fx1 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 4 )) -scale 400%"
95 | fx2="$fx2 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 2 )) -scale 400%"
96 | fx3="$fx3 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 1 )) -scale 400%"
97 | fi
98 |
99 | if [[ "$REDUCE_CONTRAST" = "1" ]]; then
100 | fx1="+contrast $fx1"
101 | fx2="+contrast +contrast $fx2"
102 | fx3="+contrast +contrast +contrast $fx3"
103 | fi
104 |
105 | if [[ "$DIM_STRENGTH" != "0" ]]; then
106 | fx1="$fx1 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 4 ))%"
107 | fx2="$fx2 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 2 ))%"
108 | fx3="$fx3 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 1 ))%"
109 | fi
110 |
111 | gm convert "$original" \
112 | $fx1 \
113 | "$CACHE_DIR/blur-0.$EXT"
114 | gm convert "$CACHE_DIR/blur-0.$EXT" \
115 | $fx2 \
116 | "$CACHE_DIR/blur-1.$EXT"
117 | gm convert "$CACHE_DIR/blur-0.$EXT" \
118 | $fx3 \
119 | "$CACHE_DIR/blur-final.$EXT"
120 |
121 | if [[ -n "$BLUR_IMAGE_SAVE_LOCATION" ]]; then
122 | gm convert \
123 | "$CACHE_DIR/blur-final.$EXT" \
124 | "$BLUR_IMAGE_SAVE_LOCATION"
125 | fi
126 |
127 | info "Done."
128 | }
129 |
130 | # Get current feh wallpaper
131 | get_feh_wallpaper() {
132 | tail -n1 "$HOME/.fehbg" | sed 's/--no-fehbg //g' | cut -d' ' -f3 | sed "s/'//g"
133 | }
134 |
135 | # Get wallpaper mode like --bg-tile
136 | get_feh_wallpaper_mode() {
137 | tail -n1 "$HOME/.fehbg" | sed 's/--no-fehbg //g' | cut -d' ' -f2 | sed "s/'//g"
138 | }
139 |
140 | # get_current_workspace => "2"
141 | get_current_workspace() {
142 | # 2 * DG: N/A VP: 0,0 WA: N/A Name
143 | wmctrl -d | grep '\*' | cut -d' ' -f1
144 | }
145 |
146 | # get_open_windows_count() => "2"
147 | get_open_windows_count() {
148 | count=0
149 | workspace="$(get_current_workspace)"
150 | for id in $(wmctrl -l | cut -d' ' -f1);do
151 | if [[ $(wmctrl -l | grep $id | cut -d' ' -f3) == $workspace ]]
152 | then
153 | xprop -id "$id" | grep -Fq 'window state: Iconic' || ((count++))
154 | fi
155 | done
156 | echo $count
157 | }
158 |
159 | is_blank() {
160 | count=$(get_open_windows_count)
161 | [[ "$count" -eq 0 ]]
162 | }
163 |
164 | set_blurred_wallpaper() {
165 | debug "Setting blurred wallpaper"
166 | local mode="$1" # --bg-tile
167 |
168 | if [[ "$ANIMATE_FADE" == 1 ]]; then
169 | # We're going to redirect output to /dev/null to supress feh warnings
170 | feh --no-fehbg "$mode" "$CACHE_DIR/blur-0.$EXT" &> /dev/null
171 | sleep $ANIMATION_INTERVAL
172 | feh --no-fehbg "$mode" "$CACHE_DIR/blur-1.$EXT" &> /dev/null
173 | sleep $ANIMATION_INTERVAL
174 | fi
175 |
176 | feh --no-fehbg "$mode" "$CACHE_DIR/blur-final.$EXT" &> /dev/null
177 | }
178 |
179 | set_original_wallpaper() {
180 | debug "Setting original wallpaper"
181 | local mode="$1" # --bg-tile
182 |
183 | if [[ "$ANIMATE_FADE" == 1 ]]; then
184 | feh --no-fehbg "$mode" "$CACHE_DIR/blur-1.$EXT" &> /dev/null
185 | sleep $ANIMATION_INTERVAL
186 | feh --no-fehbg "$mode" "$CACHE_DIR/blur-0.$EXT" &> /dev/null
187 | sleep $ANIMATION_INTERVAL
188 | fi
189 |
190 | feh --no-fehbg "$mode" "$wall_original" &> /dev/null
191 | }
192 |
193 | kill_other_instances() {
194 | if [[ "$(pgrep -fcl "$PROC_EXPR")" -gt 1 ]]; then
195 | head "Stopping other instances of $BIN..."
196 |
197 | local count=1
198 | while [[ "$(pgrep -fcl "$PROC_EXPR")" -gt 1 ]]; do
199 | count=$(( count + 1 ))
200 | old_pid="$(pgrep -fo "$PROC_EXPR")"
201 |
202 | # Kill it; if it refuses after some time, force-stop it
203 | if [[ "$count" -gt 10 ]]; then
204 | kill -9 "$old_pid"
205 | else
206 | kill "$old_pid"
207 | fi
208 | sleep 0.1
209 | done
210 | fi
211 | }
212 |
213 | run_loop () {
214 | prev_blank="-"
215 | prev_wallpaper="-"
216 | first_run="1"
217 |
218 | while true; do
219 | wallpaper="$(get_feh_wallpaper)"
220 |
221 | # Check if wallpaper has changed.
222 | if [[ "$prev_wallpaper" != "$wallpaper" ]]; then
223 | wallpaper_mode="$(get_feh_wallpaper_mode)"
224 |
225 | # If there's no wallpaper, try again later.
226 | if [[ -z "$wallpaper" ]]; then
227 | sleep "$POLL_INTERVAL"
228 | continue
229 | else
230 | generate_blurred_images "$wallpaper"
231 | prev_wallpaper="$wallpaper"
232 | prev_blank=""
233 | fi
234 | fi
235 |
236 | blank="$(is_blank && echo 1 || echo 0)"
237 | if [[ "$prev_blank" != "$blank" ]]; then
238 | if [[ "$blank" == 0 ]]; then
239 | set_blurred_wallpaper "$wallpaper_mode"
240 | elif [[ "$first_run" == "0" ]]; then
241 | # Skip set_original_wallpaper if we were started without
242 | # an active window so that the animation is skipped
243 | set_original_wallpaper "$wallpaper_mode"
244 | fi
245 | prev_blank="$blank"
246 | fi
247 |
248 | first_run=0
249 | sleep "$POLL_INTERVAL"
250 | done
251 | }
252 |
253 | show_help() {
254 | echo "Usage: $BIN [-v|--verbose]"
255 | echo ''
256 | echo 'Options:'
257 | echo ' -b, --blur N set blur strength to N (4...128, default 32)'
258 | echo ' --darken N darken image by N (4...100, default 32)'
259 | echo ' --lighten N lengthen image by N (4...100, default 0)'
260 | echo ' -c, --uncontrast reduce contrast'
261 | echo ' --save-image PATH save blurred image to PATH'
262 | echo ' --no-animate skip fading animation'
263 | echo ''
264 | echo 'Daemon options:'
265 | echo ' -d, --daemon run in background'
266 | echo ' -s, --stop stop previously-ran daemon'
267 | echo ''
268 | echo 'Other options:'
269 | echo ' -v, --verbose show more messages'
270 | echo ' -q, --quiet supress messages'
271 | echo ''
272 | }
273 |
274 | parse_opts() {
275 | while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
276 | -h | --help)
277 | MODE=noop
278 | show_help
279 | ;;
280 | -V | --version )
281 | MODE=noop
282 | echo version
283 | ;;
284 | -b | --blur )
285 | shift
286 | BLUR_STRENGTH="$1"
287 | ;;
288 | -c | --uncontrast )
289 | REDUCE_CONTRAST=1
290 | ;;
291 | --save-image )
292 | shift
293 | BLUR_IMAGE_SAVE_LOCATION="$1"
294 | ;;
295 | --no-animate )
296 | ANIMATE_FADE=0
297 | ;;
298 | -D | --dim | --darken )
299 | shift
300 | DIM_COLOR="#000"
301 | DIM_STRENGTH="$1"
302 | ;;
303 | --lighten )
304 | shift
305 | DIM_COLOR="#fff"
306 | DIM_STRENGTH="$1"
307 | ;;
308 | --tint-color )
309 | shift
310 | DIM_COLOR="$1"
311 | ;;
312 | --tint-strength )
313 | shift
314 | DIM_STRENGTH="$1"
315 | ;;
316 | -d | --daemon )
317 | MODE=background
318 | ;;
319 | -s | --stop )
320 | MODE=stop
321 | ;;
322 | -q | --quiet )
323 | VERBOSE=0
324 | ;;
325 | -v | --verbose )
326 | VERBOSE=2
327 | ;;
328 | esac; shift; done
329 | if [[ "$1" == '--' ]]; then shift; fi
330 | }
331 |
332 | ensure_feh() {
333 | if ! command -v feh >/dev/null; then
334 | echo "$BIN requires Feh to set wallpapers."
335 | exit
336 | fi
337 | }
338 |
339 | # Ensure that 'graphicsmagick' is available.
340 | ensure_gm() {
341 | if ! command -v gm >/dev/null; then
342 | echo "$BIN requires GraphicsMagick to set wallpapers."
343 | exit
344 | fi
345 | }
346 |
347 | ensure_wmctrl() {
348 | if ! command -v wmctrl >/dev/null; then
349 | echo "$BIN requires wmctrl to detect events."
350 | exit
351 | fi
352 | }
353 |
354 | print_usage() {
355 | head "Monitoring changes"
356 | info "$BIN will now blur any wallpapers set using 'feh'."
357 | info "To change your wallpaper, try:"
358 | info ""
359 | info " feh --bg-tile your-image.jpg"
360 | }
361 |
362 | main() {
363 | ensure_feh
364 | ensure_gm
365 | ensure_wmctrl
366 | parse_opts "$@"
367 |
368 | case "$MODE" in
369 | background)
370 | kill_other_instances
371 | print_usage
372 | "$0" --worker --quiet & disown
373 |
374 | head "Background mode"
375 | info "$BIN started in background mode!"
376 | info "To stop, use '$BIN --stop'."
377 | ;;
378 |
379 | stop)
380 | kill_other_instances
381 | ;;
382 |
383 | noop)
384 | exit
385 | ;;
386 |
387 | *)
388 | kill_other_instances
389 | print_usage
390 | run_loop
391 | ;;
392 | esac
393 | }
394 |
395 | # Perform cleanup operations before stopping.
396 | do_cleanup () {
397 | # Guard clause so that it's only ran once
398 | if [[ "$CLEANING_UP" == "1" ]]; then return; fi
399 | CLEANING_UP=1
400 |
401 | rm -rf "$CACHE_DIR"
402 |
403 | # Restore original wallpaper before exiting
404 | if [[ "$MODE" == "foreground" ]] && [[ -e "$HOME/.fehbg" ]]; then
405 | head "Restoring original wallpaper"
406 | source "$HOME/.fehbg"
407 | fi
408 | }
409 |
410 | finish () {
411 | do_cleanup
412 | exit 1
413 | }
414 |
415 | trap finish EXIT
416 | trap finish SIGHUP
417 | trap finish SIGINT
418 | trap finish SIGTERM
419 | main "$@"
420 |
--------------------------------------------------------------------------------
/untitled.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kiddae/feh-blur-wallpaper/1d5d18f9f3a69ce37accd5daea61542b02ee46e1/untitled.gif
--------------------------------------------------------------------------------