[empathy] Ensure we disconnect from signals on Individuals' Personas as they're removed



commit 019365d216471676ddc3c878219e1685874c3d7e
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Thu Sep 2 10:58:41 2010 +0100

    Ensure we disconnect from signals on Individuals' Personas as they're removed
    
    EmpathyIndividualStore connects to some signals on all of the (Telepathy)
    Personas in each Individual it stores. If an Individual changes its set of
    Personas, some of those signals might end up never getting disconnected. This
    fixes that by listening to FolksIndividual::personas-changed and disconnecting
    signals as appropriate. Closes: bgo#628153

 libempathy-gtk/empathy-individual-store.c |   82 +++++++++++++++++------------
 1 files changed, 48 insertions(+), 34 deletions(-)
---
diff --git a/libempathy-gtk/empathy-individual-store.c b/libempathy-gtk/empathy-individual-store.c
index e72b7ec..985b6e3 100644
--- a/libempathy-gtk/empathy-individual-store.c
+++ b/libempathy-gtk/empathy-individual-store.c
@@ -819,24 +819,19 @@ individual_store_contact_updated_cb (EmpathyContact *contact,
 }
 
 static void
-individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
-    FolksIndividual *individual)
+individual_personas_changed_cb (FolksIndividual *individual,
+    GList *added,
+    GList *removed,
+    EmpathyIndividualStore *self)
 {
-  GList *personas, *l;
+  GList *l;
 
-  g_signal_connect (individual, "notify::avatar",
-      G_CALLBACK (individual_store_individual_updated_cb), self);
-  g_signal_connect (individual, "notify::presence-type",
-      G_CALLBACK (individual_store_individual_updated_cb), self);
-  g_signal_connect (individual, "notify::presence-message",
-      G_CALLBACK (individual_store_individual_updated_cb), self);
-  g_signal_connect (individual, "notify::alias",
-      G_CALLBACK (individual_store_individual_updated_cb), self);
+  DEBUG ("Individual '%s' personas-changed.",
+      folks_individual_get_id (individual));
 
   /* FIXME: libfolks hasn't grown capabilities support yet, so we have to go
    * through the EmpathyContacts for them. */
-  personas = folks_individual_get_personas (individual);
-  for (l = personas; l != NULL; l = l->next)
+  for (l = removed; l != NULL; l = l->next)
     {
       TpContact *tp_contact;
       EmpathyContact *contact;
@@ -848,29 +843,14 @@ individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
       contact = empathy_contact_dup_from_tp_contact (tp_contact);
       empathy_contact_set_persona (contact, FOLKS_PERSONA (l->data));
 
-      g_object_set_data (G_OBJECT (contact), "individual", individual);
-      g_signal_connect (contact, "notify::capabilities",
-          G_CALLBACK (individual_store_contact_updated_cb), self);
+      g_object_set_data (G_OBJECT (contact), "individual", NULL);
+      g_signal_handlers_disconnect_by_func (contact,
+          (GCallback) individual_store_contact_updated_cb, self);
 
       g_object_unref (contact);
     }
 
-  individual_store_add_individual (self, individual);
-}
-
-static void
-individual_store_disconnect_individual (EmpathyIndividualStore *self,
-    FolksIndividual *individual)
-{
-  GList *personas, *l;
-
-  g_signal_handlers_disconnect_by_func (individual,
-      G_CALLBACK (individual_store_individual_updated_cb), self);
-
-  /* FIXME: libfolks hasn't grown capabilities support yet, so we have to go
-   * through the EmpathyContacts for them. */
-  personas = folks_individual_get_personas (individual);
-  for (l = personas; l != NULL; l = l->next)
+  for (l = added; l != NULL; l = l->next)
     {
       TpContact *tp_contact;
       EmpathyContact *contact;
@@ -882,14 +862,48 @@ individual_store_disconnect_individual (EmpathyIndividualStore *self,
       contact = empathy_contact_dup_from_tp_contact (tp_contact);
       empathy_contact_set_persona (contact, FOLKS_PERSONA (l->data));
 
-      g_signal_handlers_disconnect_by_func (contact,
-          G_CALLBACK (individual_store_contact_updated_cb), self);
+      g_object_set_data (G_OBJECT (contact), "individual", individual);
+      g_signal_connect (contact, "notify::capabilities",
+          (GCallback) individual_store_contact_updated_cb, self);
 
       g_object_unref (contact);
     }
 }
 
 static void
+individual_store_add_individual_and_connect (EmpathyIndividualStore *self,
+    FolksIndividual *individual)
+{
+  g_signal_connect (individual, "notify::avatar",
+      (GCallback) individual_store_individual_updated_cb, self);
+  g_signal_connect (individual, "notify::presence-type",
+      (GCallback) individual_store_individual_updated_cb, self);
+  g_signal_connect (individual, "notify::presence-message",
+      (GCallback) individual_store_individual_updated_cb, self);
+  g_signal_connect (individual, "notify::alias",
+      (GCallback) individual_store_individual_updated_cb, self);
+  g_signal_connect (individual, "personas-changed",
+      (GCallback) individual_personas_changed_cb, self);
+
+  individual_personas_changed_cb (individual,
+      folks_individual_get_personas (individual), NULL, self);
+  individual_store_add_individual (self, individual);
+}
+
+static void
+individual_store_disconnect_individual (EmpathyIndividualStore *self,
+    FolksIndividual *individual)
+{
+  individual_personas_changed_cb (individual, NULL,
+      folks_individual_get_personas (individual), self);
+
+  g_signal_handlers_disconnect_by_func (individual,
+      (GCallback) individual_store_individual_updated_cb, self);
+  g_signal_handlers_disconnect_by_func (individual,
+      (GCallback) individual_personas_changed_cb, self);
+}
+
+static void
 individual_store_remove_individual_and_disconnect (
     EmpathyIndividualStore *self,
     FolksIndividual *individual)



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