aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Withnall <philip.withnall@collabora.co.uk>2010-09-02 17:58:41 +0800
committerPhilip Withnall <philip.withnall@collabora.co.uk>2010-09-02 23:13:29 +0800
commit019365d216471676ddc3c878219e1685874c3d7e (patch)
tree3510bef8abb9c28a230470c4cf71b7a4875301a1
parent8605cf086f2509d751beb4290921327bc409dde8 (diff)
downloadgsoc2013-empathy-019365d216471676ddc3c878219e1685874c3d7e.tar.gz
gsoc2013-empathy-019365d216471676ddc3c878219e1685874c3d7e.tar.zst
gsoc2013-empathy-019365d216471676ddc3c878219e1685874c3d7e.zip
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
-rw-r--r--libempathy-gtk/empathy-individual-store.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/libempathy-gtk/empathy-individual-store.c b/libempathy-gtk/empathy-individual-store.c
index e72b7ec9e..985b6e317 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)