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).

radiobutton1
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.

Radiobutton
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).

Radiobutton
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.

Radiobutton
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.

Radiobutton
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.

Radiobutton
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:

Boxes
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:

Nodes
…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_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 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.

Breakfast

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.

Topics

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.

GNOME Boston Summit 2015

The Boston Summit is a 3-day hackfest for GNOME developers and contributors, that we traditionally hold over the Columbus day weekend.

In recent years, we’ve sometimes met in Montreal,  but we are back in Boston, at the MIT again, this year.

Early Turning

Details

When: Saturday, October 10 — Monday, October 12
Where: MIT building E51, Cambridge, MA

Topics

There’s plenty of topics we can discuss. Here are some I would be interested in working on:

  • gnome-builder and xdg-app
  • Application development (bundling, SDKs, sandboxing, portals…)
  • A visual refresh for GNOME

If you are interested, please let us know you’re coming.

Hope to see many old and new faces there !

Guadec update

Here is a quick  tour of what you missed if you did not make it to my Guadec talk this year.

It was a bit different from my usual ‘state of the union’ or ‘GTK+ roadmap’ presentations. Instead, I showed a selection of tips and tricks, things you perhaps didn’t know yet how to do with GTK+.

Scrollbar steppers still exist

Guadec 1

Context menus on scrollbars

Guadec 2

Adding items to context menus and popovers
Guadec 3
Decorative overlays

Guadec 4

Custom spin buttonsGuadec 5
Discrete scales

Guadec 6

Markup in text views

Guadec 7

Filter models with extra columns

Guadec 9

The slides are here, and if you want to study the examples in more detail, they are all available in gtk3-demo in GTK+ master.

Some GTK+ sightings

I had a chance to demonstrate some GTK+ file chooser changes that have accumulated in the last year, so I thought I should share some of this material here.

File Chooser 1
All the screenshots here are of the testfilechooser application in GTK+ master as of today (some bugs were found and fixed in the process).

Search

Search in the filechooser area that I have spent a bit of time on myself this cycle. We’ve improved the internals of the search implementation to match the sophistication of nautilus:

  • The current folder is already loaded, so we search through that data without any extra IO.
  • We ask tracker (or the platforms native indexer) for search results.
  • Locations that are not covered by that, we crawl ourselves, skipping remote locations to avoid excessive network traffic.

File Chooser 2
The easiest way to start a search is to just type a few characters – the search entry will appear and the search begin (you can of course also use the Search button in the header, or hit Ctrl-F to reveal the search bar.
File Chooser 6
If you type a character that looks like the beginning of a path (~, / or .), we bring up the location entry instead to let you enter a location.

Note that we show helpful hints in the subtitle in the header: if you are searching, we tell you where. If you are expected to enter a URL, we tell you that.
File Chooser 3For search results, we show a location column that helps to determine quickly where a result comes from – results are sorted so that results from the current folder come first.  Recent files also have a location column. The formatting of the modification time column has been improved, and it can optionally show times in addition to dates.

As you can also see here, the context menu in the file list (as well as the one in the sidebar) has been changed to a popover. The main motivation for this is that we can now trigger it with a long press on touch screens, which does not work well with a menu.

File Chooser 4If the search takes longer than a few moments, we show a spinner.  Hitting Escape will stop the search. Hitting it again will hide the search entry. Hitting it one more time will close the dialog.

File Chooser 5If the search comes up empty, we tell you about it.

File Chooser 7As I already mentioned, we don’t crawl remote locations (and tracker doesn’t index them either). But we still get results for the current folder. The footer below the list informs you about this fact.

Sidebar

The GtkPlacesSidebar is shared between nautilus and the file chooser since a few years ago. This cycle, it has been rewritten to use a GtkListBox instead of a GtkTreeView. This has a number of advantages: we can use real widgets for the rows, and things like the eject button are properly themeable and accessible.

File Chooser 8Another aspect that was improved in the sidebar is the drag-and-drop of files to create bookmarks. We now show a clear drop location and gray out all the rest.  Some of these changes are a direct result of user testing on nautilus that happened last year.

Places

The sidebar used to list all your removable devices, remote mounts, as well as special items for ‘Enter Location’, etc. To prevent the list from getting too long, we have moved most of these to a new view, and just have a single “Other Locations” item in the sidebar to go there.
File Chooser 9As you can see, the places view also has enough room to offer ‘Connect to Server’ functionality.

File Chooser 10It has completion for known server locations.

File Chooser 11We show progress while connecting to a server.

File Chooser 12And after the connection succeeded, the location shows up under ‘Networks’ in the list, from where it can be unmounted again.

File Chooser 13The recent server locations are also available in a popover.

File Chooser 14If you don’t have any, we tell you so.

Save mode

All of the improvements so far apply to both Open mode and Save mode.

File Chooser 15The name entry in Save mode has been moved to the header (if we have one).

File Chooser 16For creating directories, we now use a popover instead of an embedded entry in the list.

File Chooser 18This lets us handle invalid names in a nicer way.

Credits

All of these changes will appear in GTK+ 3.18 in September. And we are not quite done yet – we may still get a modernized path bar this cycle, if everything works out.

The improvements that I have presented here are not all my work.  A lot of credit goes to Allan Day, Carlos Soriano, Georges Basile Stavracas Neto, and Arc Riley. Buy them a drink if you meet them!

Westcoast summit 2015

I am in San Francisco this week, for the second Westcoast Summit – this event was born last year, as a counterweight to the traditional GNOME summits that are happening every fall on the other coast.

Sunday was a really awesome day to arrive in San Francisco, my hotel is right around Market St, where this was going on:

Gay pride parade

Maybe this inspired my choice of texture when I  wrote this quick demo in the evening:

Pango power

Like last year, we are being hosted by the awesome people at Endless Mobile . And like last year, we are lucky to have the elementary team join us to work together and have a good time.

We started the day with a topic collection session:

Topic collectionSince everyone was interested in sandboxing and xdg-app, we started with Alex giving an overview of the current status and ideas around xdg-app. Endless has done an experimental build of their own runtime, and (almost) got it working in a day. After the general sandboxing discussion had run its course, Alex and I decided to patch evince to use the document portal.

GTK topicsIn the afternoon, we did a session on GTK+ topics, which produced a number of quick patches for issues that the elementary team has in their use of GTK+.

Later on, KentonVarda and Andy Lutomirsky of sandstorm.io came by for a very useful exchange about our approaches to sandboxing.

kdbus vs cap'n protoI have put some notes of todays discussions here.

GNOME 3.16 sightings

As is my habit, I’ve taken some screenshots of new things that showed up in my smoketesting of the GNOME 3.15.90 release.Since we are entering feature freeze with the .90 release,  these pictures give some impression of whats in store for GNOME 3.16.

The GNOME shell theme has seen the first major refresh in a while. As part of this refresh, the theme has been rewritten in sass, and is now sharing much more code with the Adwaita GTK+ theme. Window decorations are now also sharing code between client-side and server-side.

New Shell ThemeA long-anticipated redesign of notifications has landed just-in-time for 3.15.90. This is a major change in the user interaction. Notifications are now appearing at the top of the screen. The message tray is gone, old notifications can now be found in the calendar popup.

New notificationsNew NotificationsSystem integration has been improved, e.g in the area of privacy. We now have  a privacy page in gnome-initial-setup, which offers you to opt out of geolocation and automatic bug reporting:

Privacy Outside of the initial setup, the same settings are also available in the control-center privacy panel.

The nautilus UI has received a lot of love. The ‘gear’ menu has been replaced by a popover, the list appearance is improved,
and file deletion can now be undone from a notification.

Improved NautilusNautilus ImprovementsOther applications have received a fresh look as well, for example evince and eog:

EvinceEye of GNOMEThere will also be a number of new applications, here are a few:

New applicationsYou can try GNOME 3.15.90, for example in Fedora 22 today. Or you can wait for GNOME 3.16, which will arrive on March 25.

Sandboxed applications for GNOME

It is no secret that we’ve been interested in sandboxed applications for a while. It is evident here, here, here or here, to name just a few.

What may not be widely known yet is that we have been working on putting together a working implementation of these ideas. Alexander Larsson has made steady progress, and we’re now almost at the point where it is useful for  other people to start playing with it.

If you want to go straight to the playing part, you can head to this wiki page, which has all the links and explanations you need.


Some rights reserved by whiteoakart

Why sandboxed apps ?

There are several reasons:

  • We want to make it possible for 3rd parties to create and distribute applications that work on multiple distributions.
  • We want to run the applications with as little access as possible to the host (for example user files or network access), so that users can try applications without necessarily having to trust them fully.
  • We want to make it much easier to write applications – jhbuild has its uses, but it is an endless source of frustration and a very high hurdle for new contributors.

Traditionally, the only answer available to people who need to distribute an executable that works across several Linux distributions is to statically link all but the lowest-level dependencies.

That is not only wasteful in terms of bandwidth for downloading, but also at runtime, when every application loads its own copy of those dependencies, instead of sharing them.

And the real problem comes when one of those dependencies needs to be updated, e.g. because of a security issue (some people still remember the infamous zlib double-free incident). Dealing with this in a fairly efficient way is a strong point of the Linux packaging model, as its proponents are quick to point out.

So,  are sandboxed apps any better ? By themselves, they aren’t.

Runtimes and bundles

We suggest to introduce the concept of a runtime to help with this. A runtime provides a well-defined environment that an app can run in – one way to think of it is as a /usr filesystem with fixed contents.
Typical examples would be “GNOME 3.14” or “KDE 5.6”.

It is important to note: you can have multiple runtimes installed on the system, and even multiple versions of the same runtime. Things that are not included in the runtime will still have to be bundled with the application – but the problem becomes much more manageable.

What about the applications themselves ? In the filesystem, an app bundle is simply a directory which contains a metadata file that describes the application, what runtime it needs, and various other things. The actual contents of the app bundle are in a subdirectory. The last component of an app bundle is another subdirectory, containing the various files that are needed by the host system and the session to present the app to the user: desktop files, icons, etc.

The only way to run such a bundled application is through a helper, which sets up the  sandbox. It uses kernel namespaces and bind mounts to isolate the application from the host system and its filesystem. The app bundle contents get mounted under /self, and the runtime gets mounted under /usr.

But what about the developer experience ? The runtime idea has a counterpart that helps with this, the developer runtime, or sdk. It is basically, the runtime with the ‘devel’ parts added, including tools like a compiler and a debugger.  And similar to the ‘xdg-app run’ command that sets up a sandbox to run an application in, there is an ‘xdg-app build’ command that sets up a ‘developer sandbox’ with the sdk.

Is this progress ?

One question I expect is: What about freedom ? This sounds just like corporate walled gardens and app stores. I think this is a fair question – we are trying to replicate some of the strong points of the app store model. The existing examples of this model have a strong flavor of control, and focus entirely on consumption as opposed to creation.

But I think we can actually turn this into a freedom-enhancing change, if we pay attention while building it.

One vision I have is that we could have a “Modify this application” context menu item in gnome-shell which downloads the sources of the app bundle, sets up the right sdk, opens the sources in your favourite IDE, where you can make your modifications, build it, test it and create a new bundle that you can share with your friends.

In particular the last part (wrapping your modifications in an easy-to-share form) is really not easy in the traditional distribution world, where everything has to be a package that comes from your distributor.

This might be a great fit for gnome-builder, which will hopefully gain support for building bundled applications. Coincidentally, the gnome-builder project is just entering the last week of its fundraising campaign – if you haven’t donated yet, you have 7 days left to do so.

Our implementation

Some notable facts about the implementation that Alex’ has been working on:

  • Both runtimes and app bundles can be installed per-user and system-wide, and they can coexist perfectly fine with traditional applications. There’s no need for everybody to adopt this model at once, we can transition gradually to it.
  • We use OSTree to distribute both runtimes and applications as well as updates. OSTree is a good fit for this, because its use of content-based addressing and hardlinks transparently makes runtimes and bundles share disk space, and at the same time it doesn’t impose strong requirements on the host system.  But OSTree does not have to be the only distribution mechanism – the definition of the filesystem layout for applications and the sandboxing setup is has no dependencies on it.
  • The build tooling supports using rpmbuild and rpms to build runtimes and application. With this, what we do becomes very similar to the rpm-ostree project: They use rpms to populate OS images on the server side, we use rpms to put together runtimes and applications. In both cases, the results get distributed to end users via OSTree.
  • We have a repository with a few example applications and a yocto-based runtime for GNOME 3.15.
Whats next ?

There are lots of smaller (and some bigger things left to do).

Currently, we are working on making gnome-software show and handle these application bundles in addition to  traditional packaged applications.

Our short-term goal is to provide an initial test version of a ‘reference runtime’ for the GNOME 3.16 release.

If you want to learn more, you can study the SandboxedApps wiki page that I’ve already mentioned, or you can come to DevConf.cz, where Alex will be presenting his work.

GNOME Wayland porting – the endgame

Mosaic by Alison's Eyes.

Its been a while since I mentioned Wayland in this space – of course that doesn’t mean that work on GNOME Wayland support has stopped.

Quite the opposite, in fact. The GNOME 3.15.4 release that is due this week will close a number of the remaining gaps:

  • libinput 0.8 has been released, with most of the APIs that we need
  • Handling of input configuration has largely moved to mutter (the picture is not quite as clean as it could be, because we still need support for X configurations that do not use libinput in gnome-settings-daemon)
  • The corresponding control-center changes are about to land too
  • gnome-shell supports pointer barriers for the hot corner under Wayland as well
  • GTK+ popovers are using subsurfaces now, so they can extend beyond window boundaries
  • GTK+ prefers the Wayland backend over the X backend, if both are available

One gap that has not been closed yet is support for Wacom tablets. The required libinput changes and Wayland protocol extensions did not quite make it into libinput 0.8 – but much of the work has been done and will hopefully land before long.

The hero’s of this latest round of Wayland progress are Carlos Garnacho, Rui Matos, Jonas Ådahl, Jasper St. Pierre, Peter Hutterer and Hans de Goede, to name just a few.

I can hear you ask the question:

Thats all great, but when is it going to be done ?!

Clearly, we want to reach an endpoint where we can declare the Wayland port done and use it by default, in Fedora.  So, in order to not drag this out forever, we are aiming for the following:

  •  Use Wayland for the login screen in Fedora 22

Why ? The login screen is pretty self-contained and we don’t have to worry about application compatibility or support for exotic devices. And we will get Wayland to run on (almost) all systems this way, which should give a lot more exposure and help shake out lingering bugs and hardware issues.

  • Use the Wayland backends of the various toolkits (mainly GTK+, but also SDL and maybe Qt), if we are in a Wayland session.

Why ? This ensures that we get the maximum amount of exposure from the brave souls who are trying the Wayland session today, while not affecting the experience of everybody else who prefers the traditional X session.

As mentioned above, this change is happening for GTK+ in 3.15.4.

  • Make the Wayland session the default in rawhide, soon after we’ve branched for F22.

Why ?  If we want to have a shot at switching the default for Fedora 23, we need to do this anyway. And doing it sooner rather than later is the only logical choice.

+ +