[gnome-software/gnome-3-30] feature/popular/summary tile: Rework idle source removal



commit 83fdb4271248a194de2d09c7e2fd81ec6fa0f851
Author: Kalev Lember <klember redhat com>
Date:   Wed Oct 17 09:46:03 2018 +0200

    feature/popular/summary tile: Rework idle source removal
    
    When setting up an idle source, save the returned id so that we can
    remove the idle source in destroy() and when changing the GsApp that the
    tile shows.
    
    This fixes tile->app NULL critical warnings when quickly switching
    between categories and a resource leak when the idle fires after
    destroy().
    
    Also, this bumps the glib dep to 2.56.0 for g_clear_handle_id.

 meson.build           |  2 +-
 src/gs-feature-tile.c | 14 +++++++-------
 src/gs-popular-tile.c | 14 +++++++++-----
 src/gs-summary-tile.c | 15 ++++++++-------
 4 files changed, 25 insertions(+), 20 deletions(-)
---
diff --git a/meson.build b/meson.build
index cc8b91dc..7f240f2e 100644
--- a/meson.build
+++ b/meson.build
@@ -98,7 +98,7 @@ conf.set('HAVE_LINUX_UNISTD_H', cc.has_header('linux/unistd.h'))
 
 appstream_glib = dependency('appstream-glib', version : '>= 0.7.3')
 gdk_pixbuf = dependency('gdk-pixbuf-2.0', version : '>= 2.32.0')
-gio_unix = dependency('gio-unix-2.0')
+gio_unix = dependency('gio-unix-2.0', version : '>= 2.56.0')
 gmodule = dependency('gmodule-2.0')
 gtk = dependency('gtk+-3.0', version : '>= 3.22.4')
 json_glib = dependency('json-glib-1.0', version : '>= 1.2.0')
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
index db5983a6..2cf74d96 100644
--- a/src/gs-feature-tile.c
+++ b/src/gs-feature-tile.c
@@ -36,6 +36,7 @@ struct _GsFeatureTile
        GtkWidget       *stack;
        GtkWidget       *title;
        GtkWidget       *subtitle;
+       guint            app_state_changed_id;
 };
 
 G_DEFINE_TYPE (GsFeatureTile, gs_feature_tile, GS_TYPE_APP_TILE)
@@ -55,9 +56,7 @@ app_state_changed_idle (gpointer user_data)
        g_autofree gchar *name = NULL;
        g_autoptr(GsCss) css = NULL;
 
-       /* nothing set yet */
-       if (tile->app == NULL)
-               return G_SOURCE_REMOVE;
+       tile->app_state_changed_id = 0;
 
        /* update text */
        gtk_label_set_label (GTK_LABEL (tile->title), gs_app_get_name (tile->app));
@@ -98,14 +97,14 @@ app_state_changed_idle (gpointer user_data)
                atk_object_set_description (accessible, gs_app_get_summary (tile->app));
        }
 
-       g_object_unref (tile);
        return G_SOURCE_REMOVE;
 }
 
 static void
 app_state_changed (GsApp *app, GParamSpec *pspec, GsFeatureTile *tile)
 {
-       g_idle_add (app_state_changed_idle, g_object_ref (tile));
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
+       tile->app_state_changed_id = g_idle_add (app_state_changed_idle, tile);
 }
 
 static void
@@ -118,6 +117,7 @@ gs_feature_tile_set_app (GsAppTile *app_tile, GsApp *app)
 
        if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
 
        g_set_object (&tile->app, app);
        if (app == NULL)
@@ -139,9 +139,9 @@ gs_feature_tile_destroy (GtkWidget *widget)
 {
        GsFeatureTile *tile = GS_FEATURE_TILE (widget);
 
-       if (tile->app)
+       if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
-
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
        g_clear_object (&tile->app);
 
        GTK_WIDGET_CLASS (gs_feature_tile_parent_class)->destroy (widget);
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index 4c998fe5..39141e5a 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -39,6 +39,7 @@ struct _GsPopularTile
        GtkWidget       *stack;
        GtkWidget       *stars;
        GtkWidget       *label_origin;
+       guint            app_state_changed_id;
 };
 
 G_DEFINE_TYPE (GsPopularTile, gs_popular_tile, GS_TYPE_APP_TILE)
@@ -57,6 +58,8 @@ app_state_changed_idle (gpointer user_data)
        gboolean installed;
        g_autofree gchar *name = NULL;
 
+       tile->app_state_changed_id = 0;
+
        accessible = gtk_widget_get_accessible (GTK_WIDGET (tile));
 
        switch (gs_app_get_state (tile->app)) {
@@ -84,14 +87,14 @@ app_state_changed_idle (gpointer user_data)
                atk_object_set_description (accessible, gs_app_get_summary (tile->app));
        }
 
-       g_object_unref (tile);
        return G_SOURCE_REMOVE;
 }
 
 static void
 app_state_changed (GsApp *app, GParamSpec *pspec, GsPopularTile *tile)
 {
-       g_idle_add (app_state_changed_idle, g_object_ref (tile));
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
+       tile->app_state_changed_id = g_idle_add (app_state_changed_idle, tile);
 }
 
 static void
@@ -102,8 +105,9 @@ gs_popular_tile_set_app (GsAppTile *app_tile, GsApp *app)
 
        g_return_if_fail (GS_IS_APP (app) || app == NULL);
 
-       if (tile->app)
+       if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
 
        g_set_object (&tile->app, app);
        if (!app)
@@ -146,9 +150,9 @@ gs_popular_tile_destroy (GtkWidget *widget)
 {
        GsPopularTile *tile = GS_POPULAR_TILE (widget);
 
-       if (tile->app)
+       if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
-
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
        g_clear_object (&tile->app);
 
        GTK_WIDGET_CLASS (gs_popular_tile_parent_class)->destroy (widget);
diff --git a/src/gs-summary-tile.c b/src/gs-summary-tile.c
index 050bb54d..790a1c31 100644
--- a/src/gs-summary-tile.c
+++ b/src/gs-summary-tile.c
@@ -37,6 +37,7 @@ struct _GsSummaryTile
        GtkWidget       *summary;
        GtkWidget       *eventbox;
        GtkWidget       *stack;
+       guint            app_state_changed_id;
        gint             preferred_width;
 };
 
@@ -61,9 +62,7 @@ app_state_changed_idle (gpointer user_data)
        gboolean installed;
        g_autofree gchar *name = NULL;
 
-       /* nothing set yet */
-       if (tile->app == NULL)
-               return G_SOURCE_REMOVE;
+       tile->app_state_changed_id = 0;
 
        accessible = gtk_widget_get_accessible (GTK_WIDGET (tile));
 
@@ -100,14 +99,14 @@ app_state_changed_idle (gpointer user_data)
                atk_object_set_description (accessible, gs_app_get_summary (tile->app));
        }
 
-       g_object_unref (tile);
        return G_SOURCE_REMOVE;
 }
 
 static void
 app_state_changed (GsApp *app, GParamSpec *pspec, GsSummaryTile *tile)
 {
-       g_idle_add (app_state_changed_idle, g_object_ref (tile));
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
+       tile->app_state_changed_id = g_idle_add (app_state_changed_idle, tile);
 }
 
 static void
@@ -123,8 +122,9 @@ gs_summary_tile_set_app (GsAppTile *app_tile, GsApp *app)
        gtk_image_clear (GTK_IMAGE (tile->image));
        gtk_image_set_pixel_size (GTK_IMAGE (tile->image), 64);
 
-       if (tile->app)
+       if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
 
        g_set_object (&tile->app, app);
        if (!app)
@@ -174,8 +174,9 @@ gs_summary_tile_destroy (GtkWidget *widget)
 {
        GsSummaryTile *tile = GS_SUMMARY_TILE (widget);
 
-       if (tile->app)
+       if (tile->app != NULL)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
+       g_clear_handle_id (&tile->app_state_changed_id, g_source_remove);
        g_clear_object (&tile->app);
 
        GTK_WIDGET_CLASS (gs_summary_tile_parent_class)->destroy (widget);


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