A new default theme for GTK+

This has been a long time coming. We’ve wanted to replace the default GTK+ theme for a very long time.

-#define DEFAULT_THEME_NAME "Raleigh"
+#define DEFAULT_THEME_NAME "Adwaita"

The Raleigh theme that we’ve used as the default until now has some advantages:

  • It is very simple
  • No dependency on a theme engine (external or internal)
  • It does not use a lot of resources

But there is no nice way of putting it: it is very ugly.

Raleigh

This may not  be such a big deal on Linux, where distributions generally have ‘their’ theme, not to mention the many packaged and readily available themes.  So, basically no Linux user ever sees the default GTK+ theme. The situation is very different on other platforms, where GTK+ is often bundled with applications, and it may not be easy to install themes, or get the bundled GTK+ to use them.

For a very long time, we’ve held onto the belief that the theming system is a way to make applications blend smoothly into the platform, and that there should be a native theme for each major platform that GTK+ can run on.

This is a great idea in theory. In practice, it has not worked out so well.  The one platform where we have a native theme is Windows, and even though the ms-windows theme has received much appreciated attention and updates by Руслан Ижбулатов  this cycle, it is still incomplete and has problems with some recent GTK+ features.

(No need to panic though. Even if it is no longer the default, the ms-windows theme will still be available.)

Adwaita on the other hand,  is a very complete theme that has received a lot of attention over the last three years. Not only does it support all recent GTK+ features, many of the CSS improvements that the GTK+ theming machinery has received in the last years were direct responses to the needs of the Adwaita designers.

Adwaita
With Adwaita, GTK+ applications can rely on having a 100% complete theme that will look and feel the same on all supported platforms.  A theme that is constantly receiving a lot of love and attention and keeps up with new GTK+ features.

Another big plus: Adwaita has a high-quality dark variant, which will now also be available everywhere.

Adwaita dark

So, why not do this switch earlier ? After all, Adwaita has been around for a while.

The main reason is that we did not want to lose the ‘no theme engine’ characteristic of the default theme.  Theme engines, and loadable modules in general, are something we’ve been moving away from for a while now. They are

  •  questionable from a security perspective (executable code thats shipped separately, inserted into all your applications)
  • associated with search path problems
  • require stable APIs for many things that are more or less internal

(No reason to panic, though. Theme engines will not stop working overnight in GTK+ 3.)

The alternative to engines that we want themes to use is CSS. Our CSS implementation has only recently become powerful enough to replace the last features from the Adwaita theme engine  (focus rectangles and menu shadows). That is why we are doing the switch now.

One of consequences of moving Adwaita into GTK+ is that we will no longer ship application-specific theming as part of the theme (many core GNOME applications currently have small amounts of CSS glue inside gnome-themes-standard). Where this is still relevant, applications should just install it themselves. Here is an example for how to do this.

Thanks for the huge amount of recent work on Adwaita go to Jakub Steiner, Lapo Calamandrei, Jon McCann and Cosimo Cecchi.

A GtkInspector update

I’ve first introduced GtkInspector a few weeks ago. Since then, it has made it into the GTK+ 3.13.2 development release and is
now available in Fedora rawhide, which should hopefully make debugging of GTK+ applications in Fedora easier.

I’ve continued to work on the inspector, and it is time to give an update on what it can do now. So far, my focus has been mostly on covering more of GTK+’s features at a basic level, and so much on adding sophisticated debugging support. That will probably change over time.

In unsorted order, here are some of the recent additions:
Inspector warning
We show a warning dialog now when the inspector window is opened with a keyboard shortcut. This is meant as a safety net for users who may end up here by accident when they mistype an application shortcut. We don’t want them to get scared by the inspector, so we offer them a quick way out.

The warning dialog can be turned off permanently with a setting, so frequent users of the inspector can avoid it.

When using the mouse to pick a widget, we now lower the inspector window, so it doesn’t get in the way.

ResourcesThis tab shows all the embedded resources in the application (as well as in used libraries). This is perhaps not such a great debugging feature, but still useful information. We show the type and size of the resources, and display e.g. images as such.

Property Editing: FontsEditing of properties has been changed from a cell renderer to popovers. Popovers let us use much more room so that we can e.g. embed a font chooser to edit font properties.

Property Editing: AttributeSome other properties have gotten their own editors. Here, we are editing a cell renderer property that is mapped to a tree model column. The editor allows to change the attribute mapping, and the Properties button lets us jump to the tree model in question, where it will open the Data tab:

Tree Model
It can be useful to see the data in the tree model, to verify that we have used the right column in the attribute mapping.

Property Editing: ActionsAnother custom property editor has been added for action names. The Properties button lets us jump to the Actions tab of the widget where the action is defined:

ActionsActions can be activated from here. For stateful actions, we also allow to set their state:

Action EditingOne feature I am proud of is that when gesture support was merged in GTK+ a few weeks ago, the branch already came with GtkInspector support for gestures.

GesturesI hope that this can become a model for the future, and we can make ‘GtkInspector support’ an expected deliverable for every new GTK+ feature, just like accessibility or internationalization are now.

Last, not least, the inspector is very useful in sorting out theme questions – the GNOME designers have used it quite a bit while doing a major refactoring of the Adwaita theme that will land soon.

Of course, one can also use it for more silly things, like figuring out how to do translucent headers:

Translucent titlebars

I’m very interested in hearing both success stories of GtkInspector helping to solve problems and gaps where GtkInspector is lacking functionality.

Introducing GtkInspector

If you need to solve a tricky GTK+ problem in your application, gtkparasite is a very useful tool to have around. It lets you explore the widget hierarchy, change properties, tweak theme settings, and so on.

Unfortunately, gtkparasite is a tool for people ‘in the know’ – it is not part of GTK+, not advertised on our website, and not available out of the box on your average GTK+ installation.

At the Developer Experience hackfest in Berlin a few weeks ago, the assembled GTK+ developers discussed fixing this situation by making an interactive debugger like gtkparasite part of GTK+ itself. This way, it will be available whenever you run a GTK+ application, and we can develop and improve the debugging tools alongside the toolkit.

So, I’ve spent some of my spare time on this since the hackfest. The results are now in GTK+ master.  I’ve started from the gtkparasite code, but things have changed quite a bit, and some new things have appeared.

GtkInspectorIf you want to give it a try yourself, you can just use the Control-Shift-I or Control-Shift-D shortcuts to open an inspector window in any application that is using GTK+ master, or you can just set the GTK_DEBUG=interactive environment variable. Note that the keybinding will only work if GTK+ can find the org.gtk.Debug settings schema, so you probably want to run the application under jhbuild.

Here is a video of GtkInspector in action.

Among the things you can see in the video are interactive picking of widgets for inspection, visual debugging of graphic updates and baseline alignment, changing of widget properties, theme tweaks and general version and environment information.

I’ve also put together a page with ideas for future improvements to this debugging tool. If you are looking for a fun project to work on, this might just be it!

Thanks to Christian Hammond for creating gtkparasite and maintaining (over many years) such a useful debugging tool.  The GTK+ inspector would not exist without it.

Tweaking a the GTK+ theme, using CSS

I got asked today:

How do I make the sidebar in evolution as narrow as the one in thunderbird, so I can see all my mail folders ? Doesn’t GTK+’s awesome CSS theming make that sort of thing very easy ?

Well, I was hopeful that it would, but I figured that I better try before saying yes. Here is what I came up with:

First, create a local directory to hold our theme modification:

mkdir ~/.local/share/themes/Adwaita/gtk-3.0

Next, copy the gtk.css file from the system theme:

cp /usr/share/themes/Adwaita/gtk-3.0/gtk.css ~/.local/share/themes/Adwaita/gtk-3.0

Well, that didn’t go as expected:

Oops

What went wrong ? It turns out that the Adwaita css file is pretty minimal:

@import url("resource:///org/gnome/adwaita/gtk-main.css");

All the secret sauce is wrapped up in a resource bundle in the same directory. GTK+ automatically looks for such a bundle in the same directory as the css file when loading themes. With this knowledge, making my local copy of Adwaita work is a simple as linking the resources into the right place:

ln -s /usr/share/themes/Adwaita/gtk-3.0/gtk.gresource ~/.local/share/themes/Adwaita/gtk-3.0

The last step is to add a little bit of css to gtk.css:

EMailSidebar.view {
  font-size: 5px;
}

@import url("resource:///org/gnome/adwaita/gtk-main.css");

And we reach the desired end result:

Small print

I know what you are going to ask:

How did I come up with the selector EMailSidebar.view that matches the evolution sidebar ?

The answer is, I used gtkparasite, which is a pretty useful debugging tool for this sort of problem.

A parasite

And because it is so useful, we are planning to include something very similar to it in GTK+ itself soon. You can follow this bug to track the progress.

Westcoast summit, day three

This being last day of the hackfest, people started to disappear in the afternoon. Before that, we had a planning session for Wayland in GNOME 3.14, and came up with a number of concrete tasks and goals. We decided to use bugzilla to track the tasks, so I’ve updated the existing tracker bug.  One of our goals for this cycle is to make Wayland sessions day-to-day usable and keep them that way. Therefore, we want to get Wayland testing into gnome-continuous and aim for having Wayland sessions working well in Fedora rawhide by the end of this month.

Westcoast Summit, day two

San Francisco
The second day of the hackfest in San Francisco was punctuated by hour-long presentation of the Endless Mobile team about their mission and product. Part of the presentation was done by video stream from Rio.

Around this highlight, the usual small group discussions and hacking continued all day.

I got a demonstration of california from its author. CaliforniaIt is still young, but looks very nice already. ‘Just enough calendar’, was my impression. Since it uses eds underneath, all my stuff shows up right away.

I also had a good exchange with Daniel from elementary about their widget and theming needs.

One of the bigger discussions in the afternoon was about application  development, how to make it easier and remove obstacles. To kick it off, Christian demonstrated his IDE prototype, which looks really nice. The discussion circulated around the expected topics: better documentation, better tools, distribution and revenue, etc. I don’t think there were any grand conclusions, but as far as GTK+ is concerned, I think we should do a few things:

  • Add more topic- or recipe-based documentation. I’ve made a start on this with my Building Applications talk. Some of the examples that were mentioned include: A preference dialog from scratch, Side-bar best practices.
  • Get serious about considering glade part of the (wider) GTK+ project. The challenge for 3.14: Have all widgets supported in glade at the day of the release.
  • Adopt gtkparasite. We’ve let gtkparasite languish in random forks on github for too long. This is really useful technology, and should be fully integrated into glade and other ides.

Throughout the day, I fixed several GTK+ bugs that were pointed out by Daniel and Jim. I also continued to port applications to  DBus-activatable.

Westcoast Summit, day one

The first day of the Westcoast summit is now over. We enjoyed the excellent hospitality of the Endless Mobile crew.

Before coming here, I set up a GNOME goal for converting applications to DBus activation, and with the help of Cosimo, I converted a few applications. This will make applications fit nicely into the coming session setup with systemd –user and kdbus.

One of the longer discussions we had today was around this topic. Lennart explained how things might work: The systemd user instance creates the user bus when a user logs in, and every application that is started via DBus activation is actually spawned by the systemd user instance, and thus gets its own cgroup, and D-Bus policy, which will be used to limit the access that sandboxed applications have on the bus.

Kay demonstrated systemd –user and kdbus launching a full GNOME session on his laptop. Most things just work already. Only a few things will need fixes:

  •  PolicyKit currently uses the session of the caller in determining which authentication agent to talk to, etc.  Applications that are activated on the user bus are not technically part of a session (as in: a descendent of the gnome-session process), so this won’t work anymore.
  • gdm keeps a process around for the lifetime of the session that provides the pam stack used e.g. when unlocking the session, and without a clear session association, this may not work in the same way anymore.

We can work on these issues while we are waiting for kdbus to find its way in the kernel.

After discussing this, and many other topics, we ended the day in a fantastic Chinese restaurant, followed by beer.

Keeping gnome-shell approachable

One aspect that I always found very appealing about gnome-shell is that you could just go in /usr/share/gnome-shell/js, make a few changes, hit Alt-F2 r and try them out. This was a very low barrier to entry – no development environment needed, no days of jhbuilding dependencies. This is at least part of the explanation why shell extensions exist in large numbers. Sure, you still have to make yourself familiar with the internal and external APIs that are used in gnome-shell, and if you are unlucky, then Alt-F2 r will show you not your cool hack, but the fail whale.

I was a bit sad to see that we’ve lost a bit of this newcomer friendliness in 3.12, when all the JavaScript and css files were wrapped up in resources and included in the gnome-shell binary (to be exact, they are located in /usr/lib64/gnome-shell/libgnome-shell.so, not in /usr/bin/gnome-shell itself). Why was this done ? I guess having everything in one file and not spread across the file system makes gnome-shell start up a tiny bit faster (although I’m not sure if anybody has measured this).

But how do I now try gnome-shell changes quickly ? Let see…

For some background, gnome-shell is using the GResource mechanism for embedding the js files in the binary. Under the covers, this puts the files in a separate ELF section and makes their content available in a filesystem-like structure. The application itself can get at the resources e.g.  by constructing GFiles from resource:// URIs, like this:

file = g_file_new_for_uri ("resource:///org/gnome/software/gtk-style.css");

To access the embedded resources from the outside, you can use the gresource utility that is shipped with GLib. It can list the resources and also extract their content. Sadly, there is currently no easy way to replace existing resources with newer versions, since that requires recreating the ELF section and relinking the application.

gnome-shell has quite a few resources; the list looks like this:

gresource list /usr/lib64/gnome-shell/libgnome-shell.so
/org/gnome/shell/extensionPrefs/main.js
/org/gnome/shell/gdm/authPrompt.js
/org/gnome/shell/gdm/batch.js
/org/gnome/shell/gdm/fingerprint.js
/org/gnome/shell/gdm/loginDialog.js
/org/gnome/shell/gdm/oVirt.js
/org/gnome/shell/gdm/realmd.js
/org/gnome/shell/gdm/util.js
...

Here is how I used the gresource tool to get back to gnome-shell tweakability. Since the gresource commandline is not very versatile, I wrote this little script:

#! /bin/sh

gs=/usr/lib64/gnome-shell/libgnome-shell.so

cd $HOME/gnome-shell-js

mkdir -p ui/components ui/status misc perf extensionPrefs gdm

for r in `gresource list $gs`; do
  gresource extract $gs $r > ${r/#\/org\/gnome\/shell/.}
done

After running this script, all the js files that make up the gnome-shell UI can be found in $HOME/gnome-shell. Now I can point gnome-shell at these files with the (undocumented) GNOME_SHELL_JS variable:

GNOME_SHELL_JS=$HOME/gnome-shell-js gnome-shell

And – voila! – gnome-shell is as hackable as it always was.

Dialogs in GTK+ 3.12

Dialogs are getting a face-lift in GTK+ 3.12.

Most of the work on this was done by Jon McCann, I’ve only helped out here and there. The main visible change is the switch to client-side decorations and headerbars.

Here are some examples of GTK+’s built-in complex dialogs with their new look:

File Chooser

Color Chooser

The application chooser has had a bit more work done – we have a search button in the header bar, which makes a search bar appear when clicked.

Application Chooser

The most common dialogs in applications are preference dialogs. gedit shows how these can look with client-side decorations.

Preferences

And then there are simple prompts.  GTK+ has the GtkMessageDialog class for these.  Their new look is maybe the boldest part of this refresh.

Prompt

Of course, GTK+ is used in many places, and client-side decorations may look foreign in some of them. Together with these changes, we introduced a dialogs-use-header setting. Built-in dialogs will fall back to a more traditional appearance if it is not set:

Traditional File Chooser

Traditional Color Chooser

Note that some of the details in my screenshots, such as the blue color for suggested actions, depend on the theme. What you see here is how dialogs will appear with the Adwaita theme in GNOME 3.12.

The GNOME HIG contains a lot of helpful advice on how to make best use of dialogs in your application.

New in GTK+ 3.12: popovers

In the third part of my recap of the GNOME 3.12 development cycle, I’ll talk about some of the changes in GTK+ that I have been involved in.

Popovers have already been discussed quite a bit. Most of the popover implementation has been done by Carlos Garnacho, generalizing his earlier work on touch selection popups that has been in GTK+ since 3.8.

One of the nice things about popovers is that they are just normal containers – you can put any widget into them, and keyboard navigation and input works like everywhere else. This is a marked contrast to menus, which are very specialized. Attempts to put entries, sliders or buttons into menus usually end badly.

I recently acquired a laptop with a touchscreen, so I can say with confidence that popovers are also much easier to use with touch than menus.

Here are some examples of popovers in gedit:

PopoverPopover

My own contribution to popovers has been to convert GtkVolumeButton to use a popover:

Popover

I also made it possible to populate popovers from a GMenuModel, giving you instant popover menus:

Popover

Popovers are still very new, so their adoption in GNOME 3.12 will be somewhat limited. But we are in the lucky position that we already have quite good design guidance for popovers, so this will probably change soon.