Category Archives: Uncategorized

Portals: Using GTK+ in a Flatpak

The time is ripe for new ways to distribute and deploy desktop applications: between snappy, Flatpak, AppImage and others there are quite a few projects in this area.


Most of these projects involve some notion of sandboxing: isolating the application from the rest of the system.

Snappy does this by setting environment variables like XDG_DATA_DIRS, PATH, etc,  to tell apps where to find their ‘stuff’ and using app-armor to not let them access things they shouldn’t.

Flatpak takes a somewhat different approach: it uses bind mounts and namespaces to construct a separate view of the world for the app in which it can only see what it is supposed to access.

Regardless which approach you take to sandboxing, desktop applications are not very useful without access to the rest of the system.  So, clearly, we need to poke some holes in the walls of the sandbox, since we want apps to interact with the rest of the system.

The important thing to keep in mind is that we always want to give the user control over these interactions and in particular, control over the data that goes in and out of the sandbox.


The flatpak story for this has been portals. To quickly summarize: Portals are high-level (in the sense that they talk about concepts that are relevant to users) APIs that let sandboxed applications request access to resources outside. Portal calls will (almost) always involve user interaction (basically, a dialog).

We have talked about portals for quite a while, see for example this post by Allan from two years ago. Therefore,  I am very happy to announce that we now have first release of the portal infrastructure :

Note that the portal APIs themselves are desktop-neutral, and we have separated the implementation using GTK+ dialogs into their own module. We are also working on a qt/KDE  implementation.

The  APIs included in these releases cover a lot of basic things:

  • opening files
  • opening uris
  • printing
  • taking screenshots
  • notifications
  • inhibiting screen lock
  • network status
  • proxy information

Using portals in apps

The good news is that most of these will just work transparently in GTK+ applications, since GTK+ and GLib have suitable APIs that can be made to use the portals without any changes required from the sandboxed application. This support is already in place in the master branches; and will be in the 3.22 releases. We are working on a similar level of support for qt/KDE.

In detail, for opening files, you can use GtkFileChooserNative (a file chooser implementation that will also use a native Windows filechooser if you are on that platform). GtkFileChooserButton will do this for you, unless you manually set its dialog to something else. Certain things will not work with the portal, such as previews, or adding extra custom widgets.

For printing, use GtkPrintOperation (again a long-standing GTK+ api that will use a native Windows print dialog if you are on that platform).

For opening uris, use gtk_show_uri or g_app_info_launch_default_for_uri. We also added a new function that works slightly better in this context, gtk_show_uri_on_window().


As I said, most of the portals will just be transparently used by sandboxed GTK+ applications (provided they use GTK+ from git), but I’ve also written a portal-test application to try all the available portals.


All of the tests use the regular GTK+ APIs, with the exception of the Screenshot button. Since we don’t have a screenshooting API in GTK+, that button makes a direct D-Bus call to the portal. Here is how it looks in action:


Whats next ?

For the first release, we’ve focused on portals for toolkit-level functionality. There is obvously a long list of other system integration points that will need to be covered. High up on our list for the near future are access to devices like webcams and microphones, and pulseaudio. If you are interested, the list of issues has some more information.

Update: I’ve been asked: Why do I need a portal, the file chooser in the libreoffice flatpak seems to work just fine ?! Most of the current flatpaks are shipping with a relatively open sandbox configuration that allows the application full access to the host filesystem, or at least to your entire home directory. Portals enable applications to  function in a constrained sandbox that does not have this.

Dispatches from the GTK+ hackfest

A quick update from the GTK+ hackfest. I don’t really want to talk about the versioning discussion, except for two points:

First, I want to apologize to Allison for encouraging her to post about this – I really didn’t anticipate the amount of uninformed, unreasonable and hateful reactions that we received.

Second, I want to stress that we just at the beginning of this discussion, we will not make any decisions until after Guadec. Everybody who has opinions on this topic should feel free to give us feedback. We are of course particularly interested in the feedback from parties who will be directly affected by changes in GTK+ versioning, e.g. gstreamer and other dependent libraries.

20160613_155602Todays morning discussion was all about portals. Portals are high-level D-Bus apis that will allow sandboxed applications to request access to outside resources, such as files or pictures, or just for showing URIs or launch other applications. We have early implementations of some of these now,  but after the valuable feedback in todays discussion, we will likely make some  changes to it.

An expectation for portals is that there will be a user interaction before an operation is carried out, to keep users in control and let tem cancel requests. The portal UIs will be provided by the desktop session.

We want to have a number of portals implemented during the summer, starting with the most important ones, like file chooser,  ‘open a uri’, application launcher, proxy support, and a few others. The notes from this discussion can be found here.

20160613_105754In the afternoon, the discussion moved to developer documentation, how to improve it, let readers provide feedback and suggestions, and integrate them in gnome-builder.

We also discussed ways to make GTK+ better for responsive designs.

Modularity and the desktop

shellsThere has been much talk about modularity recently. Fedora even has a working group on this topic. Modularity is such a generic term that  it is a bit hard to figure out what this is all about, but the wiki page gives some hints: …base module… …docker image… …reduced dependencies… …tooling… 

A very high-level reading would be that this is about defining tools and processes to deliver software in modules, which can be larger units than packages, and e.g. come in the form of container images.

Another reading would be that this is an effort to come to grips with the changing role of distributions in a world were containers are the dominant way to run and deploy applications.

Modularity on the desktop

In this post, I want to look at how this modularity effort looks from the desktop perspective, and what we are doing in this area.

Our main goal for a while has been to make it easier to get desktop applications from application developers to users.

In the traditional Linux distribution world, this is a total nightmare: Once you’ve written your application, you need to either learn how to create an Ubuntu .deb, an Arch .pkg, a Fedora .rpm, to name just a few, and then follow lengthy processes to get your packages accepted into these distributions.

And once you’ve done all that, you will get bug reports that your application is broken with the one or other version of one of your dependencies. If not right away, then a few months down the road when the distributions move on to the latest and greatest releases.  So, keeping those packages working requires the constant attention of a package maintainer.

To improve on this sad state of affairs, we need to make applications much less dependent on the OS they run on, and on the libraries that happen to come with the OS.

At this point, you might say: Aha, you want to bundle dependencies! Yes, but read on. Bundling is a bad word in the traditional distribution world. It implies duplication, since multiple applications may bundle the same library. And having multiple copies of the same library (possibly different versions, too), makes it harder to ensure that bug and security fixes get applied to all the copies.  Not to mention that all the duplication consumes bandwidth when you have to download it all.

Bundling everything with the application certainly has its drawbacks. But there are several things we can do to preserve most of the benefits of bundling, while avoiding the worst of the problems.

One takeaway from the modularity discussions mentioned earlier is that going to larger units than individual packages (ie modules) has  advantages: we thin out the dependency graph, and we get a large piece of functionality that can be tested, installed and updated as a unit.

And we can use a smart storage and transport mechanism such as OSTree to limit the impact that duplication has on bandwidth.

Desktop applications commonly depend on similar sets of libraries: the GTK+ stack is a good example, kdelibs is another.  Treating these common library stacks as modules makes a lot of sense.  We decided to call these modules runtimes. Applications can declare a single dependency on the runtime they need, and get a well-defined set of APIs and libraries in return.

What if you need a library that is not in the runtime ? In that case, you can still bundle it with your application. You will be reponsible for the libraries that you bundle, but in return your users get exactly the version that you’ve tested your app with.

By decoupling the runtimes from the OS and by making them available in the same way as the applications, we  make it possible to have applications that can run on different distributions, regardless of the library versions that are included in the OS. Of course, there is limits to what we can achieve: the applications and runtimes still have requirements (e.g. on Linux kernel features, or on session services that are expected to be present). But building an application that can run on Fedora, Ubuntu, Arch, RHEL and other modern distributions is entirely possible.

But what about security updates?  To make this system work, we need to offer well-maintained runtimes that application authors can rely on, and provide updates for them just as we do now with distribution packages.

But that is not enough. We also need to isolate applications from the rest of the system (and your data!) at runtime, in order to limit the damage that they can do. Historically, the Linux desktop has been really bad about this: X lets any client snoop all input, and applications are generally free to read whatever they find in your home directory. Part of our desktop modularity story is to use container technologies and e.g. Wayland to confine (or sandbox) applications at runtime.

Modularity now!

 Bubblewrap cat by dancing_stupidity

We have been working towards this goal for quite a while, with the Wayland port and gnome-software as a non-package-centric installer.

What I’ve outlined above is more or less the architecture of the Flatpak system (formerly known as xdg-app).  It is not 100% fleshed out yet, but enough pieces are in place now that you can try it out and e.g. install a nightly build of libreoffice that works on both Fedora and Ubuntu.

Head over to to learn more.

Yet another GTK+ update

GTK+ 3.20 was released a while ago; we’re up to 3.20.3 now.  As I tried to explain in earlier posts here and here, this was a pretty active development cycle for GTK+. We landed a lot of of new stuff, and many things have changed.

I’m using the neutral term changed here for a reason. How you view changes depends a lot on your perspective. Us, who implemented the changes, are of course convinced that they are great improvements. Others who maintain GTK+ themes or applications may have a different take, since changes often imply that they have to do work to adapt.

What changed in GTK+

A big set of changes is related to the inner workings of GTK+ CSS.

The CSS box model is much better supported in widgets. This includes padding, margins, borders, shadows, and the min-width and min-height properties. Since many widgets are complex, they typically have many CSS boxes. Here is how the box tree GtkNotebook looks:


In the past (up to and including GTK+ 3.18), we used a mixture of widget class names (like GtkNotebook), style classes (like .button) and widget names (like #cancel_button) for matching styles to widgets. Now, we are using element names for each box (e.g. header, tabs and tab in the screenshot above). Style classes are still used for optional things and variants.

The themes that are included in GTK+ (Adwaita, Adwaita dark, HighContrast, HighContrastInverse and the win32 theme) have of course been updated to follow this new naming scheme. Third-party themes need and application-specific CSS need to be updated for this too.

To help with this, we have expanded both the general documentation about CSS support in GTK+ here and here, and we have documented the element names, style classes and the node hierarchy for each widget. Here, for example, is the notebook documentation.

The documentation is also a good place to learn about style properties that have been deprecated in favor of equivalent CSS properties, like the secondary cursor color property. We warn about deprecated style properties that are used in themes or custom CSS, so it is easy to find and replace them:

(gtk3-demo:14116): Gtk-WARNING **: Theme parsing error: gtk-contained.css:18:37: The style property GtkWidget:secondary-cursor-color is deprecated and shouldn't be used anymore. It will be removed in a future version

There’s also a number of new features in CSS. We do support the CSS syntax for radial gradients, we let you load and recolor symbolic icons, image() and calc() are supported, as well as the rem (‘root em’) unit.

Beyond CSS, the drag-and-drop code as been rearchitected to move the drag cancel animation and most input handling into GDK, thereby dropping most of the platform-dependent code out of GTK+.  The main reason for doing this was to enable a complete DND implementation for Wayland. As a side-effect, we gained the ability to use non-toplevel widgets as drag icons, and we dropped the X11 specific feature to use RGBA cursors as drag icons.

The Wayland backend has grown most features that it was missing compared to X11:  the already mentioned full DND support, kinetic scrolling, startup notification, primary selection, presenting windows, a bell.

Changes in applications

Here is an unsorted list of issues that may show up in applications with GTK+ 3.20, with some advice on how to handle them.

One of the motivations for the changes is to enable animations and transitions. If you use gtk_style_context_save/restore in your draw() function, that prevents GTK+ from keeping the state that is needed to support animations; so you should avoid it when you can.

There is one place where you need to use gtk_style_context_save(), though: when using “theme colors”.  The function gtk_style_context_get_color() will warn when you pass a state other than the current state of the context. To avoid the warning, save the context and set the state:

gtk_style_context_save (context);
gtk_style_context_set_state (context, state);
gtk_style_context_get_color (context, state, &color);
gtk_style_context_restore (context);

And yes, it has been pointed out repeatedly that this change makes the state parameter of gtk_style_context_get_color() and similar functions largely useless – this API has been around sinc e 3.0, when the CSS machinery was much less developed than it is now. Back then, passing in a different state was not a problem (because animations were not really supported).

Another word of caution about  “theme colors”: CSS has no concept of foreground/background color pairs. The CSS background is just an image, which is why gtk_style_context_get_background_color() is deprecated and we cannot generally make it return a useful color. The proper way to have a theme-provided background in a widget is to call gtk_widget_render_background() in your draw() function.

If you are using type names of GTK+ widgets in your CSS, look up the element names in the documentation and use them instead. For your own widgets, use gtk_widget_class_set_css_name() to give them an element name, and use it in the CSS.

A problem that we’ve seen in some applications is the interaction between size_allocate() and draw(). GTK+’s CSS boxes need to know their size before they can draw. If you derive from a GTK+ widget and override size_allocate without chaining up, then GTK+ does not get a chance to assign sizes to the boxes. This will lead to critical warnings from GTK+’s draw() function if you don’t override it. The possible solutions to this problem are either to chain up in size_allocate or to provide your own draw implementation.

If you are using GTK+ just for themed drawing without using GTK+ widgets, you probably need to make some changes in the way you are getting theme information. We have added a foreing drawing example to gtk3-demo that shows how this can be done. The example was written with the help of libreoffice and firefox developers, and we intend to keep it up-to-date to ensure that this use case is not neglected.

A plea

If you are maintaining a GTK+ application (in particular, a big one like, say, inkscape), and you are looking at porting from GTK+ 2 to GTK+ 3, or updating it to keep up with the changes in 3.20, please let us know about the issues you find. Such feedback will be useful input for us when we get together for a GTK+ hackfest in a few weeks.

Whats coming

One of the big incoming changes for 3.22 is a GL-based renderer and scene graph. Emmanuele has been working on this on-and-off for quite a while – you may have seen some of his earlier presentations. Together with the recent merge of (copies of) clutter and cogl into mutter, this will put clutter on the path towards retirement.


My first xdg-app

A few days ago, I set out to get some experience with building an application as an xdg-app.  In this post, I’m collecting some of the lessons I learned.

Since I didn’t want pick a too easy test case, I chose terminix, a promising terminal emulator for GNOME. Terminix uses GTK+ and vte, which means that most dependencies are already present in the GNOME runtime.


However, terminix is written in D, and the GNOME sdk does not include D support.  So, the challenge here is to build a compiler and runtime for this language, and any other required language-specific utilities. The DMD D compiler is written in D (naturally), so some bootstrapping was required.

Build tools

xdg-app comes with low-level build support in the form of various xdg-app build commands. But you really want to use the newer xdg-app-builder tool. It is really nice.

xdg-app-builder downloads and builds the application and all its dependencies, according to a JSON manifest.  Thats par for the course for modern build tools, of course. But xdg-app-builder also has smart caching: It keeps git checkouts  of all sources (if they are in git), and only rebuilds them when they change. It also keeps the results of each modules’ build in an ostree repository, so reusing a previous build is really fast.

All the caches are kept in .xdg-app-builder/ in the directory where you run the build. If you have many dependencies, this hidden directory can grow large, so you might want to keep an eye on it and clean it out every now and then (remember, it is just a cache).

You can take a look at the JSON file I came up with.

Build API

Similar to the GNOME Continuous build system, xdg-app-builder assumes that each module in your JSON supports the ‘build api’ which consists of configure & make & make install. The world is of course more diverse than that, and rolling your own build system is irresistable for some.

Here is a way to quickly add the required build api support to almost any module (I’ve stolen this setup from the pitivi xdg-app build scripts):

Place a foo-configure script next to your JSON recipe that looks like this (note that Makefile syntax requires tabs that were eaten when I pasted this content in here):


cat <<EOF >Makefile
all: whatever is needed to build foo

        ...commands to install foo go here


In the JSON  fragment for the foo module, you add this file as an extra source (we are taking advantage of the fact that xdg-app-builder allows multiple sources for a module):

"modules": [
        "name": "foo",
        "sources": [
                "type": "git",
                 "url": "",
                 "branch": "master"
                "type": "file",
                "path": "foo-configure",
                "dest-filename": "configure"

I guess you could just as well have the Makefile as yet another source; this approach is following the traditional role of configure scripts to produce Makefiles.

Network access

As I mentioned already, the first step in my build was to build a D compiler written in D. Thankfully, the build script of the dmd compiler is prepared for handling this kind of bootstrapping. It does so by downloading a pre-built D compiler that is used to build the sources.

Downloading things during the build is not great for trusted and repeatable builds. And xdg-app’s build support is set up to produce such builds by running the build in a controlled, sandboxed environment, which doesn’t have network access.

So, in order to get the D compiler built, had to weaken the sandboxing for this module, and grant it network access.  It took me a little while to find out that the build-args field in the build-options does this job:

"modules": [
        "name": "dmd",
                "build-args": ["--share=network"]

Shedding weight

After navigating around other hurdles, I eventually succeeded in having a build of my entire JSON recipe run through the end. Yay! But I quickly discovered that the build directory was quite heavy. It came to over 200M, a bit much for a terminal.

xdg-app-builder creates the final build by combining the build results from all the modules in the JSON recipe. That means my terminix build included a D compiler, static and shared libraries for the D runtime, build utilties, etc.

To fix this, I added a couple of cleanup commands to the JSON. These are run after all the modules have been built, and can remove things that are no longer needed.

"cleanup-commands": ["rm -rf /app/lib",
                     "rm -rf /app/src",
                      rm -rf /app/share/nautilus-python",
                      "rm /app/bin/dmd",

Note that the paths start with /app, which is the prefix that xdg-app apps are put in (to avoid interference with /usr).

After these cleanups, my build weighed less than a megabyte, which is more acceptable.

Trying it out

The best way to distribute an xdg-app is via an OSTree repository. Since I don’t have a good place to put one, and Terminix is developed on github, I decided to turn my xdg-app into a bundle, using this command:

xdg-app build-bundle ~/xdg-app-repos/terminix \
                     terminix.x86_64.xdgapp \
                     com.gexperts.Terminix \ 

Since github has a concept of releases, I’ve just put the bundle there:


Why Wayland anyway ?

The Fedora Workstation working group decided this week that we’re not quite there yet for making the Wayland session the default in Fedora 24.

That is a bit of a disappointment for me, since we have worked very hard this cycle to close the gaps;  you can see the progress we’ve made here: primary selection, kinetic scrolling, drag-and-drop,  startup notification, pointer confinement have all landed this cycle. Not to mention countless smaller bug fixes and robustness improvements. But gaps are gaps, so we will take one more cycle to address them.


In any case, the Wayland session in Fedora 24 will be the best Wayland session we’ve ever had, and I really encourage everybody to try it out when F24 released.

Chances are that you won’t be able to tell the difference between the X and Wayland sessions. That is of course intentional – we’ve put a lot of effort into making sure that things work as well or better than before. But it is also a bit of a dilemma for advertising the Wayland work.

Why do it if everything is the same in the end ?


One reason is that Wayland is designed from the ground up to isolate clients from each other.  There is no shared coordinate space. Wayland clients cannot snoop on each others input or inject fake input events. They can’t draw on each others windows or cover up windows with fake replicas.

All of these things and many other exploits are possible for malicious X clients, because the X protocol wasn’t designed for untrusted clients.

This makes Wayland a much better choice of display protocol when sandboxing untrusted applications, like xdg-app does.


Another reason for using Wayland is that the Wayland protocol is a much better fit for a modern, compositing-based display system.

The X protocol contains many pieces that are simply no longer relevant today, like core fonts or core rendering. Modern toolkits and applications don’t use most of the protocol, but the obsolete parts have to stay if you want to claim to implement the X11 protocol.

Some problematic parts of the X protocol, such as grabs, are simply not present under Wayland.


A third reason for Wayland is that it will be a good basis to enable features that are hard to support under X, such as input transformation or smooth transitions between composited desktop and fullscreen clients.

Currently, we are still playing catch-up with the features of the traditional X session, so we haven’t really done much work on such new features yet. But as a small example,  we’ve already seen that it was relatively easy to add touchpad gesture support to Wayland, while X doesn’t have them yet.

There are more reasons for Wayland beyond these three, and you can read more about them e.g.  here or here.

Try it

Again, if you haven’t tried Wayland yet, the F24 release will be a great time to do so. Simply select the Wayland session (currently just called GNOME) in the session chooser on the login screen:


A Wayland status update

Peter argues that the question “Is Wayland ready yet?” is not the best question to ask.  Then maybe this is a better question:

Is GNOME on Wayland ready yet ?

It has been our goal for a while to get to a point where the Wayland port can be declared complete and ready to be enabled by default. We’ve come a long way since we started the porting effort in September 2013. In fact, we feel that we’re close enough that we can  aim for Wayland by default in Fedora 24.

But the last mile is always the longest, and there’s still a few steps to take before we’re there.  With this weeks releases of Wayland 1.9.91 and the GNOME 3.19.4 releases, we’ve taken a couple of the steps:

  • A lot of work has gone into fixing the positioning of dialogs, menus and other popups in applications. When it was first introduced, the GTK+ Wayland backend was using heuristics based on window type hints for this; now we are more strict about it: just setting a transient parent should be enough to ensure proper placement. We also try to handle dialogs without transient parent as good as we can.
  • Kinetic scrolling now works as well under Wayland as under X11 – or even better (at least as far as the protocol is involved; Wayland has explicit support for this while we are relying on driver-specific heuristics under X). The relevant Wayland protocol additions needed  for this are the axis stop events.
  • Drag-and-Drop under Wayland is now comparable to X11. This is the culmination of multiple efforts:  The Wayland protocol gained some necessary dnd events and supports actions now.  On the GTK+ side, we’ve moved drag icon creation and input handling to the GDK backends, where it can be done in a backend-specific manner.

Whats next ?

  • We should see initial support for Wacom  tablets in Wayland 1.10.
  • A replacement for the X11 primary selection (“middle click paste”) is also in the works; I hope we can reach agreement on the protocol soon.
  • Inside GTK+, menu positioning is being reworked in a similar way to DND: Pushing it down to GDK, where it can be implemented in a backend-specific manner. This is being driven by the team working on the Mir backend, but it will benefit Wayland just as well.

And here is a sneak preview of Wayland remoting that Jonas has been working on for a while:

CSS boxes in GTK+

In my last update, I talked about CSS nodes in GTK+, which are used to match theme style information to widgets, and to hold state that is needed to handle e.g. animations.

Today, I’ll focus on CSS boxes in GTK+. This is where we take size information from the theme, such as margins, padding, and minimum sizes, and apply them to the widget layout. The internal name we’ve chosen for the objects that encapsulate this information is gadgets . I’m well aware that we’re not exactly breaking new ground with this name, but the name isn’t really important (as none of this is currently exposed as public API). For the purpose of this post, you can think of gadgets simply as CSS boxes that make up widgets.

Lets start with a simple example widget, to see what this is about: a radio button (all of the screenshots here are showing GtkInspector, which is available in any GTK+ application, so you can easily do these experiments yourself).

We start by making the border of the widget’s box visible. The CSS snipplet shown below is using the element name radiobutton, which GtkRadioButton sets on its main CSS node, so this selector will match.

Radio button
This is how it looks. If you compare carefully with the earlier screenshot, you can see that GTK+ has made the widget bigger to make room for the 6 pixel border, while giving the same size as before to the content of the widget.

The CSS box model has more than just a border, it also allows for padding (inside the border) and margins (outside the border). In fact, the box model is much more complicated than this, and we’re only scraping the surface here. The GTK+ implementation of the box model handles most of the important parts, but doesn’t cover some things that don’t fit well in our situation.

So, lets add a margin and padding. To make this visible, we use some features of CSS background rendering: We specify two backgrounds (a solid blue one and a solid yellow one), and we let one of it be clipped to the size of the ‘content box’ (the area given to the widget content) and one to the size of the ‘padding box’ (which is the content area plus the padding around it).

This is how it looks. The margin is not very visible here, but you can clearly see the padding (yellow) and the content (blue). Note again how the widget has gotten larger to accommodate the padding and margin.

When I talked about CSS nodes, I mentioned how widgets can have extra nodes for their ‘components’. This extends to gadgets: each of the widgets components gets their own CSS box, with its own margin, padding, background and whatnot.

So, lets continue the coloring exercise by making our CSS snipplet match not just the radiobutton itself, but also the label and the indicator. Their CSS names are label and radio.

This is how it looks. Here, we can actually see the margin of the label have an effect: it causes the content area (in blue) to be bigger than it would otherwise be.

I hope by now it is obvious that this is giving a lot of expressive power to theme authors, who can use all of this to affect the layout and rendering of all the widgets and their components. And there are a lot of them:

The GtkInspector is a really useful tool for exploring what is possible with all of this. It gives easy access to both the CSS nodes of each widget:

…and to the CSS properties of each node, which is basically the outcome of matching the theme CSS information to the node tree, also taking into account inherited properties and other complications:

CSS properties

Whats next ? All of what I’ve shown here  is already available in GTK+ 3.19.5. We’ve made good progress on converting most widgets to use gadgets internally (‘progress’ is a bit of an understatement, it was a herculean effort, mainly by Benjamin Otte, Cosimo Cecchi and myself). But we are not done yet, so we will continue working on completing the conversion, and on documenting GTKs CSS capabilities better.

When that is done,  we can look at adding other interesting bits of the CSS spec, like calc() or border collapsing. CSS is a huge standard, and theme designers always ask for more.

A GTK+ update

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.Spinning
  • CSS nodes can explored and manipulated in GtkInspector.Inspect!
  • 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. Fancy Switches
  • 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.Fancy 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_style_context_save (context);
gtk_style_context_set_state (contexts,
gtk_style_context_get_color (context,
          gtk_style_context_get_state (context),
gtk_style_context_restore (context);

What else is new ?

Support for help overlays Shortcuts 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.

Boston GNOME Summit update

The Boston GNOME summit this year is a small, focused hackfest.


The first day was filled with discussions and planning, with one of the central topics being how to make gnome-builder, xdg-app and gnome-continuous play well together. You can find notes and conclusions from this discussion here.


In the afternoon, Christian Hergert gave us an extensive demo of gnome-builder, with led to lots of discussion around future plans.

The second day was entirely devoted to hacking. Everybody got something done:

  • Cosimo added support for operating with elevated privileges to gvfs.  Here is a screencast showing this in action:

    The code for this is already in gvfs git.

  • Owen debugged and fixed various issues with gnome-builder under Wayland: mispositioned code completion popups and window stacking problems with the project chooser.
  • Christian asked everybody in the room what missing features kept them from using gnome-builder, and implemented several of the answers he got. One example is better indentation support in both emacs and vi modes.
  • Giovanni added support to the gnome-continuous build machinery to produce xdg-app bundles, and used it to produce an xdg-app for gnome-weather.
  • Myself, I took the shortcuts overlay implementation from gnome-builder and adapted it for GTK+.
    Shortctus overlay
    This code can be found in gtk+ git.

Thanks to everybody who participated so far. The Summit will continue tomorrow with more discussion and hopefully more productive hacking.

I’d also like to thank  Walter Bender and the MIT for hosting us, and Red Hat for sponsoring our breakfasts.