summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2022-10-10 20:16:45 +0200
committerNiels De Graef <ndegraef@redhat.com>2022-10-11 08:31:48 +0200
commitc2e72f699295d792fd790bfd5e4d48b5c646ceb6 (patch)
tree02df7f33b4b8055abea5e83f80f88bd83fa86462 /src
parent3f932b2d14a884d59aceceb5be6aef7f2a360c27 (diff)
downloadgnome-contacts-c2e72f699295d792fd790bfd5e4d48b5c646ceb6.tar.gz
contact: Copy the chunks before applying changes
When applying the changes of certain fields, we've seen that this leads to a `individuals_changed_detailed()` being called with the same individual in the `removed` and `added` set. The signal callback propagates to several layers, until it lands in the `Contact:on_individual_personas_changed()` function. There, all chunks related to the persona are removed, even when we still might be applying changes of some of the other chunks. The `apply_changes()` method in other words should keep its own copy to prevent that. Fixes: https://gitlab.gnome.org/GNOME/gnome-contacts/-/issues/271
Diffstat (limited to 'src')
-rw-r--r--src/core/contacts-contact.vala11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/core/contacts-contact.vala b/src/core/contacts-contact.vala
index 761f447..742bab7 100644
--- a/src/core/contacts-contact.vala
+++ b/src/core/contacts-contact.vala
@@ -264,9 +264,12 @@ public class Contacts.Contact : GLib.Object, GLib.ListModel {
public async unowned Individual? apply_changes (PersonaStore store) throws GLib.Error {
unowned Individual? individual = null;
+ // Create a (shallow) copy of the chunks
+ var chunks = this.chunks.copy ((chunk) => { return chunk; });
+
// For those that were a persona: save the properties using the API
- for (uint i = 0; i < this.chunks.length; i++) {
- unowned var chunk = this.chunks[i];
+ for (uint i = 0; i < chunks.length; i++) {
+ unowned var chunk = chunks[i];
if (chunk.persona == null)
continue;
@@ -297,8 +300,8 @@ public class Contacts.Contact : GLib.Object, GLib.ListModel {
// Find those without a persona, and save them into the primary store
var new_details = new HashTable<string, Value?> (str_hash, str_equal);
- for (uint i = 0; i < this.chunks.length; i++) {
- unowned var chunk = this.chunks[i];
+ for (uint i = 0; i < chunks.length; i++) {
+ unowned var chunk = chunks[i];
if (chunk.persona != null)
continue;