Icon and tooltip for menu item

Hi!

I need to add an icon to menu item, the menu is displayed as popover from menu model (context popup, gtk4).
The code I am trying to add the icon:


	GMenuItem * item = g_menu_item_new( "item", "win.item_action" );

	GdkPixbuf * pixbuf = gdk_pixbuf_new_from_file( "...path.../icon.png", NULL );
	GIcon * icon = G_ICON( pixbuf );
	g_menu_item_set_icon( item, icon );

Unfortunately, this code have no effect.
Any ideas what is wrong here?

And, another question: does anyone know how to add a tooltip to the same menu item? The item is not a widget…

Thanks

Is it with GTK 3 or 4?

For GTK 3 I’ve written this small library: Amtk, but I think it will be hard to have the same set of features with GTK 4.

BTW, Amtk doesn’t implement GtkBuilder or have an XML format, but that’s just syntactic sugar. The most important is what is possible to do in the first place (the feature set). Amtk just builds upon GAction and the GTK 3 widgets, and these are very flexible.

Edit: and, GtkUIManager (deprecated) created an abstraction on top of the basic GTK 3 widgets, but with that abstraction it was more difficult to use all the possibilities of the basic menu/toolbar widgets, connecting some things to a statusbar, etc.

Remember not all ‘model renderers’ support every attribute — As you’ve found here, GtkPopover doesn’t support icons on general items.

I can’t say I’m aware of any supporting a tooltip, but I may be misremembering.

If popover doesn’t support icons, what is the proper way to implement context menu (popup, activated by mouse right click) that supports icons?

If you’re using GTK 3, libdazzle has DzlMenuButton which is like GtkMenuButton but uses an implementation which will show icons for rows which have a “verb-icon-name” attribute. The alternate attribute name was mostly chosen so that you had to be specific about wanting them displayed.

Thank you, but I am interesting in GTK 4.

You might consider adding a custom menu item, such as has been done in many recent applications which have a theme switcher widget at the top of the menu. In the model definition, something like this:

  <menu id="primary_menu">
    <section>
      <item>
        <attribute name="custom">customwidget</attribute>
      </item>
    </section>

Then, in the window’s Construct method, you would get the GtkPopoverMenu associated with your menu button and use the add_child method to replace it with whatever custom widget you wish (including a composite widget which would have a label and an icon in a horizontal box, for instance).

GtkPopoverMenu pop;
pop = (GtkPopoverMenu)gtk_menu_button_get_popover (my_menu_button);
gtk_popover_menu_add_child (pop, my_custom_widget, "customwidget");

Apologies if the above C is incorrect. I’ve done this in Vala and Rust, but rarely touch C. Note that you will likely have to add an action manually and construct your custom widget in such a way that it is activated on clicks. Or you could just use a GtkButton with the has-frame property set to FALSE.

Thank you for explanation, it make sense. Hoped that creation of context menu would be not so complicated :slight_smile:

It’s not really complicated—unless you go against the convenience API that is strongly encouraging you not to use icons inside menus.

If you use GtkPopoverMenu you have various attributes you can use—including icon and verb-icon, but generally speaking icons in menus have all but disappeared from most platforms (if they ever had them in the first place).

Menus don’t really have tooltips either, these days. If you need an additional tooltip to explain what a menu item does, then you probably want a more descriptive label instead.

2 Likes

I would second all that ebassi said.

One of my earlier applications was originally on gtk3, and in the process of porting to gtk4 I did for a time have the urge to swim upstream and attempt re-implementing certain things in the interface exactly as they had been before, including menu icons. What I found is that not only was the code cleaner after I let go of that and started building in the way that the toolkit is expected to be used, I actually preferred the resulting interface.

I’m actually in the process of taking this to a further level and rewriting parts of several applications to target Gnome specifically. So while I’m happy to share knowledge on how one might do a thing, it does pay to stop and think whether it’s a thing that you really should do.

Hi,
Regarding the icons in menu: obviously, the code will be cleaner, because API don’t provide simple way to add icons (at least in popover); question about menu icons usage is discussable, maybe indeed it’s preferable way to avoid them, maybe not - but it’s religion discussion, I just want to know how to do it. @ebassi , you mention that we can use “icon” and “verb-icon” attributes (as I understand without custom menu items?) - not clear to me how - can you, please, give an example?
Regarding tooltip: the purpose of tooltips is not only explain what a menu items does, but provide some extra information if need; for example - I want to display clipboard content when mouse pointer hover “paste” item. If signal like “item-hover” will be provided (I saw the thread about it) - it will give a possibility to provide “custom tooltip”, but of course, something native and simple to use is preferable.

You set them as you’d set any other attribute: either in the XML, or programmatically using the GMenuItem API.

I don’t have an example for you: that’s why I linked the documentation.

The important part is that it’s entirely implementation defined whether or not the icon will be shown.

This is a terrible idea: tooltips will be blocked by retrieving the clipboard’s contents, which can be arbitrarily large.

In any case: no, menus created by GTK will not have tooltips.

Another case of providing extra info in menu items is the Recent files list. Typically, such a list displays file names only, but it can use tooltips for displaying full paths. You’ll find it e.g. in LibreOffice, at least in the GTK3 version. I don’t know whether they’ve dropped this feature in the GTK4 version.

I have implemented a similar feature (not in the menu). It works reasonably fast with small amounts of text (1-5 MB) even on a slow machine. But very large amounts would be problematic. Can we get somehow the size of the (potential) clipboard content without retrieving it?

I am not sure whether GTK4 supports select events by menu items. If so, you can apply the method used 30 years ago by Turbo Vision. This was a framework for DOS. Because it was text-based, tooltips were impossible. However, it was possible to display hint texts for menu items in the status line. Forward to the past? :slight_smile:

As the person who implemented the whole recent files API and related widgetry in GTK, I can authoritatively tell you that recent files menus are a terrible UI that does not scale and does not work reliably enough to be placed in front of a user. That’s why the file selection dialog has a whole “recently used” mode, which allows for better filtering and presentation. Menus with recent files are a bad solution from the early ‘00s, and they were never actually tested with real workflows, otherwise it’d be immediately apparent how they work only for the case of opening the very last file you touched—and only if that matches the type of file handled by the application, in which case the clipboard would be a better place to store it.

Me too… I implemented this feature too, from scratch. As a user, I find it useful. Of course, the file type must be checked and if the file has been deleted/moved to a different location, it is a good idea to remove the menu item with it. Alternatively, there is a list of favorite files that are entered by the user explicitly. If I work with files saved in many different folders, I find using the file manager or Open file dialog less efficient.

Just for better understanding, my own programming experience relates to a Recent files list displayed by a particular application in the menu, which works autonomously and without using any special APIs. The idea to collect data about all used files in one place and to make it to the central point in a system-wide control mechanism (what Recent files API does, if I see it right) is in fact surprising. I think it is necessary to distinguish between user experience (presumed or empirically determined) and a particular implementation.

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