Getting themed icons to work with snap

I’m trying to support icon themes in my snap. I’ve prefixed my icons with snap.$CRAFT_PROJECT_NAME and replaced the icon name in .desktop file with sed via override-pull. But snapcraft still replaces the icon name with the path to meta/gui/icon.png. If I try to copy the .desktop file to meta/gui with other name rather than $CRAFT_PROJECT_NAME, I get additional .desktop file with proper icon support. The problem is that there becomes two .desktop file and I can’t find a way to prevent snapcraft from generating it.

I assume it happens due to this, that and that code. I tried to remove the desktop key from the part but this doesn’t help, perhaps because I have parse-info key but I don’t want to remove it as I do want the remaining metadata to be imported, just not the desktop file to get icon theme support screwed then.

Can I somehow support icon themes with parse-info?

@jamesh can you help with this?

The initial .desktop file

[Desktop Entry]
Name=Telegram
Comment=New era of messaging
TryExec=telegram-desktop
Exec=telegram-desktop -- %u
Icon=snap.telegram-desktop.
Terminal=false
StartupWMClass=TelegramDesktop
Type=Application
Categories=Chat;Network;InstantMessaging;Qt;
MimeType=x-scheme-handler/tg;x-scheme-handler/tonsite;
Keywords=tg;chat;im;messaging;messenger;sms;tdesktop;
Actions=quit;
DBusActivatable=true
SingleMainWindow=true
X-GNOME-UsesNotifications=true
X-GNOME-SingleWindow=true

[Desktop Action quit]
Exec=telegram-desktop -quit
Name=Quit Telegram
Icon=application-exit

The .desktop file after snapcraft’s changes

[Desktop Entry]
Name=Telegram
Comment=New era of messaging
TryExec=telegram-desktop
Exec=telegram-desktop -- %u
Icon=${SNAP}/meta/gui/icon.png
Terminal=false
StartupWMClass=TelegramDesktop
Type=Application
Categories=Chat;Network;InstantMessaging;Qt;
MimeType=x-scheme-handler/tg;x-scheme-handler/tonsite;
Keywords=tg;chat;im;messaging;messenger;sms;tdesktop;
Actions=quit;
DBusActivatable=true
SingleMainWindow=true
X-GNOME-UsesNotifications=true
X-GNOME-SingleWindow=true

[Desktop Action quit]
Exec=telegram-desktop -quit
Name=Quit Telegram
Icon=${SNAP}/meta/gui/icon.png

Both the snap.telegram-desktop. provided by snap and the system application-exit get replaced with ${SNAP}/meta/gui/icon.png. While the first one just prevents application icon from being themed, the second one replaces the action icon with application icon what is inappropriate.

It’s been a while since I’ve exercised this code, but things seemed to work in this bare-bones project I tried:

name: themed-icon-test # you probably want to 'snapcraft register <name>'
base: core24 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  themed-icon-test:
    command: foo.sh
    desktop: foo.desktop
    plugs: [desktop]

parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: nil
    override-build: |
      cat << \EOF > $CRAFT_PART_INSTALL/foo.sh
      #!/bin/sh
      EOF
      chmod a+x $CRAFT_PART_INSTALL/foo.sh

      cat << \EOF > $CRAFT_PART_INSTALL/foo.desktop
      [Desktop Entry]
      Exec=themed-icon-test
      Icon=snap.themed-icon-test.foo
      Name=Test
      EOF

      mkdir -p $CRAFT_PART_INSTALL/meta/gui/icons/hicolor/apps
      touch $CRAFT_PART_INSTALL/meta/gui/icons/hicolor/apps/snap.themed-icon-test.foo.png

The Icon= line in the desktop file Snapcraft wrote to $SNAP/meta/gui/themed-icon-test.desktop was left as is. It also looked fine in the version snapd wrote when installing the snap too.

Is there anything obvious you’re doing different to my minimal example?

As I already mentioned, I believe part’s desktop/parse-info + top-level adopt-info key are at fault. While I don’t mind removing the desktop key, I need adopt-info/parse-info but they apparently set the desktop key implicitly based on the metainfo content.

I have a WIP branch, it needs a rebase on top of other branch in order to be buildable though.

Okay. Here is an updated version of the test program that does reproduce what you’re seeing:

name: themed-icon-test
base: core24
version: '0.1'
summary: summary
description: description
icon: snap-icon.png

confinement: strict

apps:
  themed-icon-test:
    command: foo.sh
    desktop: foo.desktop
    plugs: [desktop]

parts:
  my-part:
    plugin: nil
    override-build: |
      cat << \EOF > $CRAFT_PART_INSTALL/foo.sh
      #!/bin/sh
      EOF
      chmod a+x $CRAFT_PART_INSTALL/foo.sh

      echo "snap" > $CRAFT_PART_INSTALL/snap-icon.png
      echo "desktop" > $CRAFT_PART_INSTALL/desktop-icon.png

      cat << \EOF > $CRAFT_PART_INSTALL/foo.desktop
      [Desktop Entry]
      Exec=themed-icon-test
      Icon=desktop-icon.png
      Name=Test
      EOF

This version gets rid of the use of $SNAP/meta/gui/icons themed icons just to make things simpler. It stops replacing the icon in the desktop file if I comment out the top level icon: snap-icon.png line. I assume the same will hold true for your project if you do the same.

I would suggest filing a bug report against Snapcraft here, as the behaviour seems bizarre. If you’ve got a snap that provides two desktop files with different icons, it’s going to mangle them all to use the same icon. It’s not clear why any of this is desirable.

Wow, thanks, it works indeed! I assume the side effect is that it stops updating the icon in the store?

Ah, never mind, I see it doesn’t update even with it, the icon is old…

1 Like