GTK+ Stock Items Deprecation

What is going on?

We have deprecated the use of Stock Items and associated functionality in GTK+ 3.10.

What are the Stock Items?

GTK+ 3 has 105 predefined “things” that may be used to construct various user interface elements. They are listed here:

https://developer.gnome.org/gtk3/stable/gtk3-Stock-Items.html#GTK-STOCK-ABOUT:CAPS

What is a Stock Item?

struct GtkStockItem {
 gchar *stock_id;
 gchar *label;
 GdkModifierType modifier;
 guint keyval;
 gchar *translation_domain;
};

Which may represent three things (but not always all three):

What were these used for?

Stock Items have proved quite useful in the past. They have:

  1. Provided a guaranteed, consistent, and high quality set of icons for use in applications.
  2. Provided a convention and mechanism for an application author to reference, add, and use icon images.
  3. Associated a text label and icon pair to a single handle so that the application author would not be concerned with exactly how the  toolkit would present the resulting user interface control — as either a label, an image, or both.

Example interfaces using a handle to reference icons

  1. Images
  1. gtk_image_new_from_stock()
  2. gtk_image_set_from_stock()
  1. Status Icons
  1. gtk_status_icon_new_from_stock()
  2. gtk_status_icon_set_from_stock()
  1. Cell Renderers
  1. GtkCellRendererPixbuf:stock-id
  1. Entries
  1. gtk_entry_set_icon_from_stock()
  1. Tooltips
  1. gtk_tooltip_set_icon_from_stock()
  1. Misc
  1. gtk_drag_set_icon_stock()
  2. gtk_drag_source_set_icon_stock()
  3. gtk_widget_render_icon_pixbuf()

Example interfaces using a handle to an adaptive label / image pair

  1. Buttons
  1. gtk_button_new_from_stock()
  2. gtk_dialog_new_with_buttons()
  3. gtk_dialog_add_button()
  4. gtk_dialog_add_buttons()
  5. gtk_file_chooser_dialog_new()
  6. gtk_recent_chooser_dialog_new()
  7. gtk_recent_chooser_dialog_new_for_manager()
  1. Menu items
  1. gtk_image_menu_item_new_from_stock()
  1. Toolbar items
  1. gtk_tool_button_new_from_stock()
  2. gtk_menu_tool_button_new_from_stock()
  3. gtk_radio_tool_button_new_from_stock()
  4. gtk_toggle_tool_button_new_from_stock()
  1. Actions
  1. gtk_action_set_stock_id()
  2. etc.

So what’s wrong with that?

A guaranteed, consistent, and high quality set of icons

This was certainly important to have in the old days but is no longer required. There are now a number of extremely high quality icon themes that conform to the Icon Theme Specification

and the Icon Naming Specification.

Including the legendary GNOME Icon Theme and GNOME Symbolic Icon Theme.

A handle to reference icon images

Since GTK+ 3.0 we have recommended not using Stock Items to reference icon images and recommended using named icons instead. This guidance has been highlighted in the GTK+ 2 to GTK+ 3 Migration Checklist. So, it is by no means new.

In most cases the porting from a Stock Item to a named icon is trivial. The first step is to find the standard icon name for the deprecated Stock Item. To ease this task the GTK+ 3.10 documentation will list the proper “named icon” to use to replace every Stock Item that has a direct mapping. Or, you may use the Stock Items Migration Guide.

In the cases where there isn’t an obvious candidate then you may wish to reconsider the use of an icon at all. Or at least, consult one of the designers.

If named icons don’t suffice, you may want to look at using the much more capable Icon Interfaces in GIO.

A handle to an adaptive label / image pair

It is really tricky for an application author to design an application that can and will appear quite different before its users. We have tried to reduce or eliminate this kind of variability. In recent years, application dialog buttons display with text labels instead of possibly showing an image too. The same goes for menu items. It is now up to the application author (designing the application according to platform guidelines) to decide how the widget elements should appear.

This is especially important because not all Stock Items have both an associated icon and a label. You really have to know how it is implemented for it to work reliably. Breaking the abstraction to some degree.

It is much clearer not to have this kind of magic in the public API. To have clear expectations about the type of input. And not have the code use fragile heuristics to figure out what you meant. And to allow the compiler and type system to check the input to assist the application developer. Basically, not something like this: “Adds a button with the given text (or a stock button, if button_text is a stock ID)”

One objection that has been raised is that now application authors will need to include and translate label strings (such as “_Save”) application-side. This means application authors will need to decide which characters to use for mnemonics. This is actually a good thing. A problem we’ve always had with standardized label strings hardcoded in the toolkit is that inevitably the mnemonics clash. We’ve never had a solution for this and there is even a FIXME in the code for it. To do it correctly you really need to know what ones you've already used and what items are important enough to have them. While it may be possible to invent some kind of mechanism to pick mnemonics automatically, we don’t currently have one. And it will likely be complicated to do reliably considering translations. Instead of relying on internal magic it is better to trust the application author to get it right.

The problems of consistency between applications is a valid one and may be addressed the way we address other consistency issues, with documentation and clear guidelines . We already have the Stock Items Migration Guide and I expect some of this will migrate into the GTK+ documentation and platform HIG soon.

Buttons

The guidance since before GTK+ 3.0 was for buttons to be text labels only or icon images only. Unless you really know what you are doing. The way we tried to implement this guidance was a kludge to work around Stock Item usage. Because stock items almost always implicitly specified both an icon and a label string and couldn’t really unconditionally turn off showing images we had to introduce gtk_button_set_always_show_image(). This is gross. It is much better to expect that author to add whatever she wants to the button, explicitly, and without magic. And deprecate the behind the scenes shenanigans.

Old:

button = gtk_button_new_from_stock (GTK_STOCK_SAVE);

New:

button = gtk_button_new_with_mnemonic (_(“_Save”));

Check the Stock Items Migration Guide to find the appropriate label to use.

Dialogs

Dialogs are in a similar position to Buttons. But with an additional strike against Stock Items. Many properly designed dialogs will not be able to be implemented using only Stock Items for action buttons. Mixing strings and stock-ids in order to create a dialog makes the interface incoherent. And may result in visual inconsistencies. So, given the recommendation that buttons primarily contain text. It is much clearer to simply recommend the use of text label strings in the dialog API.

Old:

dialog = gtk_dialog_new_with_buttons (NULL, NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_NONE, NULL);

New:

dialog = gtk_dialog_new_with_buttons (NULL, NULL, 0, _(“_Close”), GTK_RESPONSE_NONE, NULL);

Check the Stock Items Migration Guide to find the appropriate label to use.

Menu Items

Well before GTK+ 3.0, the use of icons in menu items was haphazard and inconsistent. The recommendation since then has been to only use icons in “noun” menu items and not at all in “verb” or “action” items. When a menu item is constructed from a Stock Item, which implicitly provided an icon in many cases, we needed to indicate whether the icon was intended. This resulted in gtk_image_menu_item_set_always_show_image(). Not awesome. So now, like with buttons we have deprecated the behind the scenes shenanigans.

And it wouldn’t hurt to just port your app to use GMenu anyway. It is really much nicer.

Old:

item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL);

New:

item = gtk_menu_item_new_with_mnemonic (_(“_Save”));

Check the Stock Items Migration Guide to find the appropriate values.

Toolbar Items

Toolbar Items are even tricker than Buttons or Menu Items. They can be icons, text, both, vertical, horizontal, large or small. But again, we really want the application author to specify the behavior and appearance explicitly as much as possible.

Old:

item = gtk_tool_button_new_from_stock (GTK_STOCK_SAVE);

New:

item = gtk_tool_button_new (NULL, _(“_Save”));

gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), “document-save”);

Check the Stock Items Migration Guide to find the appropriate values.

Actions

We have a much more powerful and easier to use action system already in place. Deprecating the old action system is important in order to clearly indicate to application authors which system is recommended.

Here’s an actual example of such a port to GtkBuilder, GAction, GMenu, and GApplication:

Port of print-editor to GtkBuilder etc

So what’s the benefit?

Marking the things we know are not recommended as officially deprecated results in a much clearer, more concise, and coherent application developer experience.

Doing so sooner than later maximizes the time available to port applications away from deprecated APIs. This means we can do GTK+ 4 sooner. And that will be glorious.

Feedback

The most important thing about this deprecation period is to learn. This is where we need your help. Please try to port your application to the new recommended interfaces. And let us know what we’re missing and what we didn’t anticipate.

Send your feedback to the GTK+ Development Mailing List or submit a report to Bugzilla.

Thanks.