changeset 2300:6e47d510dbbb

GTK4: Since GTK4 needs to add the popup menu to the parent widget... We need to remove it after the popup closes, so we trap the "close" signal and try to remove the popup from the parent. Since the "close" signal gets called before the menu's "activate" signal, we have to delay unparenting until after the "activate" signal handler is run. Otherwise the menu objects won't be valid for the "activate" handler, therefore we add an idle callback to unparent the widget when the rest of the processing is done.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 08 Feb 2021 10:49:50 +0000
parents 27c20fa1615e
children 69b06073a87d
files gtk4/dw.c
diffstat 1 files changed, 24 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/gtk4/dw.c	Mon Feb 08 09:53:37 2021 +0000
+++ b/gtk4/dw.c	Mon Feb 08 10:49:50 2021 +0000
@@ -2545,6 +2545,26 @@
    return ret;
 }
 
+/* Delayed unparent of the popup menu from the parent */
+gboolean _dw_idle_popover_unparent(gpointer data)
+{
+   GtkWidget *self = GTK_WIDGET(data);
+
+   gtk_widget_unparent(self);
+   return false;
+}
+
+void _dw_popover_menu_closed(GtkPopover *self, gpointer data)
+{
+   GtkWidget *parent = GTK_WIDGET(data);
+   
+   /* Can't unparent immediately, since the "activate" signal happens second...
+    * so we have to delay unparenting until the "activate" handler runs.
+    */
+   if(GTK_IS_WIDGET(parent) && GTK_IS_POPOVER(self))
+      g_idle_add(G_SOURCE_FUNC(_dw_idle_popover_unparent), (gpointer)self);
+}
+
 /*
  * Pops up a context menu at given x and y coordinates.
  * Parameters:
@@ -2561,8 +2581,11 @@
       
       gtk_widget_set_parent(tmp, GTK_WIDGET(parent));
       _dw_menu_set_group_recursive(*menu, GTK_WIDGET(tmp));
+      gtk_popover_set_autohide(GTK_POPOVER(tmp), TRUE);
+#if 0      
       gtk_popover_set_offset(GTK_POPOVER(tmp), x, y);
-      gtk_popover_set_autohide(GTK_POPOVER(tmp), TRUE);
+#endif      
+      g_signal_connect(G_OBJECT(tmp), "closed", G_CALLBACK(_dw_popover_menu_closed), (gpointer)parent);
       gtk_popover_popup(GTK_POPOVER(tmp));
       *menu = NULL;
    }