One issue that has come up recently among the folks working on Ubuntu’s icon theme is the poor appearance of the icons for snapped applications, and the inability to work around it (e.g. Gnome snaps in 19.04, 19.04 dailies: logs and system-monitor are suddenly upsteam Gnome icons).
These issues stem from the constraints snapd places on the desktop files provided by snaps. With no way to define new named icons, the only reliable way to structure the .desktop
file is to use a path for the Icon
key. There are two main problems with this:
- icons specified by path rather than icon name can not be overridden by the user’s chosen icon theme.
- icons specified by path can only be represented by a single image file.
While the first may not be particularly desirable for things outside of standard desktop tools (e.g. calculator, character map, etc), the second is likely to be generally useful. For example, while the .snap version of Firefox references a single 128x128 icon in its .desktop file, the .deb version references an icon name :
/usr/share/icons/hicolor/16x16/apps/firefox.png
/usr/share/icons/hicolor/32x32/apps/firefox.png
/usr/share/icons/hicolor/48x48/apps/firefox.png
/usr/share/icons/hicolor/64x64/apps/firefox.png
/usr/share/icons/hicolor/128x128/apps/firefox.png
/usr/share/icons/hicolor/symbolic/apps/firefox-symbolic.svg
The image appropriate to the size it will be rendered is used as the icon. The last is a GNOME extension to cover special monochrome icons that can be rendered in a theme-appropriate colour.
Even when using SVG icons, it may be desirable to provide multiple size versions: a small icon may remove detail and vary stroke thickness to ensure lines are visible at the smaller size.
So it would be useful for snap applications to do something similar to make named icons available to the host system. if we can also do it in a way that would work for a hypothetical snapped desktop, all the better. Below is a proposal for how this could look.
Directory Layout
According to the icon theme spec, an icon theme can be composed of multiple directories spread out over $XDG_DATA_DIRS
, so it shouldn’t be necessary to write to /usr/share/icons
to make icons available.
We already add /var/lib/snapd/desktop
to $XDG_DATA_DIRS
, so dropping icons in /var/lib/snapd/desktop/icons
should make them visible to any conformant implementation. I propose that snapd copy files from the $SNAP/meta/icons
directory to corresponding directories in /var/lib/snapd/desktop
. So if the Firefox snap contained the following file:
$SNAP/meta/icons/hicolor/128x128/apps/firefox.png
… on installation that file would be copied to:
/var/lib/snapd/desktop/icons/hicolor/128x128/apps/firefox.png
Icon Theme Layout
The contents of an icon theme directory are not strongly specified: instead, the index.theme
file describes a set of subdirectories and the types of icons they contain. This means that /usr/share/icons/hicolor/index.theme
will also describe how to interpret the contents of /var/lib/snapd/desktop/icons/hicolor
.
I think there are two ways we could handle this:
-
try to find the
index.theme
for the icon theme, and verify that the snap is providing icons only in those directories for the theme. -
allow the snap to provide icons in any directory that looks like it could be an icon theme subdir. Perhaps requiring 1 to 3 ASCII components would be a reasonable check.
I’m leaning towards (2), since a snap could provide a custom icon for a theme that doesn’t exist on the host system, and that shouldn’t be an error. As we are not installing any index.theme
files, this should just result in the icons being ignored.
What icon names should a snap be allowed to provide?
If Firefox installs a named icon, and references it in it’s .desktop
file, we do not want other snaps to also provide images for that icon name. We probably also don’t want snaps overriding the icons for random applications on the host system. So we probably want to namespace the icon names a snap can provide. One option would be to only allow snaps to provide icons matching snap.${SNAP_NAME}.*
. The snap.
prefix ensures we don’t conflict with host system icon names, and ${SNAP_NAME}
prevents squatting on other snaps’ icon names.
It’s not ideal, but it might be a good place to start. The main complaints I can see are:
-
it’s not going to pick up existing icon overrides. For example, Ubuntu’s Yaru theme provides
Yaru/256x256/apps/org.gnome.Calculator.png
as a custom icon for gnome-calculator. Under this scheme, the gnome-calculator snap can not use this icon name. As Yaru is Ubuntu’s theme, it could probably provide a symlink to the snap icon name to work around this, but it might be hard to convince other theme authors to do the same. -
If we want snaps to be able to provide mime type icons (e.g. LibreOffice providing icons for its document formats), those icon names are named after the mime type with the slash replaced with a dash. So requiring the
snap.
prefix is a problem here. Perhaps this can be set aside until we look at how snaps can register new mime types.
Parallel installed snap instances
If the user installs a snap twice, there’s no guarantee that the two instances will provide the same icons (e.g. one instance on stable, the other instance on edge). This probably means we’d need the following:
- rewrite icon file names to use the correct instance name when copying over to the shared icon theme tree.
- rewrite the
Icon
field in any.desktop
files that happen to specify an icon name to reference the correct instance.