Themable Application-specific Icons

Some applications could need custom named icons, i.e. named icons not listed in Icon Naming Spec.

This page will explain to GNOME/GTK+ developers a method to install and use custom named icon. The suggested method will allow developers to provide themeable icons for their applications without causing file conflicts with other packages.

Here are also listed known app-specific named icon, to help artist to build up a complete icon theme for the GNOME Desktop.

Thanks to Rodney Dawes for the original idea.

How to Install Application-specific Named Icon

You have to install application-specific named icons in a special location in filesystem.

This location is ${prefix}/share/<appname>/icons/hicolor/<size>/<context>, where context is one of the the Context directories for icon theme as defined in Context section of Icon Naming Spec and size is the icon size as suggested by the Tango Style Guidelines.

Be sure to use the exact directory name defined in the spec, or the installed icons will be ignored. This because you don't need to provide an index.theme file to make installed pixmaps available as icon theme, but the application will automatically use the one provided by the hicolor-icon-theme. The suggested version of hicolor-icon-theme is the 0.10, providing all context defined in Icon Naming Spec.

Please note that this is relevant only for icons to use inside your application, not for the application icon to use in system menus, and the app's about box and window titlebars. This icon should be installed in system-wide hicolor theme directory (${prefix}/share/icons/hicolor). So, don't install icons that belongs to Applications context in this way. Follow instead those instructions.

How to Use Installed Application Specific Named Icons

In your application, where you initialize GTK+, you also want to do the following, so that your application will find these icons if the theme tree structure in use, doesn't provide them:

gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
                                   APPNAME_DATA_DIR G_DIR_SEPARATOR_S "icons");

You can define APPNAME_DATA_DIR in your Makefile.am using for example:

INCLUDES = \
        -I$(top_srcdir)                          \
        -I$(top_builddir)                        \
        ...
        -DAPPNAME_DATA_DIR=\"$(pkgdatadir)\"     \
        ...
        $(DISABLE_DEPRECATED)                    \
        $(FR_CFLAGS)

This adds the $pkgdatadir/icons directory to the search path, and GtkIconTheme will then look in here for icons as well as the standard search paths. You can also provide icons for other themes in here, by installing them into a subdirectory for that theme.

Windows-specific notes

This solution also works on Windows. There are some caveats though:

  • The path may be different. The path that you need to provide to the gtk_icon_theme_append_search_path function is the one that contains the hicolor directory. If you have your app-specific icon in "C:\Program Files\My Application\Data\Icons\hicolor\16x16\actions\draw-ellipse.png", then you need to supply "C:\Program Files\My Application\Data\Icons" as the search path. Note that everything after that is part of the mandatory directory structure and cannot be changed.
  • The hicolor theme usually isn't present on Windows. You need to provide an index.theme file compliant with the Icon Theme Specification in the hicolor directory, otherwise the icons won't show up in the application. This file is not needed on Linux, because it already exists in a system wide location. Here is how this file could look like if you had "actions" and "status" contexts and 24x24 size and scalable icons.

[Icon Theme]
Name=hicolor
Comment=Default
Directories=24x24/actions,24x24/status,scalable/actions,scalable/status

[24x24/actions]
Type=Fixed
Size=24
Threshold=2
Context=Actions

[24x24/status]
Type=Fixed
Size=24
Threshold=2
Context=Status

[scalable/actions]
Type=Scalable
Size=48
MinSize=1
MaxSize=256
Context=Actions

[scalable/status]
Type=Scalable
Size=48
MinSize=1
MaxSize=256
Context=Status
  • The GDK-Pixbuf SVG loader is not provided by default with the GTK development bundle. You need to download it and its dependencies separately - it's in the librsvg module. Otherwise, scalable icons will not work on Windows. TODO: specify exactly what steps and components are necessary to enable the loader.

Discussion

Who is responsible for installing the icons for these 'other themes', the theme or the application? We're having this debate in-house just now. Some are saying that it's bad practice for a theme package to install files into the namespace of an application package, while others are pointing out that apps can't be expected to maintain patches for every possible theme. Distros can certainly patch those apps downstream, but that will become more of a chore as more apps start installing app-specific icons. And independent theme artists don't have that luxury at all. So what should we do? CalumBenson

I am a developer and also a theme designer, and as I see it the best solution is: 1. The application only provides Tango-compliant icons in hicolor, 2. If it wants to provide other icons, the authors work with the upstream theme designer. Applications should never install icons into themes other than hicolor. KrzysztofKosiński

I agree that Applications should never install icons into themes other than hicolor. However, should the Crux theme be allowed to install into $prefix/evince/icons/Crux, for example? The obvious answer is 'no'. But that leads to namespace problems if two different apps happen to install an app-specific icon with the same name, because then a third-party theme can't theme both of those icons separately, if it wants or needs to.

I suppose the solution to that would be to recommend here that app-specific icons are still explicitly namespaced via their filename, e.g. evince could install $prefix/evince/.../evince-zoom.png, and tomboy could install $prefix/tomboy/.../tomboy-zoom.png. Then Crux could install both $prefix/icons/Crux/.../evince-zoom.png and $prefix/icons/Crux/.../tomboy-zoom.png, if it wanted to. (Obviously in this example, both icons probably ought to look the same anyway, but there may be situations where that is not the case.) CalumBenson

I agree with Calum's solution, the applications should just use prefixed icon names where it makes sense. But the real reason it's a problem at all is that the Icon Naming Specification hasn't been updated for a long time (for example, a hibernation icon is missing). KrzysztofKosiński

Known Applications

Here is a list of GNOME Desktop application that are currenly using this method. Each entry in the list will open a page listing app-specific themable icons installed by this application

And outside the GNOME Desktop module

Third-party applications that use this solution:

Example

So, let's assume that you want provide "import", "export" (Actions context), and "conversion-running" (Status context) named and themable icons for your application. To avoid file conflicts with other applications (import, export and conversion-running could be common tasks), you can't install icons in system-wide hicolor theme directory. You have to provide them as app-specific themable icons. However, keep in mind that your names should be reasonably specific, because when a theme overrides your "export" icon, this icon will look the same in all applications that use a themable icon with this name.

Method 1: Use Helper Script

There is a semi-automated script which will do this for you. The icon-theme-installer script can be used from within make to properly install lots of icons into the theme and also update the icon cache.

Method 2: Add Code in Makefile.am

  • Add in your source tree data/icons/<size>/actions/ and data/icons/<size>/status/ directories,

  • Place here all needed icons
  • Add in actions a Makefile.am like this

themedir = $(pkgdatadir)/icons/hicolor
size = 16x16
context = actions

iconsdir = $(themedir)/$(size)/$(context)

icons_DATA = \
        import.png   \
        export.png

noinst_DATA = \
        import.xcf  \
        export.xcf

EXTRA_DIST = \
        $(icons_DATA)   \
        $(noinst_DATA)

  • Add in status a Makefile.am like this:

themedir = $(pkgdatadir)/icons/hicolor
size = 16x16
context = status

iconsdir = $(themedir)/$(size)/$(context)

icons_DATA = \
        conversion-running.png

noinst_DATA = \
        conversion-running.svg

EXTRA_DIST = \
        $(icons_DATA)   \
        $(noinst_DATA)

DraftSpecs/ThemableAppSpecificIcons (last edited 2014-07-30 16:20:11 by MattiasBengtsson)