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
  • 72,494
  • 30
  • 173
  • 237
dani
  • 51
  • 3
  • I just tried this by replacing the image file with another, and by editing the image in-situ. Both times the background refreshed immediately. Ubuntu 21.10 on Xorg. I've not done anything specific to force this behaviour, it seems to be stock. The BG files were under my home path, so not sure if that makes a difference. – lsm_datsci Dec 19 '21 at 15:07
  • Not sure if this is [the XY problem](https://meta.stackexchange.com/q/66377/167668) here but [there](https://askubuntu.com/q/1014263/38631) [are](https://extensions.gnome.org/extension/1064/system-monitor/) [Gnome](https://extensions.gnome.org/extension/120/system-monitor/) [extensions](https://extensions.gnome.org/extension/3748/the-circles-desktop-widget/) to display this kind of information. – Didier L Dec 19 '21 at 23:51
  • Welcome to Ask Ubuntu. This is a question answer site. Please don't put your solution inside the question. Please click on the **Answer Your Own Question** below and write your answer there. Then after the required waiting period you may mark the correct answer by clicking on the gray check mark ✔️ and turning it green ✅. This will help others. – user68186 Dec 21 '21 at 14:30
  • Thanks @user68186. I've done that. I'm hesitant to add a check mark as there isn't an answer that really solves the problem in a clean way yet. – dani Dec 23 '21 at 10:28

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
  • 82,909
  • 6
  • 116
  • 186
  • 1
    Yes, but how do you force Ubuntu to update the `.local/share/backgrounds` copy when the source image is modified? – Vikki Dec 19 '21 at 22:28
  • In my experience, when I copy a different graphic over the one set as background, the background is immediately updated. Will not work with move and renaming another file - will add this to the answer. – vanadium Dec 20 '21 at 07:16
  • @vanadium That's my experience with Ubuntu 18.04 too, but it doesn't work with my new 20.04 installation for some reason. – dani Dec 20 '21 at 12:30
  • For me it works on Ubuntu 20.10, so indeed perhaps there is something else going on in 20.04. Will test if I have the opportunity to run a 20.04. – vanadium Dec 20 '21 at 12:32
  • 1
    Thanks for your hints, vanadium and @Vikki ! Creating a symbolic link in `~/.local/share/backgrounds` to the original file does the trick. – dani Dec 20 '21 at 12:51
  • @vanadium I accidentally edited your post. Sorry, I didn't mean to do that; please revert my change. (I can't) – dani Dec 20 '21 at 12:52
  • Where does gnome store the path to the background picture that it actually uses? I. e. `.local/share/backgrounds/` @vanadium – dani Dec 21 '21 at 14:10
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
  • 453
  • 4
  • 5