Custom widgets for items in a GMenu sub-menu

I have a GtkPopoverMenuBar with a GMenu and another GMenu inserted as a sub-menu. When I use the basic functionality, the basic items (non sub-menus) in both the main menu and the sub-menu appear as expected:

Screenshot from 2024-09-14 13-00-37

When I attempt to use custom widgets for both of the basic items, only the one in the main menu appears while the sub-menu item is missing:

Screenshot from 2024-09-14 13-00-22

I am calling gtk_popover_menu_bar_add_child to add the custom widget for both of these items to the menubar. This feels maybe wrong and it would seem to explain the behavior I’m seeing. Logically, it seems like the custom widget for the item in the sub-menu should be added to a GtkPopoverMenu with gtk_popover_menu_add_child. However I cannot find any documentation that shows a way to get a handle to the GtkPopoverMenu that backs the sub-menu in order to pass it to gtk_popover_menu_add_child.

Can anyone point me toward an example of custom widgets in a GMenu sub-menu?

For reference, here is the code for the demo app above (also on github):

#include <stdio.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>

#ifdef CUSTOM_WIDGETS
GtkWidget *menu_item_widget_new(
		const char *text
		)
{
	GtkWidget *layout = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	GtkWidget *label = gtk_label_new(text);
	gtk_box_append(GTK_BOX(layout), label);
	gtk_widget_set_visible(layout, true);
	return layout;
}
#endif

int main(
		int argc,
		char **argv
		)
{
	gtk_init();

	GMenu *main_menu = g_menu_new();
	GtkWidget *menubar = gtk_popover_menu_bar_new_from_model(G_MENU_MODEL(main_menu));

	GMenu *file_menu = g_menu_new();
	GMenuItem *file_item = g_menu_item_new_submenu("File", G_MENU_MODEL(file_menu));
	g_menu_insert_item(G_MENU(gtk_popover_menu_bar_get_menu_model(GTK_POPOVER_MENU_BAR(menubar))), 0, file_item);

	GMenu *recent_menu = g_menu_new();
	GMenuItem *recent_item = g_menu_item_new_submenu("Recent", G_MENU_MODEL(recent_menu));

	GMenuItem *filename_item = g_menu_item_new("File.txt", NULL);
#ifdef CUSTOM_WIDGETS
	g_menu_item_set_attribute(filename_item, "custom", "s", "filename");
#endif
	g_menu_insert_item(recent_menu, 0, filename_item);
#ifdef CUSTOM_WIDGETS
	GtkWidget *filename_widget = menu_item_widget_new("CustomFile.txt");
	gtk_popover_menu_bar_add_child(GTK_POPOVER_MENU_BAR(menubar), filename_widget, "filename");
#endif

	g_menu_insert_item(file_menu, 0, recent_item);

	GMenuItem *exit_item = g_menu_item_new("Exit", NULL);
#ifdef CUSTOM_WIDGETS
	g_menu_item_set_attribute(exit_item, "custom", "s", "exit");
#endif
	g_menu_insert_item(file_menu, 1, exit_item);
#ifdef CUSTOM_WIDGETS
	GtkWidget *exit_widget = menu_item_widget_new("Custom Exit");
	gtk_popover_menu_bar_add_child(GTK_POPOVER_MENU_BAR(menubar), exit_widget, "exit");
#endif

	g_free(exit_item);
	g_free(file_item);
	g_free(filename_item);
	g_free(recent_item);

    GtkWidget *mainwin = gtk_window_new();
	GtkWidget *win_layout = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

	gtk_box_append(GTK_BOX(win_layout), menubar);
	gtk_window_set_child(GTK_WINDOW(mainwin), win_layout);
	gtk_window_present(GTK_WINDOW(mainwin));

	while (g_list_model_get_n_items(gtk_window_get_toplevels()) > 0)
		g_main_context_iteration(NULL, TRUE);

	return 0;
}

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