---
title: "Using Album Art as a Desktop Background with cmus"
date: 2024-01-30
url: https://fortes.com/2024/using-album-art-as-a-desktop-background-with-cmus/
summary: "Making my Linux desktop look like whatever I'm listening to"
---

I live in the terminal all day, so my music player of choice has been [cmus](https://cmus.github.io/) for over a decade now. It's fast, keyboard-focused, and has some nice support for scripting for the terminally-terminal-bound like me. One integration I like is having the current album be the basis of the desktop background; here it is in action:

<figure><a href="/2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid.jpg"><picture>
  <source type="image/webp" srcset="/2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_cc151beca9a04688.webp 400w, /2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_477f41324ccb4c8d.webp 800w, /2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_74b16b3c7fcc9933.webp 1600w" sizes="auto, (max-width: 800px) 100vw, 800px">
  <img src="/2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_6d137b4c7f231124.jpg" srcset="/2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_ab14ebd627fe0422.jpg 400w, /2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_6d137b4c7f231124.jpg 800w, /2024/using-album-art-as-a-desktop-background-with-cmus/2024-cmus-album-background-grid_hu_4f12e14051a3b921.jpg 1600w" sizes="auto, (max-width: 800px) 100vw, 800px" alt="Four example screenshots of an album-based desktop background" width="800" height="452" loading="lazy" decoding="async">
</picture></a>
  <figcaption>Floating terminal in sway, with background based on current album</figcaption>
</figure>


I [originally wrote this script](https://github.com/fortes/dotfiles/blob/01ee8be393575041267ade1dbfe97af32f7816ab/stowed-files/cmus/.local/bin/cmus-album-background.sh) for i3/X, but recently moved over to [Sway](https://swaywm.org/), which required a bunch of updates, so here it is for those who share my unhealthy aversion to GUIs.

First, add this to your cmus config:

```text
set status_display_program=cmus-status
```

Here, `cmus-status` is a bash script I have that does minor processing of the currently-playing track. In order to make the album background script (and our tmux status script) a bit simpler, this helper script writes out metadata for the playing track to a temporary file, that is then read by other scripts. You could probably combine them into one script, but I didn't:

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl"><span class="nv">IFS</span><span class="o">=</span><span class="s1">$&#39;\n\t&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">main<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Args are passed in but annoying to parse, easier to call into `cmus-remote`</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> ! command_exists cmus-remote<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> album
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> albumartist
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> artist
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> cmus_status
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> file
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> mb_track_id
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> player_status
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">status_file_path</span><span class="o">=</span><span class="s2">&#34;/tmp/cmus-status.txt&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> title
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">cmus_status</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>cmus-remote -Q 2&gt;<span class="p">&amp;</span>1<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> grep -q <span class="s2">&#34;cmus is not running&#34;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    rm -f <span class="s2">&#34;</span><span class="si">${</span><span class="nv">status_file_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">player_status</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep -e <span class="s1">&#39;^status&#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> head -n <span class="m">1</span> <span class="p">|</span> awk <span class="s1">&#39;{print $2}&#39;</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">player_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;stopped&#34;</span> <span class="o">||</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">player_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;exiting&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    rm -f <span class="s2">&#34;</span><span class="si">${</span><span class="nv">status_file_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">album</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^tag album &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">albumartist</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^tag albumartist &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">artist</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^tag artist &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">file</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^file &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">mb_track_id</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^tag musicbrainz_trackid &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">title</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>grep <span class="s1">&#39;^tag title &#39;</span> <span class="o">&lt;&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">cmus_status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">|</span> cut -d <span class="s1">&#39; &#39;</span> -f 3-<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  cat &gt; <span class="s2">&#34;</span><span class="si">${</span><span class="nv">status_file_path</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s">&lt;&lt;CMUS_STATUS
</span></span></span><span class="line"><span class="cl"><span class="s">${player_status}
</span></span></span><span class="line"><span class="cl"><span class="s">${title}
</span></span></span><span class="line"><span class="cl"><span class="s">${artist}
</span></span></span><span class="line"><span class="cl"><span class="s">${album}
</span></span></span><span class="line"><span class="cl"><span class="s">${albumartist}
</span></span></span><span class="line"><span class="cl"><span class="s">${mb_track_id}
</span></span></span><span class="line"><span class="cl"><span class="s">${file}
</span></span></span><span class="line"><span class="cl"><span class="s">CMUS_STATUS</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Update status bar if running in tmux</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> -n <span class="s2">&#34;</span><span class="si">${</span><span class="nv">TMUX</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    tmux refresh-client -S
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> -n <span class="si">${</span><span class="nv">WAYLAND_DISPLAY</span><span class="k">:-</span><span class="si">}</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Run in background since PNG generation can take a while</span>
</span></span><span class="line"><span class="cl">    cmus-album-background &gt;&gt; /tmp/cmus-album-background.log 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="p">&amp;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  command_exists cmus-scrobbler <span class="o">&amp;&amp;</span> cmus-scrobbler &gt;&gt; /tmp/cmus-scrobbler.log
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">main <span class="s2">&#34;</span><span class="si">${</span><span class="p">@</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div>

One lesson learned here was to make sure the background-generation (`cmus-album-background`) script runs asynchronously, since otherwise cmus waits for it to complete.

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/usr/bin/env bash
</span></span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Generate desktop background from currently playing album</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl"><span class="nv">IFS</span><span class="o">=</span><span class="s1">$&#39;\n\t&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">default_bg</span><span class="o">=</span><span class="s2">&#34;#222222&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">tmp_art_path</span><span class="o">=</span><span class="s2">&#34;/tmp/cmus-album-bg-blurred.png&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">previous_folder_path</span><span class="o">=</span><span class="s2">&#34;/tmp/cmus-album-folder-path.txt&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">clear_background<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  swaymsg <span class="s2">&#34;output * background </span><span class="si">${</span><span class="nv">default_bg</span><span class="si">}</span><span class="s2"> solid_color&#34;</span>
</span></span><span class="line"><span class="cl">  rm -rf <span class="s2">&#34;</span><span class="si">${</span><span class="nv">tmp_art_path</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">previous_folder_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">main<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> album_dirpath
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> art_path
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> previous_dirpath
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> resolution
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> -z <span class="si">${</span><span class="nv">WAYLAND_DISPLAY</span><span class="si">}</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;Not running under Wayland, aborting&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> ! -f /tmp/cmus-status.txt <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;No cmus status file found, removing background&#34;</span>
</span></span><span class="line"><span class="cl">    clear_background
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">status</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>sed -n 1p /tmp/cmus-status.txt<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">status</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;stopped&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s1">&#39;cmus stopped, removing background&#39;</span>
</span></span><span class="line"><span class="cl">    clear_background
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">album_dirpath</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>sed -n 7p /tmp/cmus-status.txt <span class="p">|</span> xargs -0 dirname<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">previous_dirpath</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>cat <span class="s2">&#34;</span><span class="si">${</span><span class="nv">previous_folder_path</span><span class="si">}</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">album_dirpath</span><span class="si">}</span><span class="s2">&#34;</span> &gt; /tmp/cmus-album-folder-path.txt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">album_dirpath</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">previous_dirpath</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s1">&#39;already set to current album&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">art_path</span><span class="o">=</span><span class="k">$(</span>find <span class="s2">&#34;</span><span class="si">${</span><span class="nv">album_dirpath</span><span class="si">}</span><span class="s2">&#34;</span> -type f -name <span class="s2">&#34;folder.*&#34;</span> 2&gt; /dev/null <span class="p">|</span> head -n 1<span class="k">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> ! -f <span class="s2">&#34;</span><span class="si">${</span><span class="nv">art_path</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;album art file not found in </span><span class="si">${</span><span class="nv">album_dirpath</span><span class="si">}</span><span class="s2">, exiting&#34;</span>
</span></span><span class="line"><span class="cl">    clear_background
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">resolution</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>swaymsg -t get_outputs <span class="p">|</span> jq -r <span class="s1">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">    .[] | select(.focused) | &#34;\(.current_mode.width)x\(.current_mode.height)&#34;
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#39;</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  convert <span class="s2">&#34;</span><span class="si">${</span><span class="nv">art_path</span><span class="si">}</span><span class="s2">&#34;</span> -background <span class="s2">&#34;</span><span class="si">${</span><span class="nv">default_bg</span><span class="si">}</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -scale <span class="s2">&#34;</span><span class="si">${</span><span class="nv">resolution</span><span class="si">}</span><span class="s2">&#34;</span><span class="se">\^</span> -paint <span class="m">6</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -modulate 100,20,100 -fill <span class="s2">&#34;</span><span class="si">${</span><span class="nv">default_bg</span><span class="si">}</span><span class="s2">&#34;</span> -colorize 20% <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="s2">&#34;</span><span class="si">${</span><span class="nv">tmp_art_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;setting background to </span><span class="si">${</span><span class="nv">tmp_art_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  swaymsg <span class="s2">&#34;output &#39;*&#39; background </span><span class="si">${</span><span class="nv">tmp_art_path</span><span class="si">}</span><span class="s2"> fill&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">main <span class="s2">&#34;</span><span class="si">${</span><span class="p">@</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div>

The code is (hopefully) fairly straightforward, but there are a few pieces nerds may find of interest:

- `swaymsg -t get_outputs` gets the resolution of the focused display, which we then use for all other displays. This works fine for my machine since all my monitors have the same resolution, but you may want something different
- `-scale "${resolution}"\^` makes the cover large enough to fill the display while preserving its aspect ratio
- `-paint 6` smears away the details so icons and windows remain readable
- `-modulate 100,20,100` drops the saturation down to 20%; otherwise some backgrounds end up a bit much
- `-colorize 20%` darkens the result a bit, which I found helped a lot with keeping the backgrounds from being too intense
- We cache the previous album path so we can early-exit when there's no update

Finally, `swaymsg` sets the background on every display:

```bash
swaymsg "output '*' background /tmp/cmus-album-bg-blurred.png fill"
```

I really like this script, but in practice I don't actually see my desktop background much since I'm using a tiling window manager. I do see it on the lock screen though. If you pay by the CPU minute, then likely you'd want a script that only generates and sets the background when sway locks, but then you'd miss out on the 0.01% of the time where you're not covering all your monitors with tiled windows, and do you really want to live that dangerously?!

