[gtk+] Fix popover life-cycle handling



commit b01229db4b1b4c0d0ea29f55be575da7dd57fda0
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Feb 21 22:08:00 2014 -0500

    Fix popover life-cycle handling
    
    c28784524016b2a8eac18d5046ebc8cdaca7f9b0 was trying to fix
    the memory leak caused by popovers begin destroyed in
    gtk_window_destroy before chaining up to gtk_widget_destroy,
    which unrealizes the window, and would clean up the popover
    windows if the popovers were still around.
    
    Fix this in a better way by moving the popover destruction
    after the chaining up, so we unrealize first, and then
    destroy the popovers.
    
    Also, make _gtk_window_remove_popover unrealize the popover,
    for symmetry with _gtk_window_add_popover.
    
    This should fix
    https://bugzilla.gnome.org/show_bug.cgi?id=724921

 gtk/gtkwindow.c |   37 ++++++++++++++-----------------------
 1 files changed, 14 insertions(+), 23 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index befca5a..d34e24c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1338,18 +1338,8 @@ popover_destroy (GtkWindowPopover *popover)
       popover->unmap_id = 0;
     }
 
-  if (popover->widget)
-    {
-      GtkWidget *parent;
-
-      parent = gtk_widget_get_parent (popover->widget);
-
-      if (parent)
-        {
-          gtk_widget_unregister_window (parent, popover->window);
-          gtk_widget_unparent (popover->widget);
-        }
-    }
+  if (popover->widget && gtk_widget_get_parent (popover->widget))
+    gtk_widget_unparent (popover->widget);
 
   if (popover->window)
     gdk_window_destroy (popover->window);
@@ -2679,21 +2669,20 @@ gtk_window_dispose (GObject *object)
   GtkWindow *window = GTK_WINDOW (object);
   GtkWindowPrivate *priv = window->priv;
 
-  while (priv->popovers)
-    {
-      GtkWindowPopover *popover;
-
-      popover = priv->popovers->data;
-      priv->popovers = g_list_delete_link (priv->popovers, priv->popovers);
-      popover_destroy (popover);
-    }
-
   gtk_window_set_focus (window, NULL);
   gtk_window_set_default (window, NULL);
   unset_titlebar (window);
   remove_attach_widget (window);
 
   G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
+
+  while (priv->popovers)
+    {
+      GtkWindowPopover *popover = priv->popovers->data;
+      priv->popovers = g_list_delete_link (priv->popovers, priv->popovers);
+      popover_destroy (popover);
+    }
+
 }
 
 static void
@@ -5987,8 +5976,7 @@ popover_realize (GtkWidget        *widget,
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   parent_window = gtk_widget_get_window (GTK_WIDGET (window));
-  popover->window =
-    gdk_window_new (parent_window, &attributes, attributes_mask);
+  popover->window = gdk_window_new (parent_window, &attributes, attributes_mask);
   gtk_widget_register_window (GTK_WIDGET (window), popover->window);
 
   gtk_widget_set_parent_window (popover->widget, popover->window);
@@ -12212,6 +12200,9 @@ _gtk_window_remove_popover (GtkWindow *window,
   if (!data)
     return;
 
+  if (gtk_widget_get_realized (GTK_WIDGET (window)))
+    popover_unrealize (popover, data, window);
+
   priv->popovers = g_list_remove (priv->popovers, data);
   popover_destroy (data);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]