GNOME+Rust Hackfest #5 in Berlin

Last week was the fifth edition of the GNOME+Rust hackfest. What about talking a bit about what happened there?

What have we done?

The goals of this edition were:

Provide a gir tutorial so that people could generate their own GObject-based library.

Generate builder for widgets (@antoyo wrote a blog post about it available here).

Improve cairo crate API.

Upgrade all gtk-rs crates to the 2018 edition.

Discuss next gtk-rs release.

We also fixed some newly discovered gir issues and made some adds on the gstreamer-rs crate.

gir tutorial

It has been asked a certain amount of time so I decided that I'd take this hackfest opportunity to finally write it down. This is a nice introduction on how to generate your own GObject-based crate from the .gir files. I covered the basics and a bit more, however, I didn't cover errors much. Maybe for a next tutorial? I'll first wait to get some feedbacks to check what people got struggles with.

Builder for widgets?

I prefer to let you read @antoyo's nice blog post about it. But in short: some relm improvements are coming in soon!

Improve cairo crate API

The cairo crate is a bit "special" in the gtk-rs environment: it's the only not automatically generated. Because of this, it stands out a bit on a few points, the API notably. We started talking about it, if you want to join the discussions:

Please feel free to do so!

Upgrade to the 2018 edition

We're a bit lacking behind on this part: gtk-rs crates are still using the 2015 syntax. We intend to update all of our crates soon and we actually already started by updating gir to the 2018 syntax (we had to start somewhere after all!). The pull request is here for the curious ones.

Next release(s)?

We first intended to make a new gtk-rs release soon after the last one, but then we implemented a lot of new features. Therefore, it needs to be tested and checked before we can release them. We still intend to make a new release in the next two months. More to come soon!

gir fixes and gstreamer adds?

We found two bugs in gir during this hackfest:

Invalid callbacks generation

When multiple callbacks are generated for one user data pointer, we were generating invalid code. Currently, when we have a C function with callbacks, we pass our callbacks (the closures provided by the user) inside that user_data parameter (it's a *mut c_void after all!). So a function like this (a bit simplified):

void gcab_cabinet_extract( GCab *gcab, const char *path, FileCallback file_callback, ProgressCallback progress_callback, void *user_data, Cancellable cancellable, Error *error);

Generates a function like this:

Run fn extract<P: IsA<gio::File>, Q: IsA<gio::Cancellable>>( &self, path: Option<&P>, file_callback: Option<&mut dyn (FnMut(&File) -> bool)>, progress_callback: Option<&mut dyn (FnMut(i64, i64))>, cancellable: Option<&Q>, ) -> Result<(), Error>;

Both file_callback and progress_callback are callbacks and need to be passed through one user_data so we can call them inside the C callbacks. In short, a few changes were required so that the lifetime and everything alongside were correctly generated.

Invalid "inheritance" generation

In some cases, some objects which are not supposed to be subclassed (meaning, not supposed to be used as parent) got trait implementation such as impl<O: IsA<Button>> ButtonExt for O , making it possible to "inherit" from them. Thanks to this pull request, it's now fixed!

Time for thanks!

First, thanks to Kinvolk for welcoming us (again!) in their office. Also many thanks to the GNOME Foundation for sponsoring my travel and accomodation during the hackfest!

And the final thanks go to @Zeeshan for organizing this hackfest at the last minute!