From 019365d216471676ddc3c878219e1685874c3d7e Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 2 Sep 2010 10:58:41 +0100 Subject: 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 file changed, 48 insertions(+), 34 deletions(-) (limited to 'libempathy-gtk') 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,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, -- cgit v1.2.3