GtkIconPaintable search path

Hi,

The new GtkIconPaintable feature to load scalable icons looks really interesting, but currently it’s a bit verbose to use:

<!-- Before -->
<object class="GtkButton">
  <property name="icon-name">go-next-symbolic</property>
</object>

<!-- After-->
<object class="GtkButton">
  <property name="child">
    <object class="GtkImage">
      <property name="paintable">
        <object class="GtkIconPaintable">
          <property name="file">resource:///org/gtk/libgtk/icons/scalable/actions/go-next-symbolic.svg</property>
        </object>
      </property>
    </object>
  </property>
</object>

Would it make sense to have to possibility to append/prepend search paths, so icons can be automatically looked-up in predefined places?

Something like this:

gtk_paintablemanager_add_search_path("resource:///org/gtk/libgtk/icons/scalable/actions");
<object class="GtkButton">
  <property name="paintable-name">go-next-symbolic</property>
</object>

As application developer, I would then just need to pack all my icons in a defined gresource subfolder. And I could use some of the icons already embedded by libgtk as described in my example above.

Such feature could also be useful for apps like GIMP: they can embed their icon sets in separate gresource subfolders, then set the correponding search path according to the settings (or to some user/system xdg-data path for downloaded icons sets).

Does that make sense?

This would defeat the point, and just re-implement GtkIconTheme. The whole point of moving to explicit paintables is to drop icon themes and named icons.

Having said that, I do agree that the paintable approach is exceedingly verbose and just a great way to make writing UI definition files even more boring and error prone.

1 Like

My first recommendation would be: don’t edit ui files by hand. Only gtk developers should ever do that.
I agree that we should look at reducing the verbosity here.
But it is also true what ebassi said: We want to get out of the name->location mapping business, not replace the icon-theme version of this with an ad-hoc alternative.

1 Like

I think I got used to named icons and instinctively tried to find an equivalent, but yeah we can live without.

Glad to hear that, I’ll keep a look on the progress then, thanks !!

I think this is exactly what we should do. Having to specify the asset path is inherently error-prone, will undoubtedly increase the time spent writing UI files (I have no idea where you get that ‘Only gtk developers should ever do that’ from, given that the majority of current applications have handwritten UI files. They are incredibly useful for rapid prototyping and at least I am quite fast at writing them - now I’m a GTK developer, but I think the point still stands :upside_down_face:). In addition, I find it quite useful (again for prototyping) to interactively change icons using the inspector; depending on how this is implemented, this either will either be more annoying or not possible at all anymore.

I think having a flat hierarchy of files (unlike the FDG icon with their horrific split into apps/, actions/, emblems/, …) with their extensionless basename mapped as the icon name makes a lot of sense. Both in limiting the amount of porting required (the names of the adwaita icons could just be retained) and in keeping the prototyping experience high.

We could make it possible to have callbacks in there, then you can define your own mapping function and say

<object class="GtkIconPaintable">
  <property name="resource">my_icon_mapping("my-fav-icon")</property>
</object>

This might work, if we keep the names of those mapping functions small (I’m thinking about having them named the same way as the g-ir namespace name of their library. So Gtk [or gtk if we want to enforce lowercase] for builtin icons) and ensure that they are easy to use from an api user perspective (own widget with icon properties) but also easily modifiable in the inspector (either one text entry with the same parsing as the ui-file or two text entries).

Regarding a possible API, we could do

interface Gtk.Icon implements Gdk.Paintable {
    String getDomain();
    String getName();
}

abstract class Gtk.IconProvider implements Gio.IOExtensionPoint {
    @Nullable
    /*class func*/ Gtk.Icon lookup(String domain, String icon);
}

and add code to the inspector to properly handle Gtk.Icon properties. I’m intentionally not making use of the extension point name as domain, as that’ll allow us to register a FallbackIconProvider with G_MININT priority, that just always returns the missing icon texture.

The issue I have with that is however, that it operates on the class and not the instance level, so we cannot really register a Gtk.ResourceIconProvider(domain="gtk", asset_path="/org/gtk/libgtk/icons/") and another Gtk.ResourceIconProvider(domain="myapp", asset_path="/arpa/sp1rit/myapp/icons/") without subclassing.

Note that I intentionally did not mention such an extension interface. My suggestion is still to make this mapping the apps responsibility. I was just suggesting a way to cut down on the verbosity

I don’t think making it exclusively the applications responsibility is a good idea, as that’ll make moving ui files from one app to another more difficult - now that isn’t a particularly common usecase, but it happens sometimes (esp. copying from documentation). I also have to question how much prototyping time you actually save, if you have to initially write a mapping function.

Another thing I’ve noticed with extension interface, was that we could handle icons from libraries like we do for styles, that an application could register a higher priority provider, which intercepts a subset of icons from a particular library it wants to override icons from. I haven’t looked to closely into it yet, but I think it might be worth exploring a mechanism like that.

1 Like

I only found out about these resource icons a few days ago when it was mentioned in a bug ticket. They seem to follow the source tree so they’re pretty easy to find and are a quick fix for getting some icons into your app if only other option is to bundle. I’m not familiar with the xml ui stuff but they also work with plain gfile:
Gio.File.new_for_uri("resource:///org/gtk/libgtk/icons/scalable/actions/go-next-symbolic.svg")

I don’t think I mind the path verbosity that much but perhaps gtkbutton could get new constructor/method/property to use a gfile? The example from the first post could then just set the resource uri “icon-file” property directly on the button, could cut down verbosity a bit.

That is not a use case. At least it isn’t one I consider.

This isn’t about saving prototyping time per se. A goal is to support a workflow that consists of picking an icon from a palette or sheet, and dragging it into a ui designer.

I would personally do something along the following lines. Whenever there was a icon-name property add a icon-resource property that

  • loads a symbolic paintable from a resource.
  • Sets the appropiate css class on the widget

Sure

<property name="icon-resource">/my/resource/path/go-next-symbolic.svg</property>

Is more verbose than just go-next-symbolic, but that is still easy to write (and port with some sed magic) and there is no icon-theme-like black box.

Edit: another thing is that GtkApplication already knows the resource-base-path. That could be used as a mapping, e.g. just specify go-next-symbolic.svg if the base path was /my/resource/path/.

I realized that we already have a way to map names to objects in ui
files, and can use it. Here is another experiment:

1 Like