derf / feh

a fast and light image viewer
https://feh.finalrewind.org
Other
1.53k stars 159 forks source link

SIGUSR1 trigger fails to refresh sometimes #683

Open chconnor opened 1 year ago

chconnor commented 1 year ago

I have a symlink pointing to an image. I periodically overwrite the symlink to point to a different image, then send SIGUSR1 to prompt a reload.

It only works a minority of the time. After a ton of experimentation, I was able to increase the percentage of time that it would work by touch()'ing the symlink, touch()'ing the file the symlink pointed to, and all kinds of crazy other things that shouldn't work but did.

To test this, I would generate a series of images, and create a symlink "link.png" to one. Then I start "feh link.png", and find the pid. Then I run commands like this:

ln -sf actual_image1.png link.png; kill -SIGUSR1 <feh_pid>
ln -sf actual_image2.png link.png; kill -SIGUSR1 <feh_pid>
ln -sf actual_image3.png link.png; kill -SIGUSR1 <feh_pid>
ln -sf actual_image4.png link.png; kill -SIGUSR1 <feh_pid>

...often it will work for some of them but between a couple files it will consistently fail. The pattern was impossible to figure out, and seemed to change sometimes. After all this poking and prodding, I was left with the feeling that somewhere (Imlib2?) there is caching that is buggy and basically unpredictable, and which is not correctly identifying that the image has "changed". No combination of touch()'ing or sync'ing or whatever could 100% convince feh to update.

In the code, I changed the call on this line to be:

            feh_reload_image(winwid, 0, 1);

...i.e. change the last 0 to a 1 to "force_new". This fixes the issue for me -- it now refreshes every time I send SIGUSR1.

I tried to prepare a set of demonstration images, but the pattern of when it fails is so unpredictable that I'm not sure how much value there would even be in uploading them somewhere. Let me know if I should try and I will.

avlec commented 1 year ago

This change would only work if filelist_len <= 1, and it also doesn't handle reloading multiple windows. To me this seems like it would need to be a bit more flushed out. Perhaps SIGUSR3 could be dedicated for a refresh, and that receiving it would update single windows with filelist_len > 1 and would also refresh multiple windows.

chconnor commented 1 year ago

Understood, and thanks for the response. In my application I'm only viewing one image at a time on one window, so this workaround works for me. Whatever the correct solution is, it would be greatly appreciated to be able to reliably trigger a refresh. I couldn't find other appropriate solutions besides feh to make this happen. Thanks!