aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-individual-store.c57
-rw-r--r--libempathy-gtk/empathy-ui-utils.c7
-rw-r--r--libempathy-gtk/empathy-ui-utils.h3
3 files changed, 54 insertions, 13 deletions
diff --git a/libempathy-gtk/empathy-individual-store.c b/libempathy-gtk/empathy-individual-store.c
index 161787299..26b56954e 100644
--- a/libempathy-gtk/empathy-individual-store.c
+++ b/libempathy-gtk/empathy-individual-store.c
@@ -71,6 +71,8 @@ typedef struct
guint setup_idle_id;
gboolean dispose_has_run;
GHashTable *status_icons;
+ /* List of owned GCancellables for each pending avatar load operation */
+ GList *avatar_cancellables;
} EmpathyIndividualStorePriv;
typedef struct
@@ -552,13 +554,16 @@ individual_store_contact_active_cb (ShowActiveData *data)
return FALSE;
}
+typedef struct {
+ EmpathyIndividualStore *store; /* weak */
+ GCancellable *cancellable; /* owned */
+} LoadAvatarData;
+
static void
-individual_avatar_pixbuf_received_cb (GObject *object,
+individual_avatar_pixbuf_received_cb (FolksIndividual *individual,
GAsyncResult *result,
- gpointer user_data)
+ LoadAvatarData *data)
{
- FolksIndividual *individual = FOLKS_INDIVIDUAL (object);
- EmpathyIndividualStore *self = user_data;
GError *error = NULL;
GdkPixbuf *pixbuf;
@@ -572,18 +577,32 @@ individual_avatar_pixbuf_received_cb (GObject *object,
error->message);
g_clear_error (&error);
}
- else
+ else if (data->store != NULL)
{
GList *iters, *l;
- iters = individual_store_find_contact (self, individual);
+ iters = individual_store_find_contact (data->store, individual);
for (l = iters; l; l = l->next)
{
- gtk_tree_store_set (GTK_TREE_STORE (self), l->data,
+ gtk_tree_store_set (GTK_TREE_STORE (data->store), l->data,
EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR, pixbuf,
-1);
}
}
+
+ /* Free things */
+ if (data->store != NULL)
+ {
+ EmpathyIndividualStorePriv *priv = GET_PRIV (data->store);
+
+ g_object_remove_weak_pointer (G_OBJECT (data->store),
+ (gpointer *) &data->store);
+ priv->avatar_cancellables = g_list_remove (priv->avatar_cancellables,
+ data->cancellable);
+ }
+
+ g_object_unref (data->cancellable);
+ g_slice_free (LoadAvatarData, data);
}
static void
@@ -604,6 +623,7 @@ individual_store_contact_update (EmpathyIndividualStore *self,
gboolean do_set_refresh = FALSE;
gboolean show_avatar = FALSE;
GdkPixbuf *pixbuf_status;
+ LoadAvatarData *load_avatar_data;
priv = GET_PRIV (self);
@@ -678,8 +698,19 @@ individual_store_contact_update (EmpathyIndividualStore *self,
show_avatar = TRUE;
}
- empathy_pixbuf_avatar_from_individual_scaled_async (individual,
- individual_avatar_pixbuf_received_cb, 32, 32, self);
+ /* Load the avatar asynchronously */
+ load_avatar_data = g_slice_new (LoadAvatarData);
+ load_avatar_data->store = self;
+ g_object_add_weak_pointer (G_OBJECT (self),
+ (gpointer *) &load_avatar_data->store);
+ load_avatar_data->cancellable = g_cancellable_new ();
+
+ priv->avatar_cancellables = g_list_prepend (priv->avatar_cancellables,
+ load_avatar_data->cancellable);
+ empathy_pixbuf_avatar_from_individual_scaled_async (individual, 32, 32,
+ load_avatar_data->cancellable,
+ (GAsyncReadyCallback) individual_avatar_pixbuf_received_cb,
+ load_avatar_data);
pixbuf_status =
empathy_individual_store_get_individual_status_icon (self, individual);
@@ -957,6 +988,14 @@ individual_store_dispose (GObject *object)
return;
priv->dispose_has_run = TRUE;
+ /* Cancel any pending avatar load operations */
+ for (l = priv->avatar_cancellables; l != NULL; l = l->next)
+ {
+ /* The cancellables are freed in individual_avatar_pixbuf_received_cb() */
+ g_cancellable_cancel (G_CANCELLABLE (l->data));
+ }
+ g_list_free (priv->avatar_cancellables);
+
contacts = empathy_individual_manager_get_members (priv->manager);
for (l = contacts; l; l = l->next)
{
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c
index 46a26d8f7..0a2d4f4f4 100644
--- a/libempathy-gtk/empathy-ui-utils.c
+++ b/libempathy-gtk/empathy-ui-utils.c
@@ -564,7 +564,7 @@ avatar_file_load_contents_cb (GObject *object,
{
GFile *file = G_FILE (object);
PixbufAvatarFromIndividualClosure *closure = user_data;
- char *data;
+ char *data = NULL;
gsize data_size;
struct SizeData size_data;
GError *error = NULL;
@@ -617,9 +617,10 @@ out:
void
empathy_pixbuf_avatar_from_individual_scaled_async (
FolksIndividual *individual,
- GAsyncReadyCallback callback,
gint width,
gint height,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
gpointer user_data)
{
GFile *avatar_file;
@@ -639,7 +640,7 @@ empathy_pixbuf_avatar_from_individual_scaled_async (
if (closure == NULL)
goto out;
- g_file_load_contents_async (avatar_file, NULL,
+ g_file_load_contents_async (avatar_file, cancellable,
avatar_file_load_contents_cb, closure);
g_object_unref (result);
diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h
index 9c3ec6517..0b76d09a3 100644
--- a/libempathy-gtk/empathy-ui-utils.h
+++ b/libempathy-gtk/empathy-ui-utils.h
@@ -77,9 +77,10 @@ GdkPixbuf * empathy_pixbuf_from_data_and_mime (gchar *data,
gsize data_size,
gchar **mime_type);
void empathy_pixbuf_avatar_from_individual_scaled_async (FolksIndividual *individual,
- GAsyncReadyCallback callback,
gint width,
gint height,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
gpointer user_data);
GdkPixbuf * empathy_pixbuf_avatar_from_individual_scaled_finish (
FolksIndividual *individual,