adding the same GMenu to the same GtkMenuButton using `gtk_menu_button_set_menu_model()` freezes the application
This is what was causing #4420 (closed) and can be reproduced with the following:
#include <gtk/gtk.h>
static GtkWidget * menubutton;
static GMenu * menu = NULL;
static void
activate_incendio (
GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_print ("Incendio\n");
}
static void
print_hello_and_set_menubutton_model (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
if (!menu)
{
menu = g_menu_new ();
g_object_ref_sink (menu);
}
GMenu *section = g_menu_new ();
g_menu_append (menu, "Incendio", "app.incendio");
g_menu_append (menu, "Incendio", "app.incendio");
g_menu_append (section, "Incendio", "app.incendio");
g_menu_append (section, "Incendio", "app.incendio");
g_menu_append_section (menu, "section", G_MENU_MODEL (section));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menubutton), G_MENU_MODEL (menu));
}
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), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
GtkWidget * box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
menubutton = gtk_menu_button_new ();
gtk_menu_button_set_label (GTK_MENU_BUTTON (menubutton), "menubutton");
gtk_box_append (GTK_BOX (box), menubutton);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello_and_set_menubutton_model), box);
gtk_box_append (GTK_BOX (box), button);
gtk_window_set_child (GTK_WINDOW (window), box);
const GActionEntry entries[] = {
{ "incendio", activate_incendio },
};
g_action_map_add_action_entries (
G_ACTION_MAP (app), entries, 1, NULL);
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_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Compile with
gcc -o hello-world-gtk main.c `pkg-config --cflags --libs gtk4`
Just keep pressing the "Hello World" button and the program will freeze. Obviously it's pretty useless to set the same menu model over and over again but it shouldn't misbehave
The same issue happens often if you set a new menu model with items containing the same action names to either GtkPopoverMenu or GtkMenuButton. Also, the same issue happens if you try to remove all menu entries from the GMenu and add new entries that have the same action name. In all cases the backtraces are the same as the reproducer above (a bunch of nested gtk_action_muxer_primary_accel_changed()
-> gtk_action_observer_primary_accel_changed()
-> gtk_action_muxer_observer_primary_accel_changed()
with the same action_name
and action_and_target
parameters).
Version
4.4.0 on Arch Linux, also happens with 4.5.0 as a subproject