5

In Ubuntu 20.04, I use a custom png file that graphically displays stats on CPU usage, disk space, etc as background image. It works fine to set the image as background (right click on desktop -> Settings -> Background -> Add Picture).

However, when the image is modified, the background isn't updated; even after reboot. (in Ubuntu 18.04, this was the case)

How can I make Ubuntu automatically update the background when the underlying image file changes?


Messy solution:

Based on Vikki's and vanadiums replies, I found a hack that works:

cd ~/.local/share/backgrounds
rm ./<copy_of_the_background_file>
ln -s <path_to_original_background_file> ./<copy_of_the_background_file>

Install a crontab which does

touch -h ~/.local/share/backgrounds/<copy_of_the_background_file>

in regular intervals (like each minute or so).

This way, if <path_to_original_background_file> is overwritten by a new version, the symbolic link will point to the new file.


Does anyone know a cleaner way to do that? Is there a way to modify the path where gnome looks for the background image?

Thomas Ward
  • 78,878
dani
  • 51

2 Answers2

5

When you set a background from a custom graphic, a copy of it is created in your .local/share/backgrounds folder. That copy is being used as the background. You therefore need to modify that copy to make it work.

The desktop will automatically update if the file is modified in place or if another graphic is copied over the file (cp <another_graphic> <yourbackground>), i.e., provided the file inode does not change. Deleting the file or moving it, and then rename another will not work: your background will turn black. Only setting it back using the settings or logging out then back in will restore it in that case.

vanadium
  • 97,564
0

Use inotifywait

This is a cleaner solution.

inotifywait does not waste CPU resources to check for changes when the file hasn't been edited. Instead, it only returns a value when the file has been changed. This means we can use it in a while loop:

# find your background file, which may be png or jpg.
BGfile = find ~/.local/share/backgrounds/ -iname '*.png' -or -iname '*.jpg'

while inotifywait -e attrib /path/to/original/background/image.jpg do cp /path/to/original/background/image.jpg ${BGfile} # direct overwriting hack mentioned by @vanadium done

This script starts an instance of inotifywatch to watch out for changes to the metadata (attrib) of the original background image file. When the metadata finally changes, inotifywatch terminates, and returns a true value. This trigger the copying action inside the loop, and then a new instance of inotifywatch is started at the beginning of the while loop again.


Things to watch out for:

  1. Different options than attrib might be required on your computer, depending on the operating system. Play around, set up some experiments, to find out which one does your operating system and Ubuntu version works best with. (My old Ubuntu 18.04 worked well with close_write, but my new Ubuntu 22.04 works best with attrib)
  2. If you wish to run this in the background without a terminal, you don't need to use crontab. You can simply wrap it in nohup and put it into a script like so:
if [[ -z $(pgrep inotifywait) ]]; then # ignore this line if an "inotifywait" process is already running; ensures idempotency.
  nohup bash -c 'while inotifywait -e attrib /path/to/original/background/image.jpg; do cp /path/to/original/background/image.jpg ~/.local/share/backgrounds/<target_image.jpg>; done' &>/tmp/nohup-inotifywait.out &
fi

You can then run this script from the terminal, which would then detach itself and print any outputs and errors into /tmp/nohub-inotifywait.out. Then this while loop will still exist in the background even after you've closed the terminal.

  1. If you want this script to run upon start up, you can use the "Startup Application Preferences" app:

Startup Application Preferences

For example, I have named my script inotifyActions.sh and saved it at ~/.

enter image description here

Then this way, you don't even need to start your terminal and run "~/inotifyActions.sh" every time you start your computer - it runs in the background automatically as soon as you start it.

(Hope this helps someone down the line!)

Ocean Wong
  • 512
  • 5
  • 9