How does gtk_application_get_menu_by_id exactly works

,

I am trying to figure out, how does gtk_application_get_menu_by_id works and I have no idea at all.

The program flow:

  • Created an resources information

  • in the startup function I am calling gtk_builder_new_from_string()

  • after that I am calling gtk_builder_get_object and I am passing the menu id (test-menu)

  • called gtk_application_set_menubar inside startup

  • called gtk_application_window_set_show_menubar inside activate

The program works fine, but the problem comes after I call the gtk_application_get_menu_by_id() where the id passed is test-menu, the application returns:

** (GtkApplication:16669): CRITICAL **: 20:35:35.376: activate: assertion 'get_res_menu != NULL' failed

What I am doing wrong here?

builder-res

A demo code which explains it better:

#include <gtk/gtk.h>

static const gchar *resources =
    "<interface>"
        "<menu id='test-menu'>"
            "<section>"
                "<item>"
                    "<attribute name='label'>New</attribute>"
                    "<attribute name='action'>app.new</attribute>"
                    "<attribute name='accel'>&lt;control&gt;D</attribute>"
                "</item>"

                "<item>"
                    "<attribute name='label'>Open</attribute>"
                    "<attribute name='action'>app.open</attribute>"
                    "<attribute name='accel'>&lt;control&gt;O</attribute>"
                "</item>"

                "<item>"
                    "<attribute name='label'>Quit</attribute>"
                    "<attribute name='action'>app.quit</attribute>"
                    "<attribute name='accel'>&lt;control&gt;Q</attribute>"
                "</item>"
            "</section>"
        "</menu>"
    "</interface>";

static void startup ( GtkApplication *application, G_GNUC_UNUSED gpointer data )
{
    /// ***
    GtkBuilder *builder;
    GMenu      *menu;
    GMenuModel *model;

    /// ***
    builder = gtk_builder_new_from_string ( resources, -1 );

    /// ***
    menu = g_menu_new();

    /// ***
    model = G_MENU_MODEL ( gtk_builder_get_object ( builder, "test-menu" ) );
    g_assert ( model );

    /// ***
    g_menu_append_submenu ( menu, "File", model );

    /// ***
    gtk_application_set_menubar ( application, G_MENU_MODEL ( menu ) );

    /// ***
    g_object_unref ( menu );
    g_object_unref ( builder );
}

static void activate ( GtkApplication *application, G_GNUC_UNUSED gpointer data )
{
    /// ***
    GtkWidget *window;

    /// ***
    window = gtk_application_window_new   ( application );

    /// ***
    gtk_window_set_title        ( GTK_WINDOW ( window ), "GtkApplicationWindow" );
    gtk_window_set_default_size ( GTK_WINDOW ( window ), 300, 200 );

    /// ***
    gtk_application_window_set_show_menubar ( GTK_APPLICATION_WINDOW ( window ), TRUE );

    /// ***
    GMenu *get_res_menu;
    get_res_menu = gtk_application_get_menu_by_id ( application, "test-menu" );

    /// ***
    g_return_if_fail ( get_res_menu != NULL );

    /// ***
    gtk_window_present ( GTK_WINDOW ( window ) );
}

int main ( void )
{
    GtkApplication *application;
    gint status;

    /// ***
    application = gtk_application_new ( "this.is.my-nice.app", G_APPLICATION_FLAGS_NONE );

    /// ***
    g_signal_connect ( application, "activate", G_CALLBACK ( activate ), NULL );
    g_signal_connect ( application, "startup",  G_CALLBACK ( startup ),  NULL );

    /// ***
    status = g_application_run ( G_APPLICATION ( application ), FALSE, NULL );

    /// ***
    g_object_unref ( application );
    return status;
}

Created an resources information

“resources” in the documentation refers to a GResource, that is, data that is compiled into the executable (or loaded and registered from disk before creating the GtkApplication).

Usually resources are used similarly as files on disk, for example to load UI definitions with gtk_builder_new_from_resource(), but some resources are handled automatically by GTK if they exist, like /org/example/MyApp/gtk/menus.ui or /org/example/MyApp/icons.

See the “Automatic Resources” section in https://developer.gnome.org/gtk4/stable/GtkApplication.html.

1 Like

I should have already know this.Thank you