[gnome-software/wip/kalev/app-row-unreveal-crash] gs-updates-section.c: destroy() rows rather than just removing



commit 8bc1dfbb8f71138d132456f6842abc02147bfa4a
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Oct 13 12:14:34 2020 -0400

    gs-updates-section.c: destroy() rows rather than just removing
    
    It's generally good practice to use gtk_widget_destroy() if you know
    you'll never use a widget again, but in particular this makes the
    fix for https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1016, since
    otherwise the app row would be be removed before priv->app was cleared.

 src/gs-app-row.c         | 5 ++++-
 src/gs-updates-section.c | 7 +++++--
 2 files changed, 9 insertions(+), 3 deletions(-)
---
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index 36acd206..a00dfb03 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -467,7 +467,10 @@ child_unrevealed (GObject *revealer, GParamSpec *pspec, gpointer user_data)
        GsAppRow *app_row = user_data;
        GsAppRowPrivate *priv = gs_app_row_get_instance_private (app_row);
 
-       /* return immediately if we are in destruction */
+       /* return immediately if we are in destruction (this doesn't, however,
+        * catch the case where we are being removed from a container without
+        * having been destroyed first.)
+        */
        if (priv->app == NULL)
                return;
 
diff --git a/src/gs-updates-section.c b/src/gs-updates-section.c
index efab7d60..24bb419d 100644
--- a/src/gs-updates-section.c
+++ b/src/gs-updates-section.c
@@ -66,7 +66,7 @@ _row_unrevealed_cb (GObject *row, GParamSpec *pspec, gpointer data)
        list = gtk_widget_get_parent (GTK_WIDGET (row));
        if (list == NULL)
                return;
-       gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (row));
+       gtk_widget_destroy (GTK_WIDGET (row));
 }
 
 static void
@@ -117,7 +117,10 @@ gs_updates_section_remove_all (GsUpdatesSection *self)
        children = gtk_container_get_children (GTK_CONTAINER (self));
        for (GList *l = children; l != NULL; l = l->next) {
                GtkWidget *w = GTK_WIDGET (l->data);
-               gtk_container_remove (GTK_CONTAINER (self), w);
+               /* Destroying, rather than just removing, prevents the ::unrevealed
+                * signal from being emitted, which would cause unfortunate reentrancy.
+                */
+               gtk_widget_destroy (w);
        }
        gs_app_list_remove_all (self->list);
        gtk_widget_hide (GTK_WIDGET (self));


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