I’ve been writing an application in Rust using the gtk4-rs
bindings for GTK. Recently, I’ve tried compiling my application on Windows under the UCRT64 builds of Rust and GTK4, but the application will not launch (seemingly) because of the MenuModel attached to a GtkMenuButton. Here is a small MWE that (at least on my two computers) shows the difference in functionality (note - MWE is in both C and Rust since it was originally written in Rust, then I ported that example to C at the behest of the gtk4-rs
folks to make sure it was the GTK library, and not the Rust crate):
test.ui
<?xml version='1.0' encoding='UTF-8'?>
<interface>
<requires lib="gio" version="2.0"/>
<requires lib="gtk" version="4.12"/>
<object class="GtkMenuButton" id="button">
<property name="menu-model">
<menu id="test-menu">
<item>
<attribute name="action">window.close</attribute>
<attribute name="label">Close Window</attribute>
</item>
</menu>
</property>
</object>
</interface>
main.c
#include <gtk/gtk.h>
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Hello");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
// Builder
GtkBuilder *builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "test.ui", NULL);
GObject *menubutton = gtk_builder_get_object (builder, "button");
gtk_window_set_child (GTK_WINDOW (window), (GtkWidget*)menubutton);
gtk_window_present (GTK_WINDOW (window));
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Compiled with gcc $(pkg-config --cflags gtk4) -o test main.c $(pkg-config --libs gtk4)
main.rs
use gtk4::glib;
use gtk4::prelude::*;
fn main() -> glib::ExitCode {
let app = gtk4::Application::builder()
.application_id("test.test.test")
.build();
app.connect_activate(|app| {
let window = gtk4::ApplicationWindow::builder()
.application(app)
.build();
let menubut = gtk4::Builder::from_string(include_str!("test.ui"));
let menubut: gtk4::MenuButton = menubut.object("button").unwrap();
window.set_child(Some(&menubut));
window.present();
});
app.run()
}
Observed Behavior
The behavior of these two examples is slightly different, so they will both be described:
C Minimal Example
- On Arch Linux, the example works as expected, allowing the user to click on the button and displaying the menu.
- On Windows, the example loads, but the button is greyed out and unable to be interacted with.
Rust Minimal Example
- As before, on Arch Linux, the example works as expected.
- On Windows, the example crashes on startup, with the error
Gtk-ERROR **: [...]: failed to add UI: .:6.34 Object with ID not found
(the spacing between “ID” and “not” is accurate and intentional).
Software Versions
- Windows
- Rust 1.84.1
gtk4-rs
0.9.6- GTK 4.16.12 (Installed via UCRT64 in MSYS2)
- Linux
- Rust 1.86.0
gtk4-rs
0.9.6- GTK 4.18.3 (Up-to-date Arch Linux)
I’d really appreciate any help possible to figure out how to get this to work (especially if it ends up being user error!) If I can provide anything else to help find the problem, please let me know, and thank you in advance!