StTextureCache keeping thousands of icons from the AppIndicator extension
Hi! First of all thanks for GNOME Shell, it's very polished :)
I saw a design problem that may cause performance issues but it's nothing urgent.
Affected version
Arch Linux, running GNOME Shell 41.2
Bug summary
GNOME Shell together with the AppIndicator extension (used to provide tray support for apps) keeps all tray icons ever received, forever, in memory. Closing the applications, disabling the extension or forcing a GC won't release those icons.
This is a problem with apps that update their tray icon frequently. Example with Discord:
- The AppIndicator extension creates StIcon widgets and updates their GIcon whenever necessary.
- Discord 'changes' its tray icon very frequently (when your 'speaking' state changes, i.e. when you glow 'green' in the call or stop glowing).
- For some reason (could be Discord itself, Electron, or the AppIndicator extension), the GIcon passed to
st_icon_set_gicon
is different each time. - StTextureCache keeps all those icons forever (even after Discord has been closed for days, meaning its StIcon is long gone).
- You end up with a highly polluted global atlas, easily keeping thousands of copies of Discord's icons over the course of just one call (see screenshot below).
Steps to reproduce
- Start up Discord and spend some time on a call with someone.
- Look at the global atlas.
What happened
There are lots of copies of the Discord icon!
What did you expect to happen
See only a handful of copies of the Discord icon.
Relevant logs, screenshots, screencasts etc.
Context / suggestions (correct me if wrong)
This is a design problem and it's not clear who's responsibile.
Of course, something's wrong in Discord / Electron / extension since the GIcon is different every time.
But I think it's sensible for an application to update its tray icon on certain events (and they don't necessarily have to come from a file, i.e. could be painted by the app each time) and GNOME Shell shouldn't be accumulating those in memory forever, and especially not when the application has long been closed.
I also understand that the StIcon API was designed for icons coming from the icon theme, so there would be a low amount of GIcons in use (and for anything requiring custom painting, Clutter would be used instead). Loading bitmaps coming from external sources / apps doesn't fit this use case well.
I think the best solution would be to add a hint to StIcon's API to indicate that external icons are being loaded (thus disabling caching or making it less aggressive), which would then be used by the extension.
Alternatively or additionally, the cache in general could be made less aggressive by evicting icons that haven't been used in X time, or restricting each individual StIcon to keep only the last N icons in the cache.