Since I’ve been asking people to try the recipes app with Flatpak, I can’t complain too much if I get bug reports back. But how does one create a useful bug report when something goes wrong in a Flatpak sandbox ? Some of the stacktraces I’ve seen have not been very useful, since they are lacking symbols.

This post is a quick attempt to spread some basics about Flatpak debugging.

Normally, you run your Flatpak app like this:

flatpak run org.gnome.Recipes

Well, that’s not quite true; the ”normal” way to launch the Flatpak is just the same as launching a non-Flatpak app: click on the icon, or hit the Super key, type recipes, hit Enter. But lets assume you’re launching flatpak from the commandline.

What happens behind the scenes here is that flatpak finds the metadata for org.gnome.Recipes, determines which runtime it needs, sets up the sandbox by mounting the app in /app and the runtime in /usr, does some more sandboxy stuff, and eventually launches the app.

First problem for bug reporting: we want to run the app under gdb to get a stacktrace when it crashes. Here is how you do that:

flatpak run --command=sh org.gnome.Recipes

Running this command, you’ll end up with a shell prompt ”inside” the recipes sandbox. This is great, because we can now launch our app under gdb (note that the application gets installed in the /app prefix):

$ gdb /app/bin/recipes

Except… this fails because there is no gdb. Remember that we are inside the sandbox, so we can only run what is either shipped with the app in /app/bin or with the runtime in /usr/bin. And gdb is not among either.

Thankfully, for each runtime, there is a corresponding sdk, which is just like the runtime, except it includes the stuff you need to develop and debug: headers, compilers, debuggers and other useful tools. And flatpak has a handy commandline option to use the sdk instead of the regular runtime:

flatpak run --devel --command=sh org.gnome.Recipes

The –devel option tells flatpak to use the sdk instead of the runtime and do some other things that make debugging in the sandbox work.

Now for the last trick: I was complaining about stacktraces without symbols at the beginning. In rpm-based distributions, the debug symbols are split off into debuginfo packages. Flatpak does something similar and splits all the debug information of runtimes and apps into separate ”runtime extensions”, which by convention have .Debug appended to their name. So the debug info for org.gnome.Recipes is in the org.gnome.Recipes.Debug extension.

When you use the –devel option, flatpak automatically includes the Debug extensions for the application and runtime, if they are available. So, for the most useful stacktraces, make sure that you have the Debug extensions for the apps and runtimes in question installed.

Since I’ve last written about recipes, we’ve started to figure out what we can achieve in time for GNOME 3.24, with an eye towards delivering a useful application. The result is this plan, which should be doable.

But: your help is needed. We need more recipe contributions from the GNOME community to have a well-populated initial experience. Everybody who contributes a recipe before 3.24 will get a little thank-you from us, so don’t delay…

The 0.8.0 release that I’ve just created already contains the first steps of this plan. One thing we decided is that we don’t have the time and resources to make the ingredients view useful by March, so the Ingredients tab is gone for now.

At the same time, there’s a new feature here, and that is the blue tile leading to the shopping list view:

The design for this page is still a bit up in the air, so you should expect this to change in the next releases. I decided to merge it already anyway, since I am impatient, and this view already provides useful functionality. You can print the shopping list:

Beyond this, I’ve spent some time on polishing and fixing bugs. One thing that I’ve discovered to my embarrassment earlier this week is that exporting recipes from the flatpak did not actually work. I had only ever tested this with an un-sandboxed local build.

Sorry to everyone who tried to export their recipe and was left wondering why it didn’t work!

We’ve now fixed all the bugs that were involved here, both in recipes and in the file chooser portal and in the portal infrastructure itself, and exporting recipes works fine with the current flatpak, which, as always, you can install from here:

One related issue that became apparent during this bug hunt is that things work less than perfectly if the portals are not present on the host system. Until that becomes less likely, I’ve added a bit of code to make the failure less mysterious, and give you some idea how to fix it:

I think recipes is proving its value as a test bed and early adopter for flatpak and portals. At this point, it is using the file chooser portal, the account information portal, the print portal, the notification portal, the session inhibit portal, and it would also use the sharing portal, if we had that already.

I shouldn’t close this post without mentioning that you will have a chance to hear a bit from Elvin about the genesis of this application in the Fosdem design devroom. See you there!

I said that I would post regular updates on what is happening in GTK+ 4 land. This was a while ago, so an update is overdue.

So, whats new ?

Cleanup

Deprecation cleanup has continued, and is mostly done at this point. We have the beginning of a porting guide that mentions some of the required changes for early adopters who want to stick their toes into the GTK+ 4 waters. Sadly, I haven’t gotten the GTK+ 4 docs up on the website yet, so no link…

Among the things that have been dropped as part of our ongoing cleanup has been the pixel cache, which should no longer be needed. This is nice since the pixel cache was causing problems, in particular on connection with transparency and component alpha (in font rendering).

Not really a cleanup, but we also got rid of the split into multiple shared objects (libgtk, libgdk, libgsk). Now, we just install a single libgtk, which also provides the gdk and gsk APIs. This has some small performance benefits, but mainly, it makes it easier for us to have private APIs that cross the gtk/gdk boundary.

Widget APIs

Some of the core APIs that are important when you are creating your own widgets have been changed around a bit:

The five different virtual functions that are used for size requisition have been replaced by a single new vfunc, measure(). This is using the same approach that we are already using for gadgets, where it has worked well.

The draw() virtual function that lets widget render themselves onto a cairo surface has been replaced by the new snapshot() vfunc, which lets widget create render nodes. This is essentially the change from direct to indirect rendering. Most widgets and gadgets have been ported over to this new wayof doing things.

These changes are only important to you if you create your own widgets.

Window APIs

GdkWindow has gained a few new constructors to replace the old libX11-style gdk_window_new. Their names should indicate what they are good for:

gdk_window_new_toplevel

gdk_window_new_popup

gdk_window_new_temp

gtk_window_new_child

gdk_window_new_input

gdk_wayland_window_new_subsurface

gdk_x11_window_foreign_new_for_display

The last two are worth mentioning as examples where we move backend-specific functionality to backend APIs.

In the medium term, we are moving towards a world with only toplevel windows. As a first step towards this, we no longer support native child windows, and gdk_window_reparent() is gone. This allowed us to considerably simply the GdkWindow code.

Renderers

When we initially merged GSK, it had a GL renderer and a software fallback (using cairo). Since then, Benjamin has created a Vulkan renderer. The renderer can be selected using the GSK_RENDERER environment variable.

So, for example, this is how to run gtk4-demo with the cairo renderer and the X11 backend:

GSK_RENDERER=cairo GDK_BACKEND=x11 gtk4-demo

After the GSK merge, we struggled a bit to come up with a working approach to converting all our widget and CSS rendering to render nodes. With the introduction of the snapshot() vfunc, we’ve been able to make progress on this front. As part of this effort, Benjamin changed the GSK API around a bit. There are now a bunch of special-purpose render node subclasses that let us effectively translate the CSS rendering, e.g.

gsk_linear_gradient_node_new

gsk_texture_node_new

gsk_color_node_new

gsk_border_node_new

gsk_transform_node_new

…and so on. More node types will be created as we discover the need for them.

New fun

As an example of new functionality that would be very hard to support adequately in GTK+ 3, Benjamin recently added gsk_color_matrix_node_new and used it to implement the CSS filter spec, which is good for a few screenshots:

I’m still not quite done with this project. And since it is vacation time, I had some time to spend on it, leading to a release with some improvements that I’d like to present briefly.

One thing I noticed missing right away when I started to transcribe one of my mothers recipes was a segmented ingredients list. What I mean by that is the typical cake recipe that will say “For the dough…” “For the frosting…”

So I had to add support for this before I could continue with the recipe. The result looks like this:

Another weak point that became apparent was editing the ingredients on the edit page. Initially, the ingredients list was just a plain text field. The previous release changed this to a list view, but the editing support consisted just of a popover with plain entries to add a new row.

This turned out to be hard to get right, and I had to go back to the designers (thanks, Jakub and Elvin) to get some ideas. I am reasonably happy with the end result. The popover now provides suggestions for both ingredients and units, while still allowing you to enter free-form text. And the same popover is now also available to edit existing ingredients:

Just in time for the Christmas release, I was reminded that we have a nice and simple solution for spell-checking in GTK+ applications now, with Sébastian Wilmet’s gspell library. So I quickly added spell-checking to the text fields in Recipes:

Lastly, not really a new feature or due to my efforts, but Recipes looks really good in dark as well.

Looking back at the goals that are listed on the design page for this application, we are almost there:

Find delicious food recipes to cook from all over the world

Assist people with dietary restrictions

Allow defining ingredient constraints

Print recipes so I can pin them on my fridge

Share recipes with my friends using e-mail

The one thing that is not covered yet is sharing recipes by email. For that, we need work on the Flatpak side, to create a sharing portal that lets applications send email.

And for the first goal we really need your support – if you have been thinking about writing up one of your favorite recipes, the holiday season is the perfect opportunity to cook it again, take some pictures of the result and contribute your recipe!

It has been a few weeks since I’ve first talked about this new app that I’ve started to work on, GNOME recipes.

Since then, a few things have changed. We have a new details page, which makes better use of the available space with a 2 column layout.

Among the improved details here is a more elaborate ingredients list. Also new is the image viewer, which lets you cycle through the available photos for the recipe without getting in the way too much.

Most importantly, as you can see in these screenshots, we have received some contributed recipes. Thanks to everybody who has sent us one! If you haven’t yet, please do. You may win a prize, if we can work out the logistics

GNOME needs a recipe app, since we all love to cook.This is not a new idea. Looking all the way back to 2007, the idea of a GNOME cook book already existed back then. For one reason or another, we never quite got there. But the idea has stuck around.

With the upcoming 20th birthday of GNOME next year, some of us thought that we should make another attempt at this application, maybe as a birthday gift to all of GNOME.

Shortly after GUADEC, I got my hands on some existing designs and started to toy around with implementing them over a few weekends and evenings. The screenshots in this post show how far I got since then.

Why did I start to write this app from scratch (instead of e.g. trying to give a face-lift to venerable gourmet) ?

Beyond the obvious reason that I love to code as much as I love to cook, I wanted to give GNOME Builder a more serious test by starting an application from scratch. And I find it very useful to take a look at GTK+ from the application developer side, every now and then. In both of these regards, the endeavor was already successful and has yielded improvements to both GNOME Builder and GTK+. For the cooking part, you can judge that for yourself.

The main reason for writing this post is that we are at a point now where we need contributions to make progress. The idea is that we will include a decent set of recipes from GNOME contributors all over the world with the application.

Therefore, we need your recipes, ideally with good photos.

All the photos and text you see in the screenshots here are just test data that I’ve used during development, and need to be replaced with actual content.

So, how can you contribute your favorite recipes ?

Add your recipe to the app, and when you are satisfied with how it looks, you can use the Export button on the details page to create an archive with the recipe and related information, such as images. The archive also includes information about the author of the recipe (ie yourself), so make sure to provide some information for that in the Preferences dialog.

We just created a bugzilla project for recipes, so you can just attach the archive to a bug:

Please make it clear in the bug that all the included images are your own and that we are allowed to ship it with the app.

Beyond recipes, there are plenty of other ways to contribute, of course. While I’ve tried hard to get many of the features in the initial design implemented, there is a lot more that can be done: for example, unit conversion, or a way to easily share recipes, or to print a shopping list.

Where do you get it ?

The project started out on github, but it is also available on git.gnome.org now. The design materials are collected on the GNOME wiki.

If you just want to try it out without building it yourself, you can just use Flatpak:

Of course, I did not get this far on my own. Thanks are due to several people. First and foremost, Emel Elvin Yıldız, for the designs and feedback on the implementation, Jakub Steiner for the icon and visuals, and Christian Hergert for keeping this idea alive and for making GNOME builder work great.

I was in this situation recently: An application icon would not show up in GNOME shell, even after I double- and triple-checked that I did all the right things:

Installed the desktop file with the right name in /usr/share/applications

Installed the icon with the right name in the hicolor icon theme

Make sure that Icon key in the desktop file has the right name

Restart GNOME shell (this is necessary due to a bug where GNOME shell will not reliably pick up desktop file changes)

Still, I just get the generic executable icon:

GNOME shell to the rescue

I asked GNOME shell maintainer Florian Müllner for help. He said: GNOME shell is probably picking up a stale desktop file from somewhere.

But from where ? I checked all the locations listed in XDG_DATA_DIRS to no avail. At this point, I was getting desperate, so I went back to Florian. He said: Just use looking glass to find out! If you don’t remember, looking glass is a pretty handy debugging console that is built right into GNOME shell. You open it by typing the command

lg

Into the Alt-F2 run dialog.

This brings up the looking glass. Here is how it helped me solve my problem:

I switched to the window tab, then clicked on the application in question, and hit the ‘Insert’ button. That binds the object to a variable named r(x) (for some number x) in the Javascript evaluator.

Going there, I then typed the command

r(3).app_info.get_filename()

And that showed the problematic desktop file:

I removed that file and restarted the shell once more, and now everything is working as it should:

The GTK+ 4 work is continuing at full speed, and today I want to show one of the first concrete benefits from the GSK merge: We can now record and replay frames. If you ever wondered why your animation does not look quite right, this might be just the tool for you.

To try this new tool, find the Recorder tab in the GTK+ inspector, and use the record button. As you can see, we capture and save the render node tree for each frame that the application draws, as long as recording is enabled (you want to be a bit careful, this is quickly eating up a lot of memory).

The leftmost pane lets you select one of the recorded frames. The middle pane shows the render node tree, and if you select a node there, the rendering on the right is updated to show only that subtree’s effect on the frame.

This is pretty nifty, and will hopefully be very useful in improving the GSK integration in GTK+, as well as helpful for debugging rendering problems in applications.

I haven’t written about GTK+ development in some time. But now there are some exciting things happening that are worth writing about.

Plans

Back in June, a good number of GTK+ developers came together for a hackfest in Toronto, It was a very productive gathering. One of the topics we discussed there was the (lack of) stability of GTK+ 3 and versioning. We caused a bit of a firestorm by blogging about this right away… so we went back to the drawing board and had another long discussion about the pros and cons of various versioning schemes at GUADEC.

GTK+ BOF in Karlsruhe

The final, agreed-on plan was published on the GTK+ blog, and you can read it there.

Actions

Fast-forward to today, and we’ve made good progress on putting this plan into place.

GTK+ has been branched for 3.22, and all future GTK+ 3 releases will come from this branch. This is very similar to GTK+ 2, where we have the forever-stable 2.24 branch. We plan to maintain the 3.22 branch for several years, so applications can rely on a stable GTK+ 3.

One activity that you can see in the branch currently is that we are deprecating APIs that will go away in GTK+ 4. Most deprecations have been in place for a while (some even from 3.0!), but some functions have just been forgotten. Marking them as deprecated now will make it easier to port to GTK+ 4 in the future. Keep in mind that deprecations are an optional service – you don’t have to rush to act on them unless you want to port to the next version.

To avoid unnecessary heartburn and build breakage, we’ve switched jhbuild, GNOME continuous and the flatpak runtimes over to using the 3.22 branch before opening the master branch for new development, and did the necessary work to make the two branches parallel-installable.

With all these preparations in place, Benjamin and Timm went to work and did a big round of deprecation cleanup. Altogether, this removed some 80.000 lines of code. Next, we’ve merged Emmanueles GSK work. And there is a lot more work queued up, from modernizing the GDK layer, to redoing input handling, to building with meson.

The current git version of GTK+ calls itself 3.89, and we’re aiming to do a 3.90 release in spring, ideally keeping the usual 6 months cadence.

…and you

We hope that at least some of the core GNOME applications will switch to using 3.90 by next spring, since we need testing and validation. But… currently things are a still a bit rough in master. The GSK port will need some more time to shake out rendering issues and make it as fast as it should be.

Therefore, we recommend that you stick with the 3.22 branch until we do a 3.89.1 release. By that time, the documentation should also have a 3 → 4 migration guide to help you with porting.

If you are eager to get ready for GTK+ 4 now, you can prepare your application by eliminating the deprecations that show up when you build against the latest 3.22 release.

Summary

This is an exciting time for GTK+ ! We will post regular updates as things are landing, but just following the weekly updates on the GTK+ blog should give you a good idea of what is going on.

gettext has seen quite some enhancements in recent years, after Daiki Ueno started maintaining it. It can now extract (and merge back) strings from diverse file formats, including many of the formats that are important for desktop applications. With gettext 0.19.8, there is really no need anymore to use intltool or GLib’s dated gettext glue (AM_GLIB_GNU_GETTEXT and glib-gettextize).

Since intltool still sticks around in quite a few projects, I thought that I should perhaps explain some of the dos and don’ts for how to get by with plain gettext. Javier Jardon has been tirelessly fighting a battle for using upstream gettext, maybe this will help him reaching the finish line with that project.

Extracting strings

xgettext is the tool used to extract strings from sources into .pot files.

In addition to programming languages such as C, C++, Java, Scheme, etc, it recognizes the following files by their typical file extensions (and it is smart enough to disregard a .in extension):

Desktop files: .desktop

GSettings schemas: .gschema.xml

GtkBuilder ui files: .ui

Appdata files: .appdata.xml and .metainfo.xml

You can just add these files to POTFILES.in, without the extra type hints that intltool requires.

One important advantage of xgettext’s xml support, compared to intltool, is that you can install .in files that are valid; no more tag mutilation like <_description> required.

Merging translations

The trickier part is merging translations back into the various file formats. Sometimes that is not necessary, since the file has a reference to the gettext domain, and consumers know to use gettext at runtime: that is the case for GSettings schemas and GtkBuilder ui files, for example.

But in other cases, the translations need to be merged back into the original file before installing it. In these cases, the original file from which the strings are extracted often has an extra .in extension. The tool that is doing this task is msgfmt.

Intltool installs autotools glue which can define make rules for many of these cases, such as @INTLTOOL_DESKTOP_RULE@. Gettext does not provide this kind of glue, but the msgfmt tool is versatile enough that you can write your own rules fairly easily, for example:

Extending gettext

Gettext can be extended to understand new xml formats. To do so, you install .its and .loc files. The syntax for these files is explained in detail in the gettext docs. Libraries are expected to install these files for ‘their’ formats (GLib and GTK+ already do, and PolicyKit will do the same soon.

If you don’t want to wait for your favorite format to come with built-in its support, you can also include its files with your application; gettext will look for such files in $XDG_DATA_DIRS/gettext/its/.