You may have noticed that GTK+ master has a large number of changes in the CSS area. As some like to put it:
Oh NO! they’re breaking themes again!
Which is certainly one way to look at it, but I think it misses the point a little bit – since the effort is actually meant to make life easier for anybody who wants to change the appearance of GTK+ widgets.
What changes are we making ?
As a first step, we are introducing CSS nodes. A CSS node has an element name, a state and it can have style classes. Each widget has one or more CSS nodes, and they are organized in a tree. GTK+’s CSS machinery matches CSS selectors on this CSS node tree, and as a result, each node carries a full set of CSS properties.
The transition to CSS nodes is mostly done in GTK+ 3.19.2.
In a second step, we will integrate CSS nodes into size allocation and rendering. This will bring consistent support for margins, padding and min-width/height for all widgets. This step is currently being prepared on the wip/otte/gadget branch.
None of this is exposed as API yet (with some small exceptions, such as gtk_widget_path_iter_set_object_name ) . It needs more time to prove itself before we are ready to offer this as stable API.
Why are we doing this ?
There are a number of reasons for doing these changes. In no particular order,
- Element names and style classes use by widgets for their CSS nodes (and their tree relationships) are now documented and provide a stable interface for themes and custom CSS.
- Element names provide a level of abstraction over the direct use of type names, and will allow reuse of CSS. You wil be able to add a “check” node to your own widget, whereas you can’t call your own widget GtkCheckButton.
- CSS nodes are permanent. This implies that they can carry state, e.g. for running CSS animations. They can also notify on state changes.
- CSS nodes can explored and manipulated in GtkInspector.
- CSS nodes (in particular, the second phase) force us to clean up all the irregularities of the current widget rendering and move to a much more regular model, where every node draws a background and a frame.
- Positional selectors such as :first-child now work everywhere, including parts of a widget. You can e.g., use :nth-child(even) to style notebook tabs.
What do you have to do ?
If you maintain a theme or custom CSS for an application, update your selectors to use the documented element names and classes. The changes in Adwaita can serve as an example for the kind of changes that are needed.
If you use GTK+’s style machinery to render non-widget content (like mutter does for window decorations), use
gtk_widget_path_iter_set_object_name to make your widget paths look like the widgets they imitate.
If you have code that pokes colors out of GtkStyleContext to do your own rendering, you should really port to use the gtk_render APIs and custom CSS. If you want to keep your existing code working for now, you need to minimally fix gtk_style_context_get_color calls to use the correct state. Ie. go from
gtk_style_context_get_color (context, GTK_STATE_FLAG_SELECTED, &color);
to
gtk_style_context_save (context); gtk_style_context_set_state (contexts, GTK_STATE_FLAG_SELECTED); gtk_style_context_get_color (context, gtk_style_context_get_state (context), &color); gtk_style_context_restore (context);
What else is new ?
Support for help overlays got merged into GTK+ and is available in 3.19.1. We’ve gotten some feedback from early adopters and added a few more features, so things should be in good shape for wider adoption: please add it to your favorite GTK+ application, and update this page if you do so.
Wayland support is progressing. So far in 3.19, the focus has been on straightening out issues with window and popup sizing and positioning. Many of the remaining gaps will be fixed by integrating the protocols that have been under discussion for a while now: DND actions, tablet support, pointer lock,… Jonas just revamped the Wayland protocol development process, which should lead to faster progress on this front. For more details, see Jonas’ mail.