Search code examples
glibvala

GLib, is there a reliable way to test icons existence ? (Vala)


Typically, I’m gathering info of steam games, which does create game icons if user asked it. So there might be icons for games available like steam_icon_1524 but not for sure.

How could I test if an icon is available ?


Solution

  • This answer may not hold for steam games, but you said it's not specific to steam, so shrug.

    Basically, you just need to call GLib.AppInfo.get_icon. It will return null if there is no icon.

    To enumerate installed applications you use GLib.AppInfo.get_all ().

    Under the hood, what is happening is that the *.desktop files stored in the applications/ subdirectory of $XDG_DATA_DIRS (fallback if not set: "/usr/local/share/:/usr/share/") and $XDG_HOME_DATA_DIR (fallback if not set: "~/.local/share/") are parsed (see Desktop Entry Specification for details on the file format), and the "Icon" key is used determine the icon name.

    Technically, this doesn't quite tell you whether or not the icon actually exists with the current icon theme, only if it is supposed to exist. That's where the Icon Theme Specification comes in. There are several implementations, but since you're using Vala I'll assume you're using GTK+…

    You can use Gtk.IconTheme.get_default to get the theme, then Gtk.IconTheme.lookup_by_gicon to get the Gtk.IconInfo (or null if it wasn't found).

    Putting it all together, here is a quick program to list all the installed applications and their icons:

    private static void main (string[] args) {
      Gtk.init (ref args);
    
      unowned Gtk.IconTheme theme = Gtk.IconTheme.get_default ();
    
      foreach (unowned GLib.AppInfo appinfo in GLib.AppInfo.get_all ()) {
        GLib.Icon? icon = appinfo.get_icon ();
        if (icon != null && icon is GLib.ThemedIcon) {
          GLib.message ("%s: %s", appinfo.get_display_name (), icon.to_string ());
          Gtk.IconInfo? iconinfo = theme.lookup_by_gicon (icon, 48, 0);
          if (iconinfo != null) {
            GLib.message (iconinfo.get_filename ());
          } else {
            GLib.message ("No icon.");
          }
        }
      }
    }