[gnome-software/wip/kalev/tile-idle-source] feature/popular/summary tile: Rework idle source removal



commit 60d940d89ab776efeddda057cca6baa135461195
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 0a397d64..9d81e502 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.14')
 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 795bb7a2..9ef9a4cb 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -38,6 +38,7 @@ struct _GsPopularTile
        GtkWidget       *eventbox;
        GtkWidget       *stack;
        GtkWidget       *stars;
+       guint            app_state_changed_id;
 };
 
 G_DEFINE_TYPE (GsPopularTile, gs_popular_tile, GS_TYPE_APP_TILE)
@@ -56,6 +57,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)) {
@@ -83,14 +86,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
@@ -101,8 +104,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)
@@ -145,9 +149,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]