Hi everyone!

It’s time for a new release! Main adds/changes this time are:

  • We added the generation of the Atk crate.
  • We now generate functions taking callback as parameters.
  • We improved the channels handling in GLib.
  • The whole new GString type!
  • The minimum Rust version supported is now the 1.31.
  • The minimum version of all libraries has been changed to GNOME 3.14.
  • The maximum version of all libraries has been upgraded to GNOME 3.30.
  • Added subclassing support in GLib.
  • Even more bindings generated.

Let’s see those in details.

Atk

The Atk crate is about accessibility. We thought it was a miss not having it considering how important accessibility is. Now it’s fixed! You can find more information directly on the Atk repository or in the accessibility example.

Callbacks?

We already implemented by hand a lot of these functions but the big new thing in here is that they’re now automatically generated.

To present this, let’s use the foreach method of TreeModel:

The C version looks like this:

void gtk_tree_model_foreach(
    GtkTreeModel *model,
    GtkTreeModelForeachFunc func,
    gpointer user_data
);

Nothing fancy here: it takes the object we’re running this function upon, a callback and some user data. Now here’s the Rust version:

fn foreach<P: FnMut(&TreeModel, &TreePath, &TreeIter) -> bool>(
    &self,
    func: P,
);

No more user data since closures can capture their environment, just the object and the callback (aka closure). Makes things a bit simpler and nicer to use.

GLib channels

Instead of rewriting something fully in here, I’ll just show you what it looks like and recommend you to go read the excellent Sebastian’s blog post about it: https://coaxion.net/blog/2019/02/mpsc-channel-api-for-painless-usage-of-threads-with-gtk-in-rust/

enum Message {
    UpdateLabel(String),
}

[...]
let label = gtk::Label::new("not finished");
[...]
// Create a new sender/receiver pair with default priority
let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);

// Spawn the thread and move the sender in there
thread::spawn(move || {
    thread::sleep(time::Duration::from_secs(10));

    // Sending fails if the receiver is closed
    let _ = sender.send(Message::UpdateLabel(String::from("finished")));
});

// Attach the receiver to the default main context (None)
// and on every message update the label accordingly.
let label_clone = label.clone();
receiver.attach(None, move |msg| {
    match msg {
        Message::UpdateLabel(text) => label_clone.set_text(text.as_str()),
    }

    // Returning false here would close the receiver
    // and have senders fail
    glib::Continue(true)
});

GString type?

This type has been created in order to prevent some useless copies to improve performances. It’s used in case a function returns a String while fully transferring it. In such cases, we now just wrap it instead of cloning it.

This is part of our performance focus. More to come in the next release!

Minimum Rust version supported

We moved it to 1.31.0 mainly because imports handling is much easier starting this version. We still need to update macros though (an issue about it is already open).

subclassing support in GLib

This is a strongly asked feature and we now have it in GLib. A lot of work remains to be done, but it’s mostly polishing. At its current state, it can be used already. Take a look at the listbox_model if you want to see how it works.

Even more bindings generated

Just like usual, with the improvements of our gir crate, we are able to generate more and more parts of all the GNOME libraries we wrote bindings for.

Conclusion

That’s it for this release! Don’t forget to take a look at our brand new F.A.Q. section.

And again: thanks a lot to all of our contributors! This project lives thanks to their awesome work!

Changes

For the interested ones, here is the list of the merged pull requests:

sys:

glib:

cairo:

sourceview:

atk:

gio:

pango:

gdk-pixbuf:

gdk:

gtk:

pangocairo:

gtk-test:

All this was possible thanks to the gtk-rs/gir project as well:

Thanks to all of our contributors for their (awesome!) work for this release: