Skip to content

Comments

Replace GTK Widgets with Custom Widgets to Help with Upgrade to GTK4#325

Draft
Lepidopteran wants to merge 9 commits intotauri-apps:feat/gtk4from
Lepidopteran:feat/gtk4-widget
Draft

Replace GTK Widgets with Custom Widgets to Help with Upgrade to GTK4#325
Lepidopteran wants to merge 9 commits intotauri-apps:feat/gtk4from
Lepidopteran:feat/gtk4-widget

Conversation

@Lepidopteran
Copy link

@Lepidopteran Lepidopteran commented Nov 22, 2025

After messing around with gtk4-rs to see if we could get icons on the PopoverMenuBar and PopoverMenu, I had no luck.

After researching and looking at the gtk source code, I made a discovery:

static void
update_visibility (GtkModelButton *self)
{
  gboolean has_icon;
  gboolean has_text;

  has_icon = self->image && gtk_image_get_storage_type (GTK_IMAGE (self->image)) != GTK_IMAGE_EMPTY;
  has_text = gtk_label_get_text (GTK_LABEL (self->label))[0] != '\0';

  gtk_widget_set_visible (self->label, has_text && (!self->iconic || !has_icon));
  gtk_widget_set_hexpand (self->label,
                          gtk_widget_get_visible (self->label) && !has_icon);

  if (self->accel_label)
    gtk_widget_set_visible (self->accel_label, has_text && (!self->iconic || !has_icon));

  if (self->image)
    {
      gtk_widget_set_visible (self->image, has_icon && (self->iconic || !has_text));
      gtk_widget_set_hexpand (self->image,
                              has_icon && (!has_text || !gtk_widget_get_visible (self->label)));
    }
}

while GtkPopverMenu does watch for an icon attribute on an GMenuItem it does not display it if has a text with it.

Additionally from what I could find, GtkPopoverMenuBar doesn't even look for icon.

So that leads me to the conclusion in order to keep icon support, we have to create custom widget versions of GtkPopverMenu and GtkPopoverMenuBar.

So far I've gotten moderate success with recreating GtkPopoverMenuBar example below.

Screenshot From 2025-11-22 10-56-28

I've done this before for creating a custom font family chooser dropdown, it's not necessarily easy but it is doable from my experience.

I've gathered some source files and how it looks like they are structured if anyone is interested in helping:

Additionally I'd like to get separators working again, possibly creating a custom object that extends GMenuModel so we can control how the menus are built but I haven't tested that yet.

I currently haven't touched anything about the gtk back-end so I've marked this as draft request, but the end goal is to use the custom widgets for said back-end.

I personally don't see the need for icons for menu bars but I'm not okay with limiting developers.

I've also made an example to test the compatibility between the gtk4 widgets and the custom widgets, you can run it using the following:

cargo run --example gtk_widgets

Tasks

  • Replace widgets in gtk back-end with newly created widgets.
  • Create MenuBar widget
    • Display Items with submenus from GMenuModel
      • Display icons and labels
    • Make keyboard accessible
      • Left and Right arrow keys cycle through items
      • When cycling through items close current submenu and open submenu of the next item if menu was opened.
      • Down arrow key opens active item's submenu.
  • Create PopoverMenu widget.
    • Display Items.
      • Display icons and labels if item is normal.
      • Display accelerator if action has one.
      • Display checkbox if action has boolean state.
      • Display right arrow at end if item has submenu.
      • Display separators.
    • Active items displays submenu if selected and item has submenu
    • Make keyboard accessible.
      • Up and Down arrow key cycles through items.
      • Right arrow key goes into nested submenu if item has a submenu.
      • Left arrow key exits submenu goes to parent submenu if submenu is nested.
      • Enter key activates item.
  • Add ability to add separator item that groups items after it so muda can use it

Final Thoughts

Helps with #270, #259, and #272

Please let me know if what I'm doing is unwanted or if you have any feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant