gtk4-rs 0.9 and gtk-rs-core 0.20 were just freshly released, just in time for also being included in the GNOME 47 release.

This release is again relatively small, mostly providing bindings to new APIs and improvements to the glib::clone! and glib::closure! macros to work better with cargo fmt and rust-analyzer.

As usual, at the same time gstreamer-rs 0.23 and gst-plugins-rs 0.13, libadwaita 0.7 and other related crates got a new release compatible with the new gtk4-rs and gtk-rs-core releases and their own set of changes.

gtk-rs-core §

New syntax for glib::clone! and glib::closure! §

The syntax for the clone! and closure! macros was updated to look more like valid Rust code, and as a side effect it is also handled correctly by cargo fmt, rust-analyzer and other tooling now.

The old syntax is still supported but will give a deprecation warning.

To get an idea of the change, what previously looked like:

clone!(@strong self as obj, @weak v => @default-return false, move |x| {
    println!("obj: {}, v: {}, x: {}", obj, v, x);
    true
})

would now look like this:

clone!(
    #[strong(rename_to = obj)]
    self,
    #[weak]
    v,
    #[upgrade_or]
    false,
    move |x| {
        println!("obj: {}, v: {}, x: {}", obj, v, x);
        true
    },
);

Check the documentation for more details about the new syntax.

GLib 2.82 APIs §

New GLib and GIO 2.82 APIs are supported with this release. GLib 2.56 is still the minimum version supported by the bindings.

Trait re-organization for defining new GObject interfaces §

The traits for defining new GObject interfaces were slightly re-organized to make them more similar with the ones for defining new GObjects.

Previously one would write:

#[derive(Clone, Copy)]
#[repr(C)]
pub struct MyStaticInterface {
    parent: glib::gobject_ffi::GTypeInterface,
}

#[glib::object_interface]
unsafe impl ObjectInterface for MyStaticInterface {
    const NAME: &'static str = "MyStaticInterface";
}

This would now become:

#[derive(Clone, Copy)]
#[repr(C)]
pub struct MyStaticInterfaceClass {
    parent: glib::gobject_ffi::GTypeInterface,
}

unsafe impl InterfaceStruct for MyStaticInterfaceClass {
    type Type = MyStaticInterface;
}

pub enum MyStaticInterface {}

#[glib::object_interface]
impl ObjectInterface for MyStaticInterface {
    const NAME: &'static str = "MyStaticInterface";

    type Interface = MyStaticInterfaceClass;
}

While it is a bit more code, this is almost the same as for GObjects now.

Safer borrowing of GObjects and other types from FFI code §

It is possible to directly borrow GObjects and other types in FFI code without additional refcounting or copying. In previous releases the API for that was completely based on pointers, which allowed to accidentally create dangling pointers without the compiler being able to help.

let obj = {
    let mut ptr: *mut glib::ffi::GObject = ...;
    let obj: &glib::Object = glib::Object::from_glib_ptr_borrow(&mut ptr);
    obj
};
// At this point `obj` is pointing at a stack frame that does not exist anymore

Starting with this release, a reference to a pointer is used instead to avoid this from happening. The above code would not compile anymore. Previously the lifetime of the returned object would be arbitrary, now it is bound strictly to the lifetime of the pointer.

Code using this API likely does not need any changes unless the code was previously wrong.

gtk4-rs §

GTK 4.16 APIs §

New GTK 4.16 APIs are supported with this release. GTK 4.0 is still the minimum version supported by the bindings.

Changes §

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

gtk4-rs:

gtk-rs-core:

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

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