GTK Hackfest 2020 — Roadmap and accessibility

Between January 28th and January 31st, the GTK team held what’s now the third hackfest in Brussels.

The main topics of the hackfest were:

  • the schedule for the next development snapshot of GTK4
  • the missing features blocking the release of GTK 4.0
  • the current state of the accessibility support in the toolkit

The first two items occupied the most of the first two days of the hackfest; you can read the GTK 3.98 release announcement for what we’ve been working on for the past 300 days since the 3.96 release. The missing features are:

  • Event controllers for keyboard shortcuts
  • Movable popovers on Wayland
  • Row-recycling list and grid views
  • Animation API

and all of them are being worked on in topic branches. The keyboard shortcuts branch has recently been rebased, and it’s in the process of being documented and cleaned up; the movable popovers is also being reviewed after a few iterations. The last two remaining branches are fairly sizeable, and will require some more iterations to get them right—with the animations API currently being mostly a prototype.

The final topic of the hackfest was the largest, and was a discussion long overdue.

GTK’s accessibility support was added as part of the GTK 2.0 release by the Sun Accessibility Team; it depends on the abstract data types provided by ATK (the Accessibility Tool Kit), which are then implemented concretely in GTK classes like GtkWidgetAccessible, or GtkEntryAccessible. Each widget has an “accessible” object associated to it, which is either automatically created by GTK, or can be provided by application code when subclassing a GTK widget. Non-widget types can also have accessible objects associated to them—the most notable case is the set of cell renderers for tree views and combo boxes. Underneath it all, sits AT-SPI, a protocol that is used by AT—Accessible Technologies, like a screen reader—to consume the data provided by applications. Typically, ATs will use a library like libatspi to deal with the protocol itself.

The main issues with the existing stack are:

  • there’s a lot of indirection caused by the existence of ATK; any new feature or bug fix needs to be defined inside ATK and then implemented into GTK and libatspi
  • ATK was written in a very different environment, and while it has seen a few deprecations, it shows its age in the assumptions it makes—like global coordinate spaces—and in its design
  • there’s a certain overlap between AT requirements and requirements for GUI testing that end up creating friction in the API design
  • the stack has fell in disrepair since the Sun accessibility team was disbanded; most of the ongoing work is still pretty much happening in the AT space (like Orca) and in web browsers
  • the entire stack was written when CORBA was a thing, and then ported to DBus in time for GNOME3; the protocol, though, is not really efficient and requires lots of roundtrips to move around small amounts of data, instead of having bulk operations and notifications

The last point is also the reason why we need a separate accessibility bus in order to avoid spamming the session bus, and making everything slower as soon as the accessibility support is enabled. A separate bus means that we need to poke an additional hole in any sandbox, and still lets everything that connects to the accessibility bus potentially snoop into what happens in every application.

Finally, GTK only supports accessibility on Linux; there is no support for macOS or Windows, which means applications written in GTK and ported to other platforms are not accessible to ATs there. As we expose ATK in our API, adding support for accessibility features on other platforms would require bridging ATK, creating further complexity.

As we want to redesign and update the accessibility features in GTK4, we need to understand what are the requirements for existing consumers of the accessibility stack, and what kind of use cases we need to target. For that, we asked Hypra, a company dedicated to the development of accessible solutions based on free and open source software, to help us.

Hypra developers are familiar with GNOME, and have been working on the Linux accessibility stack. Their clients cover a wide gamut of accessibility users, so they are in the best position to describe what kind of ATs are in actual use on a day to day basis.

There are a wide range of tools and functionality that have to be provided by different layers of the stack, from the toolkit to the compositor; application developers must also have access to the tools necessary to provide proper support to ATs, as they have a much better idea of what their applications should look and behave than the toolkit.

Over the course of two days we have identified a plan for moving forward:

  • drop ATK from the stack, and have GTK talk the AT-SPI protocol directly; this is similar to what Qt does from the toolkit side, and it makes it easier to both expand and verify eventual protocol changes
  • clean up the AT-SPI protocol itself, updating it where needed when it comes to using DBus more efficiently
  • drop the global accessibility bus, and have ATs negotiate a peer-to-peer connection to each application
  • make ATs ask the compositor to gather global state, like key shortcuts, instead of talking to applications that would then have to ask the windowing system—if that’s possible—or return invalid data when it isn’t
  • decouple GUI testing from accessibility
  • write widget and application authoring guides for application developers, and provide validation tools that can be used as part of the build and CI process to check if UI elements have the correct accessible description and links

There are more information available on the wiki for the notes and the roadmap, and we have already scheduled an additional check point meeting for this summer.

There’s a lot of work to be done, but we have now a much clearer idea of the scope and deliverables for such a redesign. If you want to help making things happen faster, feel free to join the effort; you can also make a donation to the GNOME Foundation.

The GTK team would like to thank the GNOME Foundation for the sponsorship for the venue and the attendees, and the fine folks at Hypra for joining the hackfest and explaining use cases and the current state of the accessibility stack, as well as helping out on the development side.

GTK 3.98

A few days ago, I’ve released a GTK 3.98 tarball. This is another step towards GTK 4. It is a little bit behind schedule, and does not quite include all the things we wanted to get into it, but it gets a lot closer to what we want to ship in GTK 4.

Almost 9 months have passed since the 3.96 snapshot, so there are quite a few new things to look at. Too many to cover them all, but here are some highlights:

Performance

The GL renderer has seen a steady flow of optimizations and performance improvements.

After the Westcoast hackfest last year, the GtkTextView scrolling performance has been greatly improved by making it cache render nodes for the visible range. At the same hackfest, the text caret blinking was changed to be smoothly animated, which is not relevant for performance at all, but looks cool.

Since the new year, a big focus has been on improving the performance of the CSS machinery. The CSS value implementation has been optimized to avoid computing values whenever possible. CSS lookups are using a Bloom filter now. And the IO for icon loading has been moved to a thread.

Most of the recent work was made possible by the sysprof profiling support that was added after the performance hackfest, and has recently been enhanced to report more information. To use it, simply start a GTK application with GTK_TRACE=1 in the environment, and load the resulting syscap file with sysprof.

DND

The DND refactoring has been completed. The GTK API for DND has been turned into event controllers: GtkDragSource and GtkDropTarget. Support for file transfers via file transfer portal has been added for both DND and the clipboard.  The underlying new infrastructure for data transfers has been covered in detail before.

GDK

The move of GDK towards Wayland concepts is continuing. This cleanup is not 100% complete yet.

Child surfaces have been removed. GDK only supports toplevel and popup surfaces now. The client-side window implementation has been removed too. Global positions and related APIs such as gdk_surface_move() are no longer available.

Grabs are no longer exposed as API. As a replacement, popup surfaces can be configured to hide on outside clicks.

XI2 is now mandatory when building the X11 backend, and support for the xim input method has been removed in favor of IBus.

The Wayland backend no longer relies on libwayland-cursor to load cursor themes, and loads individual cursors on demand.

GTK removals

Many classes have been made explicitly non-subclassable, and the widget hierarchy has been simplified, by making widgets derive directly from GtkWidget where possible.

GtkMenu, GtkMenuBar, GtkToolbar and related classes have been removed. They are being replaced by GMenu and popover-based variants. Popover menus can now do traditional, nested menus, and also show accelerators.

Context menus are no longer created with ::populate-popup signals, but also use menu models and actions. Creating those actions has been made easier with APIs like gtk_widget_class_install_action(), to create them in class_init.

GtkGestureMultiPress has been renamed to GtkGestureClick, to make it more obvious what this event controller is for.

GTK additions

We did not just remove things. Some new things have been added too.

The GtkNative interface has been introduced for widgets that have their own surface. This has been split off from the GtkRoot interface, which is exclusively for toplevel widgets without a parent.

A constraint-based layout manager has been added. It would be great to see people try this out. Please give us feedback if you do.

GtkTextView and other text widgets have gained a simple undo stack that can be used with Ctrl-Z.

The Emoji chooser widget has been made public.

Whats ahead

After 3.98, I’m planning to do more frequent snapshots, as the remaining outstanding items are landing. What are those items, you are asking ?

Here are the things that we still want to integrate before GTK 4:

– Event controllers for keyboard shortcuts
– Movable popovers
– Row-recycling list and grid views
– Revamped accessibility infrastructure
– Animation API