[gnome-software/gnome-3-12] GsApp: Notify property changes in an idle callback



commit ad521c016c5db471089dbe3469fcc0db526a3cc4
Author: Kalev Lember <kalevlember gmail com>
Date:   Tue Apr 8 13:34:21 2014 +0200

    GsApp: Notify property changes in an idle callback
    
    This makes sure the notify:: callbacks in the UI code get invoked in the
    main thread. Without doing so, we can end up calling gtk+ functions from
    the plugin thread in response to GsApp property changes.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1082833
    
    https://bugzilla.gnome.org/show_bug.cgi?id=727823

 src/gs-app.c |   48 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 41 insertions(+), 7 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index deeae0b..d3458e4 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -332,6 +332,40 @@ gs_app_to_string (GsApp *app)
        return g_string_free (str, FALSE);
 }
 
+typedef struct {
+       GsApp *app;
+       gchar *property_name;
+} AppNotifyData;
+
+static gboolean
+notify_idle_cb (gpointer data)
+{
+       AppNotifyData *notify_data = data;
+
+       g_object_notify (G_OBJECT (notify_data->app),
+                        notify_data->property_name);
+
+       g_object_unref (notify_data->app);
+       g_free (notify_data->property_name);
+       g_free (notify_data);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void
+gs_app_queue_notify (GsApp *app, const gchar *property_name)
+{
+       AppNotifyData *notify_data;
+       guint id;
+
+       notify_data = g_new (AppNotifyData, 1);
+       notify_data->app = g_object_ref (app);
+       notify_data->property_name = g_strdup (property_name);
+
+       id = g_idle_add (notify_idle_cb, notify_data);
+       g_source_set_name_by_id (id, "[gnome-software] notify_idle_cb");
+}
+
 /**
  * gs_app_get_id:
  **/
@@ -507,7 +541,7 @@ void
 gs_app_set_state (GsApp *app, GsAppState state)
 {
        if (gs_app_set_state_internal (app, state))
-               g_object_notify (G_OBJECT (app), "state");
+               gs_app_queue_notify (app, "state");
 }
 
 /**
@@ -583,7 +617,7 @@ gs_app_set_kind (GsApp *app, GsAppKind kind)
        }
 
        priv->kind = kind;
-       g_object_notify (G_OBJECT (app), "kind");
+       gs_app_queue_notify (app, "kind");
 }
 
 /**
@@ -962,7 +996,7 @@ gs_app_ui_versions_populate (GsApp *app)
                priv->version_ui = gs_app_get_ui_version (priv->version, flags[i]);
                priv->update_version_ui = gs_app_get_ui_version (priv->update_version, flags[i]);
                if (g_strcmp0 (priv->version_ui, priv->update_version_ui) != 0) {
-                       g_object_notify (G_OBJECT (app), "version");
+                       gs_app_queue_notify (app, "version");
                        return;
                }
                gs_app_ui_versions_invalidate (app);
@@ -1015,7 +1049,7 @@ gs_app_set_version (GsApp *app, const gchar *version)
        g_free (app->priv->version);
        app->priv->version = g_strdup (version);
        gs_app_ui_versions_invalidate (app);
-       g_object_notify (G_OBJECT (app), "version");
+       gs_app_queue_notify (app, "version");
 }
 
 /**
@@ -1255,7 +1289,7 @@ gs_app_set_update_version (GsApp *app, const gchar *update_version)
 {
        g_return_if_fail (GS_IS_APP (app));
        gs_app_set_update_version_internal (app, update_version);
-       g_object_notify (G_OBJECT (app), "version");
+       gs_app_queue_notify (app, "version");
 }
 
 /**
@@ -1321,7 +1355,7 @@ gs_app_set_rating (GsApp *app, gint rating)
 {
        g_return_if_fail (GS_IS_APP (app));
        app->priv->rating = rating;
-       g_object_notify (G_OBJECT (app), "rating");
+       gs_app_queue_notify (app, "rating");
 }
 
 /**
@@ -1373,7 +1407,7 @@ gs_app_set_rating_kind (GsApp *app, GsAppRatingKind rating_kind)
 {
        g_return_if_fail (GS_IS_APP (app));
        app->priv->rating_kind = rating_kind;
-       g_object_notify (G_OBJECT (app), "rating");
+       gs_app_queue_notify (app, "rating");
 }
 
 /**


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