From 9c256a5c7917a01f844c43501468c4700a4fcc28 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Sun, 8 Apr 2018 22:50:31 +0200 Subject: Store: add contacts in a separate thread. This should help with issue #75 by not blocking the main thread anymore when adding a huge amount of contacts (which is almost always the case when starting Contacts). --- src/contacts-contact-list.vala | 1 + src/contacts-store.vala | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/contacts-contact-list.vala b/src/contacts-contact-list.vala index 5a0dd0e..4f75316 100644 --- a/src/contacts-contact-list.vala +++ b/src/contacts-contact-list.vala @@ -116,6 +116,7 @@ public class Contacts.ContactList : ListBox { this.notify["state"].connect (on_ui_state_changed); + this.sort_on_surname = settings.sort_on_surname; settings.changed["sort-on-surname"].connect(() => { this.sort_on_surname = settings.sort_on_surname; invalidate_sort(); diff --git a/src/contacts-store.vala b/src/contacts-store.vala index 3b75a88..5b7c715 100644 --- a/src/contacts-store.vala +++ b/src/contacts-store.vala @@ -176,10 +176,20 @@ public class Contacts.Store : GLib.Object { var replaced_individuals = new HashMap (); var old_individuals = changes.get_keys(); + // At startup, a mass of contacts are added here: so, do this in a separate thread. + var added_individuals = changes[null]; + if (!added_individuals.is_empty) { + new Thread (null, () => { + bulk_add (added_individuals); + return null; + }); + } + // Pick best replacements at joins foreach (var old_individual in old_individuals) { if (old_individual == null) continue; + foreach (var new_individual in changes[old_individual]) { if (new_individual == null) continue; @@ -202,9 +212,6 @@ public class Contacts.Store : GLib.Object { // Removing an old individual. var c = Contact.from_individual (old_individual); remove (c); - } else if (new_individual != null) { - // Adding a new individual. - add (new Contact (this, new_individual)); } } @@ -231,7 +238,9 @@ public class Contacts.Store : GLib.Object { if (i != main_individual) { // Already replaced this old_individual, i.e. we're splitting // old_individual. We just make this a new one. - add (new Contact (this, i)); + var new_contact = new Contact (this, i); + this.contacts.add (new_contact); + added (new_contact); } } } @@ -277,9 +286,16 @@ public class Contacts.Store : GLib.Object { return contacts.read_only_view; } - private void add (Contact c) { - contacts.add (c); - added (c); + private void bulk_add (Collection indivs) { + foreach (var individual in indivs) { + var c = new Contact (this, individual); + this.contacts.add (c); + // Since we do this in a separate thread, use Idle.add. + Idle.add (() => { + added (c); + return false; + }); + } } private void remove (Contact c) { -- cgit v1.2.1