Getting scalable icons to load on Windows

I’m trying to package my application on Windows, and it only loads the icons at some bad resolution instead of the scalable ones. I’ve been told that this is because gdk-pixbuf somehow requires the SVG loader for it to work. I’ve tried copying over the /lib/gdk-pixbuf-2.0/2.10.0/loaders folder to the distribution package, and I’ve also tried to copy over all dll dependencies of the loaders, but it did not appear to help.

To make sure I’m on track, please confirm my current understanding of the situation:

  • libpixbufloader-svg.{so,dll} is required to load scalable icons
  • Once that library is found and loaded, the system will automatically prefer SVGs over the pre-rasterized images when loading icons
  • The loaders themselves are not linked against, but instead are loaded at runtime, probably from some search path
  • The loaders then link against some format-specific libraries, like librsvg

And I still have the following questions:

  • What is the search path for the loaders?
  • How can I check which loaders are available / have been found?
  • Can I maybe build a gdk-pixbuf version that already links against a set of loaders instead of searching for them at run time?

So I’ve found gdk-pixbuf-query-loaders which allows me to check if it finds the correct modules. With this, I could confirm that the svg loader is indeed present and working on Windows. The issue though is to create a correct loaders.cache, which is required, under Linux but with correct file paths for Windows.

The alternative solution would be to compile gdk-pixbuf so that it directly links against that loader. There is some Windows documentation which mentions a builtin_loaders compile flag, but I don’t know if it works with out of tree loaders (the svg loader is part of librsvg).

One thing that I noticed is that icons are only loaded from an icon theme, but not from bundled resources. Compare these two logs:

DEBUG [GLib-GIO] _g_io_module_get_default: Found default implementation winhttp (GWinHttpVfs) for ‘gio-vfs’
INFO  [Gtk] look for icon cache in .\share\icons\Adwaita
INFO  [Gtk] scanning directory .\share\icons\Adwaita\scalable/actions
INFO  [Gtk] look for icon cache in .\share\icons\Adwaita
INFO  [Gtk] scanning directory .\share\icons\Adwaita\scalable/actions
INFO  [Gtk] look for icon cache in .\share\icons\Adwaita
INFO  [Gtk] scanning directory .\share\icons\Adwaita\scalable/actions
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/16x16/status/
INFO  [Gtk] scanning resource directory /example/application/icons/16x16/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/16x16/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/24x24/status/
INFO  [Gtk] scanning resource directory /example/application/icons/24x24/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/24x24/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/32x32/status/
INFO  [Gtk] scanning resource directory /example/application/icons/32x32/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/32x32/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/48x48/status/
INFO  [Gtk] scanning resource directory /example/application/icons/48x48/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/48x48/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/64x64/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/64x64/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/64x64/actions/
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] Current icon themes Adwaita hicolor 
DEBUG [GLib-GIO] _g_io_module_get_default: Found default implementation winhttp (GWinHttpVfs) for ‘gio-vfs’
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/16x16/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/16x16/status/
INFO  [Gtk] scanning resource directory /example/application/icons/16x16/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/16x16/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/22x22/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/24x24/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/24x24/status/
INFO  [Gtk] scanning resource directory /example/application/icons/24x24/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/24x24/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/32x32/actions/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/32x32/status/
INFO  [Gtk] scanning resource directory /example/application/icons/32x32/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/32x32/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/48x48/status/
INFO  [Gtk] scanning resource directory /example/application/icons/48x48/status/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/48x48/status/
INFO  [Gtk] scanning resource directory /org/gtk/libgtk/icons/64x64/actions/
INFO  [Gtk] scanning resource directory /example/application/icons/64x64/actions/
INFO  [Gtk] scanning resource directory /org/gnome/Adwaita/icons/64x64/actions/
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] look for icon cache in .\share\icons
INFO  [Gtk] Current icon themes hicolor 

The difference between them is that in the first run .\share\icons\Adwaita exists, but not in the second. You can see that it does “scanning resource directory” for the correct paths, but only for raster image resolutions and not scalable ones. The scalable icons for some reason are only loaded from an actual directory, i.e. the icon theme.

I’ve not tested, but a possible solution (with GTK 3 at least) is by configuring the GtkIconTheme, there is for example the gtk_icon_theme_set_search_path() function.

Thanks, it is on my investigation list. But for now I see a discrepancy in the behavior between Linux and Windows, so I think this might actually be a bug.

There is also the gtk-update-icon-cache command, maybe it can help too.

I tried

	let theme = gtk::IconTheme::for_display(&gdk::Display::default().expect("No display found"));
	log::warn!("icon_names: {:?}", theme.icon_names());
	log::warn!("resource_path: {:?}", theme.resource_path());
	log::warn!("search_path: {:?}", theme.search_path());
	log::warn!("theme_name: {}", theme.theme_name());
	theme.add_search_path(".");
	theme.add_resource_path("/de/piegames/dinoscore"); // Just to be sure
	theme.add_resource_path("/de/piegames/dinoscore/icons");

and I think it should help but it didn’t. (On the other side, the search paths were already okay beforehand per the debug messages)

It is possible to package gtk-3 on Windows for scalable icons loading, I did it for my app. The details are now hazy, but I remember, for example, if you cherry-pick libraries for packaging using ldd you also need to run ldd on pixbuf loaders, otherwise you may miss dependencies like librsvg, which is needed for scalable icons loading.

Take a look at my packaging scripts:

I also use a custom gtk/icon themes, so some paths you’ll need to adjust if you only package the basics/Adwaita.

Hope this helps,
A

Before wasting more of other people’s time: It was a Gtk bug. Thanks all for the help.

https://gitlab.gnome.org/GNOME/gtk/-/issues/4960

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.