diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2010-09-02 17:58:41 +0800 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2010-09-02 23:13:29 +0800 |
commit | 019365d216471676ddc3c878219e1685874c3d7e (patch) | |
tree | 3510bef8abb9c28a230470c4cf71b7a4875301a1 | |
parent | 8605cf086f2509d751beb4290921327bc409dde8 (diff) | |
download | gsoc2013-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.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 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) |