GTK4 g_menu and g_object_unref

Why is there no g_object_unref(menu); at the end of any example with g_menu?

Are the memory leaks accepted because everything is released by the OS at the end of the program anyway?

Or does GTK4 take care of it somewhere in the background?

In the following example, 2 main menus are shown separately, which demonstrates that things are different with g_menu than with GTKWidget.

// gcc -o main main.c `pkg-config --cflags --libs gtk4`

#include <gtk/gtk.h>

static void quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app)
{
    g_application_quit(G_APPLICATION(app));
}

static void activate(GtkApplication* app, gpointer user_data) {
    GtkWidget *window;
    GtkWidget *box;
    GtkWidget *menubar;
    GMenu *menu, *fileMenu, *editMenu;
    GMenuItem *menuItem;
    GSimpleAction *quit_action;

    window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(window), "GTK4 Menu");
    gtk_window_set_default_size(GTK_WINDOW(window), 330, 200);

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_window_set_child(GTK_WINDOW(window), box);

    menu = g_menu_new();
    fileMenu = g_menu_new();

    g_menu_append_submenu(menu, "Datei", G_MENU_MODEL(fileMenu));

    g_menu_append(fileMenu, "Öffnen", "app.open");
    g_menu_append(fileMenu, "Beenden", "app.quit");

    // --- menubar 1
    menubar = gtk_popover_menu_bar_new_from_model(G_MENU_MODEL(menu));
    gtk_box_append(GTK_BOX(box), menubar);
    // --- menubar 2
    menubar = gtk_popover_menu_bar_new_from_model(G_MENU_MODEL(menu));
    gtk_box_append(GTK_BOX(box), menubar);

    quit_action = g_simple_action_new("quit", NULL);
    g_signal_connect(quit_action, "activate", G_CALLBACK(quit_activated), app);
    g_action_map_add_action(G_ACTION_MAP(app), G_ACTION(quit_action));

    gtk_window_present(GTK_WINDOW(window));
}

int main(int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new("org.example.menu", 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;
}

You do need to unref the menu if you don’t want it to leak upon destroying the window. There are no floating references here like with GtkWidget (GInitiallyUnowned).

What examples are you looking at? Many ‘official’ examples use GtkBuilder XML, where the menu is owned by the builder instance, e.g. the Application demo in gtk4-demo:

Yes, there’s no problem with two views sharing the same model.

Which examples? Where did you find them?

Which examples? Where did you find them?

In the example in the first answer. The FMenuItem has an unref, but not the whole menu.

I assume you understand that the GNOME project is not responsible for random examples appearing on Stack Overflow.

The answer you linked points to this tutorial; please, file an issue against it for clarification.

In general, the answer to the “who owns this data” is answered by the API reference: ownership can be transferred from the caller (the developer) to the callee (the function); it can be transferred from the callee to the caller; or it can be retained by the callee or the caller. For instance, the documentation of gtk_application_set_menubar() specifies that the GMenuModel representing the menu bar is owned by the caller of this function (typically, you); this means that you’re responsible for releasing the reference you have once you’re done with it.

The answer you linked points to this tutorial ; please, file an issue against it for clarification.

Then would you recommend this tutorial? GitHub - ToshioCP/Gtk4-tutorial: GTK 4 tutorial for beginners

I have not read the whole tutorial, so I can’t comment on it. I can only guarantee about the quality and maintenance of the tutorials on developer.gnome.org.

Now I’m slowly starting to understand how it works with the menu.
Every time I call gtk_box_append(GTK_BOX(vbox), CreateMenuButton(menu)); the reference counter of the menu object is increased, so at the end, as soon as all menus are loaded, I can call g_object_unref(menu); once.

As a test, after creating the menu, I did the following: g_object_set_data_full(G_OBJECT(menu),"test", menu, testProc); And in the testproc I looked at the ref_count, and it shows “0”. And testProc is called once when the program ends.

I have not read the whole tutorial, so I can’t comment on it. I can only guarantee about the quality and maintenance of the tutorials on developer.gnome.org .

I had a quick look and will take a closer look when I get the chance. I’m sure you’ll learn a lot.

It’s not really something limited to menus: it works the same for every GObject instance. You may want to read the documentation:

The reference count of the menu object is increased every time you create a widget that acquires a reference on the menu object, yes.

As I have since found out, most things where GTK_xxx is written don’t need an unref, almost only for things with G_xxx.
Can you rely on the fact that if you query with ->ref_count before and after the commands and the counter is higher afterwards, you then have to do an unref yourself?

That’s not true at all.

You can avoid releasing references on anything that inherits from GInitiallyUnowned (like GtkWidget) because the initial, “floating” reference is transferred (“sunk”) to another object, for instance when you add a child widget to a container. Some API in GTK is also annotated to use full ownership transfer when using parameters.

You have to understand how reference counting work, otherwise you should not be using the C API, and you’re much, much better off with using GTK in another programming languages.

No, you most definitely cannot access the ref_count field. The field is semi-public only for debugging purposes, but application code should never use it.