Adding a context menu to a ListView using gtk4-rs

I have a ListView, and I’d like to add a right-click context menu to it. What’d be the easiest way to do so in gtk4-rs?

My best strategy so far feels a bit convoluted:

  • Add a GestureClick event controller to the ListView and respond to BUTTON_SECONDARY
  • Find some way to get the currently selected item from the ListView (not sure how to do that yet)
  • Implement a PopoverMenu
  • Find some way to trigger this menu at the correct position (not sure how to do that yet, especially since allocation is deprecated)

I found this post explaining one possible way to do it in C. Unfortunately I can’t easily translate this to my situation, plus the poster wasn’t sure it was the correct way to do it.

Since context menus have been around for decades and Gtk has too, I’m probably overlooking a more obvious solution.

Do you want the context menu to appear when the list (without any items in that location) is clicked? When an item is clicked? Or both?

If it is both, the simplest way is to implement a Gtk.GestureClick for the list, and another for the items, both using the same menu.

The items’ Gtk.GestureClick can be created directly in the item’s setup function (if you are using Gtk.SignalListItemFactory) and point to a callback of the widget itself built in the setup to call the popmenu.

If you are using Gtk.SingleSelection or Gtk.MultiSelection as the selection type in the list, just use their get_selected_item() function to find the selected item.

To activate the menu in the correct position, use the menu’s set_offset(x, y) function, where the x, y is the return from Gtk.GestureClick. This will adjust the coordinates for the item’s position in the list. Then, use the set_pointing_to(Gdk.Rectangle(x, y, 1, 1)) menu function to create the anchor point.

Ps: sorry for not giving an example with code, I’m not a Rust programmer.

1 Like

Only when an item is clicked, so I’ll only be needing a GestureClick for the items then.

No worries if you’re not a Rust programmer, I’m glad you want to help.

Regarding using get_selected_item(): I see that the gtk.org documentation of SingleSelection publicizes a gtk_single_selection_get_selected function, but MultiSelection doesn’t seem to have an equivalent of that. The situation is similar in the Rust bindings. Am I overlooking something?

With a MultiSelection, use SelectionModelExt::selection() to get a bitmap of all the selected indices.

1 Like

Ahh yes, and then I suppose I could use BitsetIter to access the values in the Bitset returned by SelectionModelExt::selection(). Thanks both for your help!

Sorry to be a bit late seeing this, but you can find an example in my code here, using ColumnView. kelpie-flight-planner/src/window/airport_view.rs at main · shartrec/kelpie-flight-planner · GitHub

1 Like

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