]> git.0d.be Git - empathy.git/commitdiff
Ensure we disconnect from signals on Individuals' Personas as they're removed
authorPhilip Withnall <philip.withnall@collabora.co.uk>
Thu, 2 Sep 2010 09:58:41 +0000 (10:58 +0100)
committerPhilip Withnall <philip.withnall@collabora.co.uk>
Thu, 2 Sep 2010 15:13:29 +0000 (16:13 +0100)
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

index e72b7ec9e6516df12ec217ebcc9b88137447bf4f..985b6e317feb877ba13a6b93169e70ef5a5ab85f 100644 (file)
@@ -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,13 +862,47 @@ 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,