Only GMenu, GMenuItem, GMenuModel, and GSimpleAction can be used to create menus in GTK4. Is it possible to put a check mark next to a known GMenuItem?
I've menaged to enable/disable menu item by manipulating GSimpleAction. However, there is no documentation how to put check mark.
I also tried to find out about this and I figured it out.
The type of a menu item depends on the type of action it was mapped to, you cannot control the menu item type directly. For a normal action created with g_simple_action_new
it will appear as just text, but if the action was created like so:
gboolean initial_value = 1;
GVariant* variant = g_variant_new_boolean(initial_state);
g_action = g_simple_action_new_stateful("stateful", NULL, variant);
We're on our way to have a checkmark menu item.
We then need to add this action to our application using g_action_map_add_action
, connect to the activate
signal of the action with g_signal_connect
, then add a menu item to our menu model model
like so:
GMenuItem* item = g_menu_item_new("item label", "app.stateful");
g_menu_append_item(G_MENU(model), item);
g_object_unref(item);
Where item label
is the label and stateful
was the name of the stateful action we created.
After all these steps (remember to connect to the signal and keep the action enabled or it will appear greyed out) the item will magically appear with a checkmark.
To change the current state of the item, we change the state of the action:
// get state
gboolean current_state = g_variant_get_boolean(g_action_get_state(G_ACTION(g_action))));
// set state
gboolean new_state = current_state;
g_action_change_state(G_ACTION(g_action), g_variant_new_boolean(new_state));
I tested it and it appears that the formatting of the menu item depends on this argument when creating the action:
// create as checkmark
g_action = g_simple_action_new_stateful("stateful", NULL, variant);
// create as dot
g_action = g_simple_action_new_stateful("stateful", G_VARIANT_TYPE_BOOLEAN, variant);
Why? I have no idea, you'd think setting it to boolean would make it a checkmark but no, setting it to NULL
does. How is anyone supposed to figure this out? I also have no idea, I spend half a day reverse engineering but maybe there's a doc page on it somewhere.
I love GTK4, it runs so well now and the menus are really flexible and powerful since they can contain widgets directly now, but the menu and action-related docs are truly awful, the information is there but scattered everywhere between the Gio, GLib and GTK doc pages and simple questions like "why is this item greyed out" can take hours to answer.