Layout managers in GTK 4

Containers and layout policies have been a staple of GTK’s design since the very beginning. If you wanted your widget to lay out its children according to a specific policy, you had to implement GtkContainer for handling the addition, removal, and iteration of the child widgets, and then you had to implement the size negotiation virtual functions from GtkWidget to measure, position, and size each child.

One of the major themes of the GTK 4 development cycle is to delegate more functionality to ancillary objects instead of encoding it into the base classes provided by GTK. For instance, we moved the event handling from signal handlers described by GtkWidget into event controllers, and rendering is delegated to GtkSnapshot objects. Another step in that direction is decoupling the layout mechanism from GtkWidget itself to an ancillary type, GtkLayoutManager.

Layout Managers

A layout manager is the object responsible for measuring and sizing a widget and its children. Each GtkWidget owns a GtkLayoutManager, and uses it in place of the measure() and allocate() virtual functions—which are going away. The gist of the change: instead of subclassing a GtkWidget to implement its layout policy, you subclass GtkLayoutManager, and then assign the layout manager to a widget.

Just like in the old GtkWidget code, you will need to override a virtual function to measure the layout, called measure(), which replaces the get_preferred_* family of virtual functions of GTK 3:

static void
layout_measure (GtkLayoutManager *layout_manager,
                GtkWidget        *widget,
                GtkOrientation    orientation,
                int               for_size,
                int              *minimum,
                int              *natural,
                int              *minimum_baseline,
                int              *natural_baseline)

After measuring, you need to assign the size to the layout; this happens in the allocate() virtual function, which replaces the venerable size_allocate() virtual function of previous GTK major versions:

static void
layout_allocate (GtkLayoutManager *layout_manager,
                 GtkWidget        *widget,
                 int               width,
                 int               height,
                 int               baseline)

On the more esoteric side, you can also override the get_request_mode() virtual function, which allows you to declare whether the layout manager requests a constant size, or if one of its sizes depend on the opposite one, like height-for-width or width-for-height:

static GtkSizeRequestMode
layout_get_request_mode (GtkLayoutManager *layout_manager,
                         GtkWidget        *widget)

As you may notice, each virtual function gets passed the layout manager instance, as well as the widget that is using the layout manager.

Of course, this has bigger implications on various aspects of how GTK widgets work, the most obvious being that all the complexity for the layout code can now stay confined into its own object, typically not derivable, whereas the widgets can stay derivable and become simpler.

Another feature of this work is that you can change layout managers at run time, if you want to change the layout policy of a container; you can also have a per-widget layout policy, without adding more complexity to the widget code.

Finally, layout managers allow us to get rid of one of the special cases of GTK, namely: container child properties.

Child properties

Deep in the guts of GtkContainer sits what’s essentially a copy of the GObject property-related code, and whose only job is to implement “child” properties for types deriving from GtkContainer. These container/child properties exist only as long as a child is parented to a specific class of container, and are used for a variety of reasons—but, generally, to control layout options, like the packing direction in boxes and box-like containers; the fixed positioning inside GtkFixed; or the expand/fill rules for notebook tab widgets.

Child properties are hard to use, as they require ad hoc API instead of the usual GObject one, and thus require special casing in GtkBuilder, gtk-doc, and language bindings. Child properties are also attached to the actual direct child of the container, so if a widget interposes a child—like, say, GtkScrolledWindow or GtkListBox do—then you need to keep a reference to that child around in order to change the layout that applies to your own widget.

In GTK’s master branch we got rid of most of them—either by simply removing them when there’s actual widget API that implements the same functionality, or by creating ancillary GObject types and moving child properties to those types. The end goal is to remove all of them, and the relative API from GtkContainer, by the time GTK 4 rolls out. For layout-related properties, GtkLayoutManager provides its own API so that objects are created and destroyed automatically once a child is added to, or removed from, a widget using a layout manager, respectively. The object created is introspectable, and does not require special casing when it comes to documentation or bindings.

You start from deriving your own type from the GtkLayoutChild class, and adding properties just like you would for any other GObject type. Then, you override GtkLayoutManager‘s create_layout_child() virtual function:

static GtkLayoutChild *
create_layout_child (GtkLayoutManager *manager,
                     GtkWidget *container,
                     GtkWidget *child)
{
  // The simplest implementation
  return g_object_new (your_layout_child_get_type (),
                       "layout-manager", manager,
                       "child-widget", child,
                       "some-property", some_property_initial_state,
                       NULL);
}

After that, you can access your layout child object as long as a widget is still a child of the container using the layout manager; if the child is removed from its parent, or the container changes the layout manager, the layout child is automatically collected.

New layout managers

Of course, just having the GtkLayoutManager class in GTK would not do us any good. GTK 4 introduces various layout managers for application and widget developers:

  • GtkBinLayout implements the layout policy of GtkBin, with the added twist that it supports multiple children stacked on top of each other, similarly to how GtkOverlay works. You can use each widget’s alignment and expansion properties to control their location within the allocated area, and the GtkBinLayout will always ask for as much space as it’s needed to allocate its largest child.
  • GtkBoxLayout is a straight port of the layout policy implemented by GtkBox; GtkBox itself has been ported to use GtkBoxLayout internally.
  • GtkFixedLayout is a port of the fixed layout positioning policy of GtkFixed and GtkLayout, with the added functionality of letting you define a generic transformation, instead of a pure 2D translation for each child; GtkFixed has been modified to use GtkFixedLayout and use a 2D translation—and GtkLayout has been merged into GtkFixed, as its only distinguishing feature was the implementation of the GtkScrollable interface.
  • GtkCustomLayout is a convenience layout manager that takes functions that used to be GtkWidget virtual function overrides, and it’s mostly meant to be a bridge while porting existing widgets towards the layout manager future.

We are still in the process of implementing GtkGridLayout and make GtkGrid use it internally, following the same pattern as GtkBoxLayout and GtkBox. Other widgets inside GTK will get their own layout managers along the way, but in the meantime they can use GtkCustomLayout.

The final step is to implement a constraint-based layout manager, which would let us create complex, responsive user interfaces without resorting to packing widgets into nested hierarchies. Constraint-based layouts deserve their own blog post, so stay tuned!

Entries in GTK 4

One of the larger refactorings that recently landed in GTK master is re-doing the entry hierarchy. This post is summarizing what has changed, and why we think things are better this way.

Entries in GTK 3

Lets start by looking at how things are in GTK 3.

GtkEntry is the basic class here. It implements the GtkEditable interface. GtkSpinButton is a subclass of GtkEntry. Over the years, more things were added. GtkEntry gained support for entry completion, and for embedding icons, and for displaying progress. And we added another subclass, GtkSearchEntry.

Some problems with this approach are immediately apparent. gtkentry.c is more than 11100 lines of code. It it not only very hard to add more features to this big codebase, it is also hard to subclass it – and that is the only way to create your own entries, since all the single-line text editing functionality is inside GtkEntry.

The GtkEditable interface is really old – it has been around since before GTK 2. Unfortunately, it has not really been successful as an interface – GtkEntry is the only  implementation, and it uses the interface functions internally in a confusing way.

Entries in GTK 4

Now lets look at how things are looking in GTK master.

The first thing we’ve done is to move the core text editing functionality of GtkEntry into a new widget called GtkText. This is basically an entry minus all the extras, like icons, completion and progress.

We’ve made the GtkEditable interface more useful, by adding some more common functionality (like width-chars and max-width-chars) to it, and made GtkText implement it. We also added helper APIs to make it easy to delegate a GtkEditable implementation to another object.

The ‘complex’ entry widgets (GtkEntry, GtkSpinButton, GtkSearchEntry) are now all composite widgets, which contain a GtkText child, and delegate their GtkEditable implementation to this child.

Finally, we added a new GtkPasswordEntry widget, which takes over the corresponding functionality that GtkEntry used to have, such as showing a Caps Lock warning

or letting the user peek at the content.

Why is this better?

One of the main goals of this refactoring was to make it easier to create custom entry widgets outside GTK.

In the past, this required subclassing GtkEntry, and navigating a complex maze of vfuncs to override. Now, you can just add a GtkText widget, delegate your GtkEditable implementation to it, and have a functional entry widget with very little effort.

And you have a lot of flexibility in adding fancy things around the GtkText component. As an example, we’ve added a tagged entry to gtk4-demo that can now be implemented easily outside GTK itself.

Will this affect you when porting from GTK 3?

There are a few possible gotcha’s to keep in mind while porting code to this new style of doing entries.

GtkSearchEntry and GtkSpinButton are no longer derived from GtkEntry. If you see runtime warnings about casting from one of these classes to GtkEntry, you most likely need to switch to using GtkEditable APIs.

GtkEntry and other complex entry widgets are no longer focusable – the focus goes to the contained GtkText instead. But gtk_widget_grab_focus() will still work, and move the focus the right place. It is unlikely that you are affected by this.

The Caps Lock warning functionality has been removed from GtkEntry. If you were using a GtkEntry with visibility==FALSE for passwords, you should just switch to GtkPasswordEntry.

If you are using a GtkEntry for basic editing functionality and don’t need any of the extra entry functionality, you should consider using a GtkText instead.

Testing Discourse for GTK

For the past 20 years or so, GTK used IRC and mailing lists for discussions related to the project. Over the years, use of email for communication has declined, and the overhead of maintaining the infrastructure has increased; sending email to hundreds or thousands of people has become increasingly indistinguishable from spam, in the eyes of service providers, and GNOME had to try and ask for exceptions—which are not easy to get, and are quite easy to be revoked. On top of that, the infrastructure in use for managing mailing lists is quite old and crumbly, and it’s unnecessarily split into various sub-categories that make following discussions harder than necessary.

After discussions among the GTK team, with the GNOME infrastructure maintainers, and with the GTK community at large, we decided to start a trial run of Discourse as a replacement for mailing lists, first and foremost, and as a way to provide an official location for the GTK community to discuss the development of, and with, GTK—as well as the rest of the core GNOME platform: GLib, Pango, GdkPixbuf, etc.

You can find the Discourse instance on discourse.gnome.org. On it, you can use the Platform and Core categories for discussions about the core GNOME platform; you can use the appropriate tags for your topics, and subscribe to the ones you’re interested in.

We’re planning to move some of the pages on the wiki to Discourse as well, especially the ones where we expect feedback from the community.

We’re still working on how to migrate users of the various mailing lists related to GTK, in order to close the lists and have a single venue instead of splitting the community; in the meantime, if you’re subscribed to one or more of these lists:

  • gtk-devel-list
  • gtk-app-devel-list
  • gtk-list
  • gtk-i18n-list

then you may want to have a look at Discourse, and join the discussions there.

Report from the GTK hackfest in Brussels

Thanks to the GNOME Foundation, various GTK developers were able to meet in Brussels right after FOSDEM, for one of our yearly hackfests.

The main topics of the hackfest were:

  • recap the work that landed into the master branch in the past 6-12 months, in order to have everyone on the same page
  • discuss the features still in flight in separate branches, assess their state of completion, and identify blockers
  • figure out what are the blockers for the first release of GTK 4.0

Hackfests allow us to have this kind of discussions with a large bandwidth at our disposal, compared to online communication channels, so they are very important for the project.

You can see the full agenda on the wiki, and we’ll make sure to write articles on the biggest items on it.

The largest items of the discussion were the introduction of new list models and list/grid view widgets; a unified key handling API; the decoupling of layout management policies from containers, and the introduction of constraint layout management; the possibility of merging widgets from libhandy, to allow for writing applications responsive to form factor changes; the switch to a purely declarative menu description API, and the removal of public menu widgets; adding 2D and 3D transformations to GtkWidget; implementing an animation API that applications can consume.

  • list models and list/grid widgets — we’d really like to retire GtkTreeView and GtkIconView, but the existing replacements, GtkListBox and GtkFlowBox, are not performant enough when scaling to very large and dynamic data sets. We need better data storage types, that can be composed to perform operations such as mapping, filtering, and sorting, but can also avoid iterating over all the elements when sizing and drawing widgets. Benjamin Otte already added various models to GTK, and is working on a list and a grid view widgets that can efficiently display their contents. Benjamin and other GNOME application developers are in the process of identifying various stakeholders for  a separate hackfest specifically for gathering more requirements and getting feedback on the new API.
  • unified key handling API — now that we moved all our pointer and touch input handling away from events and towards gestures, we want to do the same for key handling, like key bindings, mnemonics, and accelerators. The overall design is based on triggering actions, and allow introspection of all the “shortcuts” currently available to the GTK inspector, for ease of debugging. There is a development branch already available.
  • layout managers — in GTK 3, layout is imposed by containers on their children; we want to be able to decouple that from widgets and move it into a separate delegate objects hierarchy. Layout managers allow us to reduce the complexity of writing new widgets; they keep the layout code in a separate, non-derivable type; and they allow us to simplify the toolkit internals to the point that we might even make GtkWidget and instantiable type in the future. Layout managers are the first step towards adding constraint-based layout management to GTK, which do away with nesting boxes to create complex UIs. There is a development branch already available. For more information on constraint layouts, you can see the Emeus experimental library for GTK 3.
  • merging widgets from libhandy — Adrien Plazas gave an overview of what’s currently provided by libhandy, and what would be useful to have straight from GTK4 in the future. We discussed reactive layouts, and the ability express sizing with percentages, as well as possibly using constraints to get similar results.
  • declarative menus — GTK has iterated over different menus API over the years; from building menus out of widgets, to GtkUIManager, to GtkBuilder, to GMenu; we also moved to declaring the behaviour of pop up menus, in order to have the windowing system display them more accurately without exposing global coordinates. There’s a lot of overlap, but no clear winner, mostly because we still allow using widgets to build application menus and context menus. Fully switching to declarative style menus, adding new API to make them more expressive, and making GtkMenu and friends private implementations for the toolkit, would allow us to get things like being able to inspect all menus, even out of process; menus manipulable by plugin systems without necessarily creating widgets and keeping track of them; avoiding positioning bugs. There is a full strawman proposal available on the wiki, and Matthias Clasen is working on switching context menus to GMenu in a development branch.
  • widget transformations — Sadly, Timm Bädert couldn’t make it to the hackfest, but we’ve been reviewing his development branch that adds 2D and 3D transformations to GTK widgets, and we’re very excited about it.
  • animations — one last thing we’d like to land for GTK4 is an animation framework for GTK widgets to replace the current generic “frame tick callback”. The model for it is the Clutter explicit animation API, which in turn was based on Core Animation and CSS3 transitions. This work is still in the design phase, but you can expect development branches for it to land soon.

Aside from the big topics, we also discussed various smaller ones:

  • improving performance and memory use; we want to expose the SysProf counters during the frame clock phases, so we can easily identify problems.
  • improving the test suite, especially when it comes to reporting failures; right now, we have to go through the CI failure log, but we’d like to publish proper reports using the GitLab CI infrastructure
  • replacing child properties with real GObject properties on ancillary objects, especially for layout managers; would make documentation, introspection, and usage clearer.
  • finishing the drag and drop rework, to get a more modern API.
  • adding a top-level interface for “window-like” objects—such as windows, dialogs, popovers, menus/popups—useful for establishing common behaviour, and removing hacks and complexity in GtkWindow.

And, finally, yes: we did remove the “plus” from GTK. ;-)

Theme changes, revisited

A quick update on last weeks post about theme changes:

We’ve made a 3.24.4 release, to fix up a few oversights in 3.24.3. This release does not include the new theme yet, we will push that to the next release.

We’ve also made another NewAdwaita tarball, which includes refinements based on some of the suggestions we received since last week.

Try it out, and tell us about it!

Theme changes in GTK 3

Adwaita has been the default GTK+ theme for quite a while now (on all platforms). It has served us well, but Adwaita hasn’t seen major updates in some time, and there is a desire to give it a refresh.

Updating Adwaita is a challenge, since most GTK applications are using the stable 3.x series, and some of them include Adwaita-compatible theming for their own custom widgets. Given the stable nature of this release series, we don’t want to cause theme compatibility issues for applications. At the same time, 3.x is the main GTK version in use today, and we want to ensure that GTK applications don’t feel stale or old fashioned.

A trial

A number of approaches to this problem have been considered and discussed. Out of these, a tentative plan has been put forward to trial a limited set of theme changes, with the possibility of including them in a future GTK 3 release.

Our hope is that, due to the limited nature of the theme changes, they shouldn’t cause issues for applications. However, we don’t want to put our faith in hope alone. Therefore, the next three weeks are being designated as a testing and consultation period, and if things go well, we hope to merge the theme into the GTK 3.24.4 release.

It should be emphasised that these changes are confined to Adwaita itself. GTK’s CSS selectors and classes have not been changed since GTK 3.22, and the changes in Adwaita won’t impact other GTK themes.

The Adwaita updated theme is being made available as a separate tarball in parallel with the GTK 3.24.3 release, and can be downloaded here. GTK application developers are invited to try 3.24.3 along with the new version of Adwaita, and report any issues that they encounter. The GTK team and Adwaita authors will also be conducting their own tests. Details of how to test the new theme in various ways are described here.

We are hoping to strike a balance between GTK’s stability promises on the one hand, and the desire to provide up-to-date applications on the other. It is a delicate balance to get right and we are keen to engage with GTK users as part of this process!

Theme changes

The rest of this post summarises which changes are have been made to the theme. This will hopefully demonstrate the limited extent of these changes. It will also help developers know what to look for when testing.

Colors

Many of the Adwaita colors have been very slightly tweaked. The new colors are more vivid than the previous versions, and so give Adwaita more energy and vibrancy. The new colors also form part of a more extensive palette, which is being used for application icons. These colours can also be used in custom application styling.

The color changes are subtle, so any compatibility issues between the new and the old versions should not be serious. Blue is still blue (just a slightly different shade!) Red is still red. Visually, the dark and light versions of the theme remain largely the same.

Adwaita’s dark variant, showing the slight color changes between old (left) and new (right).

Note that the red of the button has been toned down a bit in the dark theme.

Header bars and buttons

Most widgets have not been specifically changed in the updated version of Adwaita. However, two places where there are widget-specific changes are header bars and buttons. In both cases, an effort has been made to be lighter and more elegant.

Buttons have had their solid borders replaced with shadows. Their background is also flatter and their corners are more rounded. Their shape has also been changed very slightly.

Header bars have been updated to complement the button changes. This has primarily been done by darkening their background, in order to give buttons sufficient contrast. The contrast between header bars’ focused and unfocused states has also been increased. This makes it easier for users to identify the focused window.

At first glance, these changes are some of the most significant, but they are achieved with some quite minor code changes.

The header bar in GNOME’s Calendar app (old version on top, new version on the bottom):

Switches

Aside from header bars and buttons, the only other widget to be changed is switches. When GTK first introduced switches, they were a fairly new concept on the desktop. For this reason, they included explicit “ON” and “OFF” labels, in order to communicate how the switches operated. Since then, switch widgets have become ubiquitous, and users have become familiar with switches that don’t contain labels.

The latest Adwaita changes bring the theme into line with other platforms and make switches more compact and modern in appearance, by removing the labels and introducing a more rounded shape.

Elsewhere, no change

Aside from the changes described above, very little has changed in Adwaita. The vast majority of widgets remain the same, albeit with very slightly altered colours. Generally, UI layouts shouldn’t alter and users should feel comfortable with the changes.

Spot the difference (the old version of Adwaita is on the left and the new version is on the right):

Conclusion

Please try the new theme. We hope you like it!

And we appreciate your feedback—in particular if you are a GTK application developer. You can provide it on irc (in the #gtk+ channel on GimpNet) or via the gtk-devel-list mailing list, or by filing an issue in gitlab.

A report from the Guadec GTK+ BoF

The GTK+ team had a full day planning session during the BoF days at Guadec, and we had a full room, including representatives from several downstreams, not just GNOME.

We had a pretty packed agenda, too.

GTK+ 3

We started out by reviewing the GTK+ 3 plans that we’ve outlined earlier.

In addition to what was mentioned there, we also plan to backport the new event controllers, to make porting to GTK+ 4 easier. We will also add meson build support to help with Windows builds.

The 3.24 releases will effectively be a continuation of the 3.22 branch and should be entirely safe to put out as stable updates in distributions.

We plan to release GTK+ 3.24.0 in time for GNOME 3.30.

GTK+ 4 leftovers

The bulk of the day was taken up by GTK+ 4 discussion. We’ve reviewed the list of leftover tasks on the roadmap:

  • Finish DND: Gestures on the GTK+ level, local shortcuts
  • Introduce GtkToplevel and cleanly support popovers
  • Add transformations
  • Create a shortcuts event controller to replace key bindings
  • Port GtkTextView to render nodes
  • Profile the cairo backend, make sure its performance is on par with GTK+ 3
  • Port various dependent libraries:
    • vte
    • webkit
    • libchamplain
    • gtk-vnc
    • gtk-spice

Most of these tasks have names next to them, but if you want to help with any of these tasks, by all means, contact us!

Noticeably absent from this list are a few things that were on the roadmap before:

  • Constraint-based layout (emeus)
  • Shader compiler and application provided shaders
  • Designer support

All of these can still happen if merge requests appear, but we don’t think that we should block on them. They can be developed externally to GTK+ 4, and become GTK+ 5 material.

GTK+ backends

We spent some time evaluating the state of GDK backends in GTK+ master.

The Windows backend is in OK shape. We have several people who help with maintenance and feature development for it, meson makes building it a lot easier, and we have ci for it.

The Quartz backend is in a much worse state. It has not been kept in buildable shape, nobody is providing fixes or feature development for it, and we don’t have ci. We had a macbook offered that could be used for ci, and it was suggested that we could use travis ci for the OS X.

GTK+ timeline

We spent a long time on this, and did not reach a 100% consensus, but it seems realistic to aim for a GTK+ 4 release in spring of 2019, if we keep making good progress on the outstanding leftovers.

When we release GTK+ 3.96, we will also announce a date for GTK+ 4.0. We hope to be able commit to release before GNOME 3.32, so GNOME application developers can switch their master branches to GTK+ 4 without worrying about whether that will disrupt other development for 3.32.

Application porting

We really want feedback from application ports at this point. But we are in a bit of a difficult position, since we can’t plausibly claim to be done with major API work until the GtkToplevel and shortcuts controller work is done.

Our recommendation to app authors at this point is:

  • If you are a bit adventurous, do a port to 3.94 on a branch. It should be possible to keep it working without too much work during the remainder of GTK+ 4 development.
  • If you are not quite as adventurous, wait until 3.24 is released, use it to prepare your port, and port to GTK+ 3.96.
  • Either way, please make your port available to users for testing, either as a regular release, or as a Flatpak with a bundled GTK+.

GLib diversion

In the afternoon, we spent a while talking about GLib. We went over a laundry list of larger and smaller items. Notable highlights: GProperty may happen for 2.60 and we may be able to use g_autoptr soon.

Other ideas

We discussed a great number of other things that we could and should do.

For example, it was suggested (and generally agreed to) that we should merge gsk into gdk, since it is small and the internals are somewhat intertwined. It was also suggested to create subdirectories in gtk/, for example for the css machinery.

News from GLib 2.58

Next September, GLib will hit version 2.58. There have been a few changes during the past two development cycles, most notably the improvement of the Meson build, which in turn led to an improved portability of GLib to platforms such as Windows, macOS, and Android. It is time to take stock of the current status of GLib, and to highlight some of the changes that will impact GLib-based code.

  • Meson – Thanks to the ongoing work of Nirbheek Chauhan and Xavier Claessens, the Meson build has been constantly improving, to the point that we can start switching to it as the default build system. The plan—as outlined on the mailing list—is to release GLib 2.58 using Meson, while keeping the Autotools build in tree and available in the release archive; then, we’ll drop the Autotools build during the following development cycle, and release GLib 2.60 without Autotools support. Linux distributors are very much welcome to start testing the Meson build in their builders; we’ve been running the Meson build as part of our CI process for a while, now, but more exposure will bring out eventual regressions that we missed; additionally, it would be stellar if people with different toolchains than GCC/Clang/MSVC would start trying the Meson build and report bugs. In the meantime, if you’re using GLib on macOS and Windows, we already recommend you switch to Meson to build GLib, as it’s easier and better integrated with those platforms than Autotools
  • Reliability and portability – GLib switched to GitLab alongside the rest of GNOME, which meant being able to run continuous integration outside of the GNOME Continuous builds. Now we run CI on multiple toolchains, multiple build systems, and multiple platforms for every commit and merge request, which significantly reduces the chances of a broken build. We’ve also improved the code coverage in the test suite. Of course, we could always do better; for instance, we don’t have a CI runner for macOS and the Solaris family of OSes, and more runners for the *BSD family would be greatly appreciated. We’ve issued a call for help, if you have a spare machine and some bandwidth that you can donate
  • File monitoring on *BSD – Apropos the *BSD family, the kqueue backend for file monitoring in GIO has been completely overhauled by Martin Pieuchot and Ting-Wei Lan; the new code is simpler, more robust, and passes all the tests
  • Use posix_spawn() for efficient process launching — Thanks to Daniel Drake, GLib now can use posix_spawn() under specific circumstances, if the platform’s C library supports it; this allows hitting fast paths in the kernel, compared to manually calling fork() + exec(); those fast paths are especially beneficial when running on memory constrained platforms
  • Reference counting types and allocations — GLib uses reference counting as a memory management and garbage collection mechanism in many of its types, but lacks the public API to allow other people to implement the same semantics in their own data structures; this leads to much copy-pasting and re-implementations, and typically to things like undefined behavior when it comes to saturation and thread safety. GLib 2.58 has a grefcount and a gatomicrefcount types, alongside their API, to reduce this duplication. Additionally, taking a cue from other languages like Rust, GLib provides a way to add reference counting semantics on memory allocations, by adding a low level API that allows you to allocate structures that do not have a reference count field, and automatically add reference counting semantics to them
  • Deprecations – A few soft deprecations have become real deprecations in this last development cycle:
      • g_type_class_add_private() has finally been deprecated, five years after we introduced the instance private data macros; if you’re still using that function in your class initialization, please switch to G_DEFINE_TYPE_WITH_PRIVATE or G_ADD_PRIVATE
      • g_main_context_wait() is officially deprecated, but you should have already seen run time warnings about its use
      • gtester, the GTest harness provided by GLib, is deprecated; if you’re using Autotools, you should use the TAP harness that comes with Automake

There have been lots of contributions in GLib, in this past cycle, thanks to the tireless efforts of Philip Withnall; he’s been instrumental in reviewing patches, triaging bugs, and implementing changes in the development process of the project. The switch over to GitLab has also improved the contribution process, with many more developers opening merge requests:

  • 2.54.0..c182cd68: 968 changesets from 143 developers, up from 412 changesets and 68 developers during the 2.53 development cycle
  • A total of 31851 lines added, 27976 removed (delta: +3875)
Developers with the most changesets
Philip Withnall 303 31.3%
Xavier Claessens 79 8.2%
Emmanuele Bassi 69 7.1%
Christoph Reiter 42 4.3%
Ting-Wei Lan 21 2.2%
Chun-wei Fan 21 2.2%
Nirbheek Chauhan 21 2.2%
Ondrej Holy 20 2.1%
Руслан Ижбулатов 20 2.1%
Mikhail Zabaluev 20 2.1%
Simon McVittie 15 1.5%
Matthias Clasen 14 1.4%
Christian Hergert 13 1.3%
Iñigo Martínez 12 1.2%
Bastien Nocera 10 1.0%
Rafal Luzynski 9 0.9%
Michael Catanzaro 9 0.9%
Will Thompson 8 0.8%
Allison Lortie 8 0.8%
Daniel Boles 8 0.8%

Make sure to test your code with GLib 2.57.2, the next development snapshot towards the 2.58.0 stable release.

GTK+ 3.94

Today, we released GTK+ 3.94.0. Again, it has been a while since the last release, so it is worth summarizing whats new in this release. There is really too much here to cover it all, so this post will only highlight the most important changes.

This release is another milestone on our way towards GTK+ 4. And while there are still some unfinished things, this release is much closer to we hope to achieve with GTK+ 4.

GSK

The Broadway backend now has a GskRenderer, so the future for Broadway looks much better.

We introduced a new type of render node, GskOffsetNode, which is a simplified GskTransformNode and takes over the job of translating content as we move up and down the render node tree. With this change, we are now able to cache render nodes for widgets over multiple frames, and reposition them if necessary.

We also introduced GskDebugNodes, which take over node names, and let us simplify some of the GTK+ apis for creating render nodes.

When falling back to cairo for rendering, we now use recording surfaces instead of image surfaces, so we can replay the rendering at a different scale.

An important new operation is gsk_render_node_diff to compare two render node trees (see below for more on this).

GDK

Following the general trend of aligning the GDK apis with Wayland instead of X, GdkWindow was renamed to GdkSurface.

The GdkTexture api has been refined, with new GdkMemoryTexture and GdkGLTexture subclasses, and a powerful new abstraction, GdkPaintable, has been introduced.

A GdkPaintable represents an object that can be painted anywhere at any size without requiring any sort of layout. This is inspired by similar concepts elsewhere, such as ClutterContent, HTML/CSS Paint Sources or SVG Paint Servers. To show off the power of this concept, a few new demos have been added in gtk4-demo:

The DND code continues to see major refactorings. It now uses the same content-provider infrastructure that was introduced in 3.93 for clipboard handling, and it has separate objects for the source and target side of a DND operation. More changes will be coming here.

GTK

widgets

GTK+ has gained support for showing videos, with the GtkVideo and GtkMediaControls widgets, and there is also a new GtkPicture widget to split off image viewing from GtkImage (which is really about icons).

GtkFontChooser allows tweaking OpenType features and font variations, and Ctrl-Shift-e for color Emoji input has been replaced with completion that can be enabled with the GtkEntry::enable-emoji-completion property.

Input

The event-specific signals in GtkWidget continue to disappear. At this point only ::event is left, but it will go away too. Instead, we are using event controllers, and several new ones have been added to cover all needed events:

  • GtkEventControllerMotion
  • GtkEventControllerKey
  • GtkGestureStylus

To make this transition easier, it is now possible to create event controllers in ui files.

Wayland has its own platform input method, based on the Wayland text protocol.

Drawing

The ::draw signal has been removed, all widgets have to implement ::snapshot. They can now create their own GtkSnapshot instances for intermediate rendering. Clipping is no longer applied on the GTK+ level – widgets are free to draw outside their allocation, if that is what is required.

Widget invalidation has been changed, it now works by discarding the cached render nodes of invalidated widgets, and recreating the missing parts of the render node tree.

For finding the region that needs to be redrawn, GTK+ diffs the render node trees of the previous and the current frame, and applies some heuristics to keep the number of rectangles from growing too large.

The GTK+ inspector lets you track invalidations, which you can see in action here:

Other changeS

GTK+ no longer supports generic loadable modules. Input methods, print backends and media backends have been converted to GIOModules and extension points.

The platform im modules (i.e. the Windows, Wayland, Broadway im contexts)  are always included and will be enabled by default on their platform.

The Vulkan support in GDK can now use a particular device that is specified by the GDK_VULKAN_DEVICE environment variable. Use GDK_VULKAN_DEVICE=list to see all availble devices.

Try it out

With GTK+ 3.94.0, it should be possible to start porting applications. The documentation has an initial porting guide.

A GTK+ 3 update

Plans

When we started development towards GTK+ 4, we laid out a plan that said GTK+ 3.22 would be the final, stable branch of GTK+ 3.  And we’ve stuck to this for a while.

I has served us reasonably well — GTK+ 3 stopped changing in drastic ways, which was well-received, and we are finally seeing applications moving from GTK+ 2.

Reality

But, GTK+ 4 is taking its time to mature (more on that in another post), and some nice new features (such as font variation support, or Emoji completion) languish unused in master. We also get requests for critical APIs from some of the ported applications.

Therefore, we have decided that it is better to change course and allow a limited amount of new features and API in GTK+ 3.x, by doing a GTK+ 3.24 release in September.

There is now a gtk-3-24 branch in git. GTK+ 3.x maintenance has moved to that branch, and we won’t be doing any further 3.22.x releases.

Highlights

The first release off this new branch is GTK+ 3.23.0, which can be found here:

https://download.gnome.org/sources/gtk+/3.23/gtk+-3.23.0.tar.xz

The highlights of this release include new font chooser features,

  • Allow setting OpenType font features
  • Show examples for OpenType font features
  • Allow selecting OpenType font variations
  • Support levels of details for selection

new Emoji features,

  • Support a completion popup for Emoji
  • Drop Ctrl-Shift-e shortcut

gdk_window_move_to_rect as public API,

and the Wayland backend using anonymous shared memory on FreeBSD.

Numerology

A side-effect of doing one more 3.x cycle is that we will have GTK+ 3.24 to be the final GTK+ 3, which is a pleasant parallel to GTK+ 2.24 being the final GTK+ 2.