This page describes how to use GMenu models for various kinds of menus in your application.
A GMenu refers to GActions with prefixed names, so you need to add GActions to your application for the things you want to expose in a menu. How you can do this is explained here: HowDoI/GAction.
The application menu
The most prominent example for using GMenu models is the application menu that is shown in the GNOME shell top bar. See HowDoI/ApplicationMenu.
DEPRECATION WARNING: The use of application menu is now being phased out.
It is possible to construct a menu model manually, using the GMenu APIs directly. This is a somewhat painful:
GMenu *menu, *section; menu = g_menu_new (); section = g_menu_new (); g_menu_append (section, "Incendio", "app.incendio"); g_menu_append_section (menu, "Offensive Spells", section); g_object_unref (section); section = g_menu_new (); item = g_menu_item_new ("Expelliarmus", "app.expelliarmus"); g_menu_item_set_icon (item, defensive_icon); g_menu_append_item (section, item); g_menu_append_section (menu, "Defensive Charms", section); g_object_unref (section); ...
Note that the 'app.' in the action names is a prefix that indicates these actions are from the application scope. See HowDoI/GAction for more information about scopes and how to set up GActions in various scopes.
A much better way of constructing menu models is to use GtkBuilder. For this, you describe your menu in xml:
<interface> <menu id="menu"> <section> <item> <attribute name="label" translatable="yes">Incendio</attribute> <attribute name="action">app.incendio</attribute> </item> </section> <section> <attribute name="label" translatable="yes">Defensive Charms</attribute> <item> <attribute name="label" translatable="yes">Expelliarmus</attribute> <attribute name="action">app.expelliarmus</attribute> <attribute name="icon">/usr/share/my-app/poof!.png</attribute> </item> </section> </menu> </interface>
In your code, you then create the GMenuModel using a GtkBuilder:
builder = gtk_builder_new_from_resource ("/my/favourite/spells/menu.ui"); menu = G_MENU_MODEL (gtk_builder_get_object ("menu");
A common pattern in modern user interfaces is to place a button, often with a gears icon, in some prominent place (top-right), which will open a menu when clicked. GTK+ comes with the GtkMenuButton widget for this use case, and it can easily be used with a GMenu:
builder = gtk_builder_new_from_resource ("/my/favourite/spells/potions.ui"); menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu")); gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menu_button), menu); g_object_unref (builder);
One thing to notice is that a gears menu will often refer to actions from the window scope. Make sure to use the 'win.' prefix when doing so, and add the actions to your GtkApplicationWindow instead of the GtkApplication.
It is possible to create a 'freestanding' GtkMenu from a menu model, using gtk_menu_new_from_model(). This GtkMenu can then be used as a context menu on any widget. The actions you refer to in such a menu can come from the application or window scopes. You can also introduce a more localized scope, using gtk_widget_insert_action_group(). The actions from such a local scope can be used in any menu that is attached below this local scope.
cauldron = my_fancy_widget (); gtk_widget_insert_action_group (cauldron, "local", cauldron_actions); menu = gtk_menu_new_from_model (cauldron_menu); gtk_menu_attach_to_widget (menu, cauldron, NULL); ...
It is also possible to construct GtkPopovers from menu models, using gtk_popover_new_from_model(). GtkMenuButton has a 'use-popover' property that will instruct it to create a popover from its model instead of a menu.
button = gtk_menu_button_new (); gtk_menu_button_set_use_popover (button, TRUE); gtk_menu_button_set_menu_model (button, menu);
GtkImageMenuItem has been deprecated, the recommended way to add icons to menu items is to put them in the main content of the menuitem (ie instead of just a label, you pack a hbox with the icon and the label). This moves the icons out of the column containing the checkmarks for radio and check menuitems, and instead aligns them with the labels. The intended use is to only use icons for nouns, not for verbs (ie a bookmark might get an icon, but a 'Reset' item should not).
GMenu supports this usage of icons out of the box. You simply specify the icon attribute on the items in your menu model, and when the menu is constructed, the icon will be properly placed in the GtkMenu. The expected value for this attribute is a serialized GIcon. Luckily, the GIcon serialization format is convenient for this use. E.g.
is a valid serialization for a GFileIcon for the file /path/to/my/icon.png and
is a valid serialization for a GThemedIcon for the symbolic icon 'preferences-desktop-locale-symbolic'.