Gtk popup menu position and destroy

i’m create a popup menu with gtk_menu_popup,

how could i get the offset of content area relative to window top left corner ? the gtk_widget_get_allocation api returns (0,0) with GtkWindow instead of (0, titlebarHeight),
or is there any way to translate position in widget to position in screen?

when should i destroy the menu with gtk_widget_destroy? when i select a menu item, the activate signal of menu item is emitted after unmap signal of popup menu, so i couldn’t destroy the menu in unmap event.

Don’t.

Please use one of these functions:

The latter two are generally the appropriate functions to cover 90% of the cases in a typical GTK application.

The gtk_menu_popup() function has been deprecated and should not be used in newly written code.

You can’t do this portably on all windowing systems, so don’t ever do it. We introduced new API precisely to deal with the fact that you should never provide global coordinates for your menu.

but these new apis is available since 3.22, i want my application to be compatible with old linux distributions.

How old is “old”? GTK 3.24 was released in September 2018. In general, it’s pointless to support older versions of GTK 3. If you need to support older Linux distributions, you should consider tools like Flatpak or Snap.

ok, thank you. any suggestion on my second problem?

You don’t destroy menus explicitly: they get destroyed when they are closed.

If you want to keep around a pointer to the menu, in order to see if one is already open, you can use gtk_menu_attach_to_widget() to attach the menu to a widget, and receive a notification when the menu is detached; in that notification function you can nullify the pointer to the menu you are keeping.

For instance, if you want to pop up a menu on a right button press:

static GtkWidget *popup_menu;

static void
popup_detached (GtkWidget *attach_widget, GtkMenu *menu)
{
  popup_menu = NULL;
}

static gboolean
on_button_press (GtkWidget *widget, GdkEvent *event, gpointer data)
{
  // we only care about right click button presses
  if (gdk_event_get_button (event) != GDK_BUTTON_SECONDARY ||
      gdk_event_get_event_type (event) != GDK_BUTTON_PRESS)
    return GDK_EVENT_PROPAGATE;

  // a popup menu is still lying around; destroy it
  if (popup_menu != NULL)
    gtk_widget_destroy (popup_menu);

  // create_context_menu() is defined elsewhere
  popup_menu = create_context_menu ();

  gtk_menu_attach_to_widget (GTK_MENU (popup_menu), widget, popup_detached);
  gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), event);

  return GDK_EVENT_PROPAGATE;
}
1 Like

i got it, thank you so much.

gtk 3.22.30 is available in RHEL7 for example.

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