Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specify an icon with a RELATIVE path for a Linux desktop entry file?

For one of my Linux applications, I have the application binary, a launcher.sh script (for the LD_LIBRARY_PATH) and a .desktop file, all in the same folder.

I'd like to use a relative path rather than an absolute path for the icon.

I've tried:

Icon=app.svg
Icon=./app.svg
Icon=$PWD/app.svg
Icon=$(dirname %k)/app.svg

but none of these work (only Icon=/path/to/app.svg). If it's not possible to specify a relative path and I must use a workaround, I was thinking I could regenerate the icon path in the .desktop file every time the launcher.sh script is run.

What would be the best way to do that? Using sed or some other replacement utility with a pseudo-regex like Icon=([valid path chars]+)\n perhaps?

like image 512
Jake Petroules Avatar asked Aug 10 '10 19:08

Jake Petroules


People also ask

How do I add icons to .desktop file?

Click the Windows key, and then browse to the Office program for which you want to create a desktop shortcut. Right-click the program name or tile, and then select Open file location. Right-click the program name, and then click Send To > Desktop (Create shortcut). A shortcut for the program appears on your desktop.

Where are icons on desktop Linux?

Go to Files -> Other Location -> Computer. From here, go to the directory usr -> share -> applications. You'll see icons of several Ubuntu applications you have installed here.


2 Answers

After doing some more research it doesn't look like it's possible to specify relative paths for an icon in a desktop entry file as far as I can see.

The workaround I used was to add the following code to the end of my launcher.sh script:

mv myapp.desktop myapp.desktop-bak
sed -e "s,Icon=.*,Icon=$PWD/app.svg,g" myapp.desktop-bak > myapp.desktop
rm myapp.desktop-bak

This will update the path of the icon each time the launcher script is run, and since the .desktop file points to the launcher script, clicking the .desktop file effectively updates its icon.

I know you could use cat or the -i option to shorten the above code but I've read that the solution I used is more reliable. If anyone has further information on that please do post a comment.

like image 167
Jake Petroules Avatar answered Oct 24 '22 06:10

Jake Petroules


It's true that the FreeDesktop specification does not permit relative paths:

Standard Keys

Icon

Icon to display in file manager, menus, etc. If the name is an absolute path, the given file will be used. If the name is not an absolute path, the algorithm described in the Icon Theme Specification will be used to locate the icon.

[ . . . ]

Values of type iconstring are the names of icons; these may be absolute paths, or symbolic names for icons located using the algorithm described in the Icon Theme Specification. Such values are not user-displayable, and are encoded in UTF-8.

The workaround is adequate, although it probably won't work for menus and panel launchers. But if you're comfortable patching the desktop file when running the launcher.sh script, why not actually install the icon? You can do it in two lines:

cp app.svg ~/.local/share/icons/hicolor/48x48/apps/
cp app.svg ~/.local/share/icons/hicolor/scalable/apps/

and then put

Icon=app

in the desktop file (app is just the filename without a file extension).

This is the intended mechanism for locating icons that don't have an absolute path, and will ensure the icons show up in menus and custom launchers. The spec has this to say:

So, you're an application author, and want to install application icons so that they work in the KDE and Gnome menus. Minimally you should install a 48x48 icon in the hicolor theme. This means installing a PNG file in $prefix/share/icons/hicolor/48x48/apps. Optionally you can install icons in different sizes. For example, installing a svg icon in $prefix/share/icons/hicolor/scalable/apps means most desktops will have one icon that works for all sizes.

One way this can be done is with the xdg-icon-resource command, e.g.

$ xdg-icon-resource install --novendor --context apps --size 48 example-app.png

However, xdg-icon-resource does not support SVG images, and in practice this accomplishes the same thing:

$ cp example-app.svg ~/.local/share/icons/hicolor/48x48/apps/
$ cp example-app.svg ~/.local/share/icons/hicolor/scalable/apps/

(That's not a typo: put the SVG file in the 48x48/apps folder and the menus and panels will be perfectly happy.)

For menus, it's a good idea to update the icon cache after installing.

$ update-icon-caches ~/.local/share/icons

Then you can simply give the iconstring as example-app like this:

Icon=example-app

This is not a relative path, but it solves the problem of having to use an absolute path and won't break if the desktop file is moved to a different location.

For what it's worth, support for relative paths was discussed on the FreeDesktop mailing list back in September 2008:

Magnus Bergmark magnus.bergmark at gmail.com

Tue Sep 23 01:01:32 PDT 2008

[ . . . ]

I propose that we allow the usage of relative paths in some way also.

Use-cases

  1. I use a lot of .directory files to make directories containing a movie have the movie poster as the icon. This behaviour could apply to any form of media, like comic books, music (album art) and photos.

  2. A vendor might want to bundle an icon to a piece of software they're distributing to go with a .desktop file which are not to go in the desktop menu and therefore are still located in the application directory.

https://lists.freedesktop.org/archives/xdg/2008-September/009940.html

The only counterargument I was able to find to this proposal is here:

A .desktop file that is not intended to go into a standard applications directory is almost entirely useless. Perhaps you should look at some of the software bundle proposals and implementations, and work with using those, instead. Another option is the xdg utils scripts, to install the .desktop file and icons in the appropriate places. I can only presume that your uninstalled application also intends to not follow the Icon Theme and Icon Naming specifications either. And I don't see setting the directory's icon as useful really. Setting an icon for the actual executable would be much more useful, though elf binaries do not have resources like win32 binaries do.

https://lists.freedesktop.org/archives/xdg/2008-September/009962.html

Related questions:

  • https://askubuntu.com/questions/277190/how-to-package-an-application-icon-properly
  • https://unix.stackexchange.com/questions/404955/is-there-a-home-directory-location-for-overriding-icons
  • https://unix.stackexchange.com/questions/428992/why-do-freedesktop-desktop-files-not-allow-relative-paths
  • https://unix.stackexchange.com/questions/585997/assign-an-icon-to-a-custom-mimetype

Relevant links:

  • https://gitlab.freedesktop.org/xdg/xdg-utils/-/issues/82
  • https://bugs.kde.org/show_bug.cgi?id=68507
  • https://bugs.kde.org/show_bug.cgi?id=73463
  • https://lists.freedesktop.org/archives/xdg/2008-September/009940.html
  • https://lists.freedesktop.org/archives/xdg/2011-April/011883.html
  • https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
like image 28
Nathaniel M. Beaver Avatar answered Oct 24 '22 07:10

Nathaniel M. Beaver