Icons and desktop files

In this tutorial, you will learn:

  • How to add an icon to your program

  • How to add your program to the applications menu

This tutorial is part of the Setting up a real-life GTK application series. If you don't want to follow along with the previous parts, simply copy the app-skeleton2 directory from the tutorial's code examples. Or, you can start from the beginning.

Most users who can use a terminal are also familiar with the time-tested routine of ./configure, make and make install. However, as the Linux desktop gains more and more ground, package managers are on the rise. Users expect to be able to install a package and then find a new entry in their Applications menu. The Makefile.am may install our executable file into /usr/local/bin, but nowadays we can't expect users to open a terminal every time they want to run it. We can put an entry into the menu by means of a desktop file.

Adding an icon to the program

Copy the app-skeleton2 project to app-skeleton3, or just rename it. (Change the version number in the AC_INIT call in configure.ac to 3 as well, if you like.) First we will appropriate an icon from the GNOME icon theme for our program. Again, we will do this the lazy way, by downloading all available sizes directly from the GNOME git repository. In the app-skeleton3 directory, type:

for size in 16 22 24 32 48; do
mkdir -p pixmaps/${size}x${size}/apps
wget -O pixmaps/${size}x${size}/apps/app-skeleton.png \
  http://git.gnome.org/browse/gnome-icon-theme/plain/gnome/${size}x${size}/status/weather-showers-scattered.png
done

This is the icon we have just downloaded, in five different sizes: [An icon of a raincloud from the GNOME icon theme]

There is a reason why we are creating this particular directory structure. It is explained in the Free Desktop Icon Theme Specification and Icon Naming Specification.

The new pixmaps directory needs a Makefile.am too. Create one there and put in it:

iconsdir = $(datadir)/icons/hicolor

nobase_dist_icons_DATA = \
	16x16/apps/app-skeleton.png \
	22x22/apps/app-skeleton.png \
	24x24/apps/app-skeleton.png \
	32x32/apps/app-skeleton.png \
	48x48/apps/app-skeleton.png

gtk_update_icon_cache = gtk-update-icon-cache -f -t $(iconsdir)

install-data-hook: update-icon-cache
uninstall-hook: update-icon-cache
update-icon-cache:
	@-if test -z "$(DESTDIR)"; then \
		echo "Updating GTK icon cache."; \
		$(gtk_update_icon_cache); \
	else \
		echo "*** Icon cache not updated. After (un)install, run this:"; \
		echo "*** $(gtk_update_icon_cache)"; \
	fi

The Automake variable nobase_dist_icons_DATA has four parts. The prefix nobase means to install the files with the same directory structure into the destination directory. Another prefix, dist means to include the files in the tarball produced when you type make dist. (By default, data files are not included.)

The third segment, icons, functions like bin did in bin_PROGRAMS: it tells where to install the files. The difference is that bin is predefined and icons is not. Automake will install the files in the location stored in the variable iconsdir, which we define above. Why it is called hicolor, you can read in the Icon Theme Specification.

Finally, the DATA directive tells Automake that these are data files; they do not need to be compiled.

The rest of the file calls the gtk-update-icon-cache utility whenever the program is installed or uninstalled. This is necessary so that the new icons can be found in the icon theme. The test may look a little confusing at first; testing whether the DESTDIR is empty means testing whether we are really installing the program into the file system, or doing a staged install. In the latter case, the icon files are not really being installed into the icon theme directory, so it makes no sense to update the icon cache. In that case, the makefile prints a message to remind the user to update the icon cache when the program is really installed.

As a last bit of icing on the cake, let us use the icon as our program's icon (in the corner of the title bar in some desktop themes, or in the application switcher.) Since we have already installed the icon into the icon theme, having the program use it is quite simple. Add the following line to the main() function of hello-world.c, for example as line 47:

gtk_window_set_icon_name (GTK_WINDOW (window), "app-skeleton");

When an icon is present in the icon theme, it can be used like this as a named icon. (Remember that you have to run make install before it will work, though.)

The desktop file

Now to create our desktop file. Create a file app-skeleton.desktop in the app-skeleton3 directory and write in it:

[Desktop Entry]
Version=1.0
Type=Application
Name=App Skeleton
Exec=app-skeleton
Comment=A sample application from the Advanced GTK+ Techniques tutorial
Icon=app-skeleton
Terminal=false
Categories=Utility;Viewer;GTK;

In short, Name is the program name that will appear in the menu, Icon is the named icon to use for the program in the menu, and Comment is the tooltip to use when the user hovers their mouse over the program name. The Terminal=false line tells the desktop environment not to start the program in a terminal. The Categories field is a hint to the desktop environment about what category it should put the program launcher into. (Some desktops, like Gnome Shell, don't use categories.)

A full list of fields and categories for use in this file, along with explanations of what they are for, can be found in two other Free Desktop specifications, the Desktop Entry Specification and the Desktop Menu Specification.

Finally, we need to update our top-level Makefile.am:

SUBDIRS = pixmaps src

desktopdir = $(datadir)/applications
dist_desktop_DATA = app-skeleton.desktop

We add the pixmaps subdirectory to our SUBDIRS variable, and instruct Automake to install the desktop file in the proper place so the desktop environment can find it.

Lastly, we add pixmaps/Makefile to the AC_CONFIG_FILES call in configure.ac. With that, we are ready to go. Try make followed by make install. A new entry should show up in your desktop's applications chooser!

But what if the user speaks another language? They will not be able to understand the name of the program and the description we have put in the desktop file. Solving this problem is what the next section is about.