How do I use custom icons in my Gnome Builder (vala) application?

In Stack Overflow, you can add your questions and answers. Well, I had been searching for a long time for this issue, and I’m sure the information is available somewhere, but I failed to find the sources I needed, neither did I did find the error message mentioned anywhere else, so I’m going to describe much of the search here, which is irrelevant for the specific question that still remains, but perhaps helpful for those who are looking for help here. (Feel free to add more clarity on comments in the details.)

I tried many things to use a custom library-icon, but none of the attempts seems to work. I get the following output when running my application:

[1/5] Generating src/clavier-resources_h with a custom command
FAILED: src/clavier-resources.h 
/usr/bin/glib-compile-resources ../../../../../../../../../Projets/Clavier/src/clavier.gresource.xml --sourcedir ../../../../../../../../../Projets/Clavier/src --c-name clavier --internal --generate --target src/clavier-resources.h
../../../../../../../../../Projets/Clavier/src/clavier.gresource.xml: Failed to locate “library-symbolic.svg” in any source directory.
[2/5] Generating src/clavier-resources_c with a custom command
FAILED: src/clavier-resources.c 
/usr/bin/glib-compile-resources ../../../../../../../../../Projets/Clavier/src/clavier.gresource.xml --sourcedir ../../../../../../../../../Projets/Clavier/src --c-name clavier --internal --generate --target src/clavier-resources.c --dependency-file src/clavier-resources.c.d
../../../../../../../../../Projets/Clavier/src/clavier.gresource.xml: Failed to locate “library-symbolic.svg” in any source directory.
ninja: build stopped: subcommand failed.

I have no clue what to do about it, neither do I find any sources online of people encountering this issue. Yes, I see it doesn’t find my custom library-symbolic.svg file, but I don’t understand why. I included it in ./data/icons, ./icons, ., ./icons/scalable/actions. None of it works. The only thing I can do to get rid of this error is including directly it under ./src :tada:. The gresources file looked like this at the time.

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/codeberg/vendillah/Clavier">
    <file preprocess="xml-stripblanks">gtk/main-window.ui</file>
    <!-- other ui files -->
  </gresource>
  <gresource prefix="/org/codeberg/vendillah/Clavier/icons">
    <file preprocess="xml-stripblanks">library-symbolic.svg</file>
  </gresource>

It was a random attempt to put it in the same folder as the gresource file like Epiphany does, and that worked, apparently. This most probably means that the files should be referenced relative to the gresources file.

I did read the documentation about themed icons and don’t see what I’m doing differently. All I learned is that I should use Gtk.IconTheme.get_for_display apparently, afterwards? Why exactly? Anyway, I did include the following lines in my application class

var theme = Gtk.IconTheme.get_for_display (Gdk.Display.get_default ());
theme.add_resource_path (".");

and it expectedly, it didn’t change the output I got before, only after I got it running, of course. It resulted in the following lines:

(process:2): Gtk-CRITICAL **: 22:26:29.440: gtk_icon_theme_get_for_display: assertion 'GDK_IS_DISPLAY (display)' failed

(process:2): Gtk-CRITICAL **: 22:26:29.441: gtk_icon_theme_add_resource_path: assertion 'GTK_IS_ICON_THEME (self)' failed

The documentation from ElementaryOS about it got me confused, as it tells me I should have the icons in ./data, but it uses a prefix=".../com/icons" (thus, it’s not even reading from data - is the prefix a path at all??).

I actually followed the tutorial by the Icon Library app, which is misleading as from looking there, I get the sense I only have to save the library file under ./data/icons and add it to my gresource, but that didn’t work without hours of searching and trying.


The end result of what I tried is that the library icon is black in dark mode (i.e. always black). I downloaded the svg from previously mentioned icon library app. Shouldn’t it be colored as it’s a symbolic icon? How can I have the icon be displayed as a white one when dark mode is enabled?

Hm, well, apparently modifying my gresource file as follows make the icons appear white on dark mode (and still black on white mode):

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/codeberg/vendillah/Clavier">
    <file preprocess="xml-stripblanks">gtk/main-window.ui</file>
    <!-- other ui files -->
  </gresource>
  <gresource prefix="/org/codeberg/vendillah/Clavier/icons">
    <file compressed="true" alias="scalable/status/library-symbolic.svg" preprocess="xml-stripblanks">library-symbolic.svg</file>
    <file compressed="true" alias="scalable/status/keyboard-symbolic.svg" preprocess="xml-stripblanks">keyboard-symbolic.svg</file>
  </gresource>
</gresources>

I’m not sure yet why exactly, so once more to whoever reads this, feel free to add why that is if you know!


How do I close my own question?

Each GTK App has a resource-base-path which you can learn more about from Gio.Application.set_resource_base_path. There are special locations under resource-base-path where if you put any files, they are automatically recognized or even loaded and applied. Some of those locations include <resource-base-path>/icons for icons, <resource-base-path>/style.css (including other variants e.g. style-dark.css, style-hc.css, style-hc-dark.css) for CSS stylesheets, etc. More information about these special locations is available at Gtk.Application and Adw.Application.

In your case, since application-id of your app is org.codeberg.vendillah.Clavier, resource-base-path of your app defaults to /org/codeberg/vendillah/Clavier and /org/codeberg/vendillah/Clavier/icons becomes the location where you can override the hicolor icon theme. As an example, in order to be able to reference library-symbolic.svg icon by its name, you can save it as a resource at /org/codeberg/vendillah/Clavier/icons/symbolic/library-symbolic.svg instead of installing it as a file at /usr/share/icons/hicolor/symbolic/library-symbolic.svg (notice that the parts after /org/codeberg/vendillah/Clavier/icons and /usr/share/icons/hicolor are the same).

As for having to put library-symbolic.svg directly in src directory, you don’t need to do that. See source_dir parameter in Meson::gnome.compile_resources for more information about changing the directories where compile_resources() looks for files mentioned in gresource.xml.

Personally, I would put my app’s icons under src/icons in the same layout I need them to be in the resources i.e. the icon files would be saved as

<repo_root>/src/icons/symbolic/library-symbolic.svg
<repo_root>/src/icons/symbolic/keyboard-symbolic.svg

and my gresource.xml would look like

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/codeberg/vendillah/Clavier">
    <file preprocess="xml-stripblanks">gtk/main-window.ui</file>
    <!-- other ui files -->
    <file>icons/symbolic/library-symbolic.svg</file>
    <file>icons/symbolic/keyboard-symbolic.svg</file>
  </gresource>
</gresources>

Edit: By the way, you don’t need to mess with Gtk.IconTheme API.

1 Like

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