G_MENU_ATTRIBUTE_ICON does not work in GTK4 as expected!

,

I wonder why in GTK4, the attribute G_MENU_ATTRIBUTE_ICON does not work, where in GTK3 works fine.

This is how it looks like in GTK3 (The Icons are present):
GMenu-GTK3

and the same code in GTK4 (The Icons are not there anymore):
GMenu-GTK4

What does GTK4 make it to behave different?

Here is the Code I was used:

#include <gtk/gtk.h>

static void clbk ( G_GNUC_UNUSED GSimpleAction *simple_action,
                   G_GNUC_UNUSED GVariant *parameter,
                   G_GNUC_UNUSED gpointer data )
{
    const gchar *const action_name = g_action_get_name( G_ACTION( simple_action ) );
    g_print ( "Action [%s] called\n", action_name );
}

static void create_actions ( GtkApplication *application )
{
    const GActionEntry entries[] =
    {
        {  "new",  clbk, NULL, NULL, NULL, { 0, 0, 0 } },
        {  "open", clbk, NULL, NULL, NULL, { 0, 0, 0 } },
        {  "save", clbk, NULL, NULL, NULL, { 0, 0, 0 } },
        {  "quit", clbk, NULL, NULL, NULL, { 0, 0, 0 } }
    };

    /// ***
    g_action_map_add_action_entries ( G_ACTION_MAP ( application ), entries, G_N_ELEMENTS ( entries ), NULL );
}

static void create_menu_item ( GMenu *menu,
                               const gchar *const label,
                               const gchar *const detailed_action,
                               const gchar *const icon,
                               const gchar *const accel )
{
    GMenuItem *item;

    /// ***
    item = g_menu_item_new ( label, detailed_action );

    /// ***
    if ( icon )
    {
        g_menu_item_set_attribute ( item, G_MENU_ATTRIBUTE_ICON, "s", icon, NULL );
    }

    /// ***
    if ( accel )
    {
        g_menu_item_set_attribute ( item, "accel", "s", accel, NULL );
    }

    /// ***
    g_menu_append_item ( menu, item );

    /// ***
    g_object_unref ( item );
}

static void create_file_menu ( GMenu *menu,
                               const gchar *const menu_name )
{
    GMenu *file_menu;

    /// ***
    file_menu = g_menu_new();

    /// ***
    create_menu_item ( file_menu, "New",  "app.new",  "document-new",     "<Control>N" );
    create_menu_item ( file_menu, "Open", "app.open", "document-open",    "<Control>O" );
    create_menu_item ( file_menu, "Save", "app.save", "document-save",    "<Control>S" );
    create_menu_item ( file_menu, "Quit", "app.quit", "application-exit", "<Control>Q" );

    /// ***
    g_menu_append_submenu ( menu, menu_name, G_MENU_MODEL ( file_menu ) );

    /// ***
    g_object_unref ( file_menu );
}

static void startup ( GtkApplication *application )
{
    GMenu *menu;

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

    /// ***
    create_file_menu ( menu, "File" );

    /// ***
    create_actions ( application );

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

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

static void activate ( GtkApplication *application )
{
    GtkWidget *window;
    window = gtk_application_window_new ( application );

    /// ***
    gtk_window_set_application ( GTK_WINDOW ( window ), application );
    gtk_window_set_title ( GTK_WINDOW ( window ), "GMenu" );

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

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

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

    /// ***
    application = gtk_application_new ( "my.gtk.app", G_APPLICATION_FLAGS_NONE );

    /// ***
    g_signal_connect_swapped ( application, "startup",  G_CALLBACK ( startup ), application );
    g_signal_connect_swapped ( application, "activate", G_CALLBACK ( activate ), application );

    /// ***
    status = g_application_run ( G_APPLICATION ( application ), argc, argv );
    g_object_unref ( application );

    /// ***
    return status;
}

OS:

Distributor ID:	Linuxmint
Description:	Linux Mint 20.1
Release:	20.1
Codename:	ulyssa

GTK Versions:

michael@mikye:~$ pkg-config --modversion gtk+-3.0
3.24.20
michael@mikye:~$ pkg-config --modversion gtk4
4.2.0

There has been some discussions in the last years about the fact that icons has been removed for menus and buttons. I wonder that you were able to show them in GTK3 at all, I have seen them the last time more than 10 years ago in some GTK2 app. But I think you know that, as you are the guy with the youtube videos :slight_smile:
Last discussion was in the last 12 months I think, someone said that he wants icons, Mr. Bassi said that it is cleaner without and that people do more remember menu entries by position, not that much by icon.

Sometimes I miss icons myself.

1 Like

I think I found the old thread:

Principle of icons in menus

1 Like

That’s the reason why I was asking:

I wonder why in GTK4, the attribute G_MENU_ATTRIBUTE_ICON does not work, where in GTK3 works fine.

Or, if it should have not working in GTK3, then why did I manage to succeed to make it work and why/where exactly stops now in GTK4?

PS: I am also agreed that icons are not the best choice as well, but someone asked me on my Channel.

Yes, this is expected. GTK3 had GtkMenu and GtkMenuItem, whereas GTK4 has GtkPopoverMenu which builds the widgetry automatically.

Icons (both “icons” and “verb-icons”) are only used for icon-only item—i.e. items explicitly without a label—or “iconic” items, i.e. items that have a “display-hint” attribute with one of these values:

  • “horizontal-buttons”
  • “inline-buttons”
  • “circular-buttons”

For icon-only buttons, the “icon” attribute will be used to show an icon in the menu item; for iconic buttons, the “verb-icon” attribute will be used instead.

You can check the documentation for GtkPopoverMenu for the attributes in question.

1 Like

Yes, that makes sense. Thank you.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.