After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 679002 - Implement a remote search provider for GNOME Shell
Implement a remote search provider for GNOME Shell
Status: RESOLVED FIXED
Product: gnome-contacts
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: GNOME Contacts maintainer(s)
GNOME Contacts maintainer(s)
Depends on:
Blocks: 677442
 
 
Reported: 2012-06-27 18:45 UTC by Florian Müllner
Modified: 2012-08-05 19:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
contact: Move get_eds_addressbooks() to App (3.20 KB, patch)
2012-06-27 18:45 UTC, Florian Müllner
committed Details | Review
contact: Use our own store reference rather than the on in App (1.15 KB, patch)
2012-06-27 18:45 UTC, Florian Müllner
committed Details | Review
contacts: Pass store as parameter to create_primary_persona_from_store (2.78 KB, patch)
2012-06-27 18:45 UTC, Florian Müllner
committed Details | Review
Add search provider for GNOME Shell (8.56 KB, patch)
2012-06-27 18:45 UTC, Florian Müllner
none Details | Review
Add search provider for GNOME Shell (9.82 KB, patch)
2012-06-29 12:33 UTC, Florian Müllner
none Details | Review
Add search provider for GNOME Shell (9.84 KB, patch)
2012-06-29 13:03 UTC, Florian Müllner
committed Details | Review
Add search provider for GNOME Shell (10.28 KB, patch)
2012-06-29 13:49 UTC, Florian Müllner
none Details | Review

Description Florian Müllner 2012-06-27 18:45:17 UTC
Last cycle, we added a DBus interface which allows applications to hook into the Shell's search. There isn't really a good reason to maintain two separate contacts search implementations (or to have contacts search implemented in gnome-shell in the first place), so add an implementation in Contacts in order to remove the built-in one from Shell.

(I'm happy to admit that I'm not entirely happy with the preparation patches, but it turned out to be the easiest way to share the relevant bits between search provider and application)
Comment 1 Florian Müllner 2012-06-27 18:45:20 UTC
Created attachment 217440 [details] [review]
contact: Move get_eds_addressbooks() to App

Contact currently references App in a couple of places, which
means the class depends on pretty much any other class. In order
to reuse the Contact class in the shell search provider (which will
be a separate executable), reduce the Contact class' dependencies.
Comment 2 Florian Müllner 2012-06-27 18:45:24 UTC
Created attachment 217441 [details] [review]
contact: Use our own store reference rather than the on in App

Contact currently references App in a couple of places, which
means the class depends on pretty much any other class. In order
to reuse the Contact class in the shell search provider (which will
be a separate executable), reduce the Contact class' dependencies.
Comment 3 Florian Müllner 2012-06-27 18:45:27 UTC
Created attachment 217442 [details] [review]
contacts: Pass store as parameter to create_primary_persona_from_store

Contact currently references App in a couple of places, which
means the class depends on pretty much any other class. In order
to reuse the Contact class in the shell search provider (which will
be a separate executable), reduce the Contact class' dependencies.
Comment 4 Florian Müllner 2012-06-27 18:45:31 UTC
Created attachment 217443 [details] [review]
Add search provider for GNOME Shell

GNOME Shell provides a DBus interface for external search provider
implementations; add a small auto-activated service which implements
that interface, to replace the Shell's built-in contact search with
results provided directly by GNOME Contacts.
Comment 5 Alexander Larsson 2012-06-28 07:24:47 UTC
Review of attachment 217443 [details] [review]:

::: src/contacts-contact.vala
@@ +148,3 @@
+      if (individual.avatar == null) {
+        if (_default_avatar == null)
+          _default_avatar = new ThemedIcon ("avatar-default");

The search provider already has a fallback check like this. Maybe not duplicate it. Its kinda weird to sometimes return null, and sometimes a default fallback.

@@ +153,3 @@
+
+      if (individual.avatar.to_string () != null)
+        return individual.avatar;

This check makes the general "Icon avatar_icon" property name a bit weird, since its really only non-null for serializable icons. I think this would be better as a get_serializable_avatar_icon() method.

@@ +159,3 @@
+  }
+
+  private Gdk.Pixbuf? _avatar_icon;

Why is this not a local variable? It does not seem to be required to keep the icon around if we keep the icon data around.

@@ +160,3 @@
+
+  private Gdk.Pixbuf? _avatar_icon;
+  private Variant? _avatar_icon_data;

This needs to be invalidated on avatar change, just like _small_avatar.

::: src/contacts-shell-search-provider.vala
@@ +1,3 @@
+using Gee;
+
+[DBus (name = "org.gnome.Shell.SearchProvider")]

Can you just add this, don't we need some kind of dependency check for it in configure?

@@ +17,3 @@
+    store.added.connect ( (c) => {
+      update_contacts_map ();
+    });

These seem both inefficient and wrong. You only need to add the new id, and if the individual id changed then you need to also remove the old one from the map.

@@ +25,3 @@
+  private void update_contacts_map () {
+    foreach (var c in store.get_contacts ()) {
+      id_to_contact_map.insert (c.individual.id, c);

This does not remove old individuals from the map.
Honestly, it just seems painful to reuse the possibly changing individual id to reference the Contact. I think it would make more sense to just assign each new contact a unique id. Something like:

Gee.HashMap<string, Contact> contacts_map;
on add
 var id = next_id++.to_string();
 contact.set_data("search-id", id)
 contacts_map.add (contact, id)
on remove
 contacts_map.remove (contact.get_data<string>("search-id")

@@ +37,3 @@
+
+      if (c.contains_strings (terms))
+          results.add (c.individual.id);

There is a lot of "garbage" in the full contacts set, we should probably also filter on contact.is_main, or at least sort those first.

@@ +56,3 @@
+    var results = new ArrayList<HashTable> ();
+    foreach (var id in ids) {
+      var contact = id_to_contact_map.lookup (id);

There is a race here, the contact could be gone now, so this needs to check for null.

@@ +108,3 @@
+  var app = new SearchProviderApp ();
+
+  if (Environment.get_variable ("CONTACTS_SEARCH_PROVIDER_PERSIST") != null)

What does this do?
Comment 6 Alexander Larsson 2012-06-28 07:52:52 UTC
Attachment 217440 [details] pushed as 72a7a5c - contact: Move get_eds_addressbooks() to App
Attachment 217441 [details] pushed as 93c9ae6 - contact: Use our own store reference rather than the on in App
Attachment 217442 [details] pushed as d891e08 - contacts: Pass store as parameter to create_primary_persona_from_store
Comment 7 Florian Müllner 2012-06-28 11:26:41 UTC
(In reply to comment #5)
> +[DBus (name = "org.gnome.Shell.SearchProvider")]
> 
> Can you just add this, don't we need some kind of dependency check for it in
> configure?

To be honest, I'm not sure. I removed the interface definition installed by gnome-shell from both the system and jhbuild directories, and the search provider still compiles fine, so I guess it's OK to just add this ...


> @@ +159,3 @@
> +  }
> +
> +  private Gdk.Pixbuf? _avatar_icon;

> Why is this not a local variable? It does not seem to be required to keep the
> icon around if we keep the icon data around.

This is actually how we keep the icon data around - neither gdk_pixbuf_get_pixels() nor g_variant_new_from_data() copy the actual pixel data. Maybe I should just keep the pixbuf and create the variant in the search provider as needed?


> @@ +108,3 @@
> +  var app = new SearchProviderApp ();
> +
> +  if (Environment.get_variable ("CONTACTS_SEARCH_PROVIDER_PERSIST") != null)
> 
> What does this do?

In normal operation, the service is autostarted via DBus and exits after some time of inactivity. However if the above variable is set, the service does not exit automatically, which can come in handy for debugging (the approach is shamelessly copied from Cosimo, who always adds FOO_PERSIST handling to DBus services)
Comment 8 Alexander Larsson 2012-06-28 12:20:23 UTC
> This is actually how we keep the icon data around - neither
> gdk_pixbuf_get_pixels() nor g_variant_new_from_data() copy the actual pixel
> data. Maybe I should just keep the pixbuf and create the variant in the search
> provider as needed?

Just ref the pixbuf and pass g_object_unref as destroy notify in g_variant_new_from_data and the pixbuf as user_data.

Also, why don't you reuse small_avatar? It seems to do the same thing...
Comment 9 Florian Müllner 2012-06-28 12:27:47 UTC
(In reply to comment #8)
> Just ref the pixbuf and pass g_object_unref as destroy notify in
> g_variant_new_from_data and the pixbuf as user_data.

Noob question - how do I do that in vala?


> Also, why don't you reuse small_avatar? It seems to do the same thing...

Good point, will do.
Comment 10 Alexander Larsson 2012-06-28 13:03:05 UTC
var v = Variant.new_from_data (VariantType.BYTESTRING,
                               pixbuf.get_pixels_with_length (), 
                               true, pixbuf);
Comment 11 Florian Müllner 2012-06-28 13:14:03 UTC
Thanks!
Comment 12 Florian Müllner 2012-06-28 13:31:08 UTC
(In reply to comment #9)
> > Also, why don't you reuse small_avatar? It seems to do the same thing...
> 
> Good point, will do.

Mmmh, there is a small difference, as small_avatar adds rounded corners individual.avatar doesn't have. However I'll ignore that for now - I suspect that designers will ask for rounded corners on *all* the icons, which means it should be implemented in gnome-shell, which would then hide the difference anyway ...
Comment 13 Alexander Larsson 2012-06-28 13:45:12 UTC
Yeah, the rounded corners is a request from the designers, so we should probably have them everywhere we show the contact avatar anyway.
Comment 14 Florian Müllner 2012-06-28 14:02:29 UTC
Right, though I suspect that we'll want rounded corners for non-contact icons as well - otherwise we could just send icon-data for all icons except the fallback one (though I don't like the idea of sending pixel data over dbus unless really necessary)
Comment 15 Alexander Larsson 2012-06-28 15:08:19 UTC
We'll drop the fallback icon for robohash style icons eventually anyway.
Comment 16 Florian Müllner 2012-06-29 12:33:06 UTC
Created attachment 217607 [details] [review]
Add search provider for GNOME Shell

This should address all comments and fix a couple of issues that went unnoted :-)


(In reply to comment #5)
> +      if (c.contains_strings (terms))
> +          results.add (c.individual.id);
> 
> There is a lot of "garbage" in the full contacts set, we should probably also
> filter on contact.is_main, or at least sort those first.

The general idea for search providers is to return the exact same result set as the corresponding in-app search. There are a couple more conditions in the list-box filter_func, but as far as I can tell from the code none of them is relevant to the search view, so the filter here should be fine.

However, I completely failed to sort the results, which should be fixed now. I'm not quite sure whether sorting the result set is the best way to do it though - the number of elements is smaller, but we need to re-sort a lot more.


Apart from that, I have an issue with result activation, which I'm somehow unable to figure out - gnome-contacts often gives me an error about not finding the requested contact. It might be related to jhbuild (switching to a contact after having started contacts with jhbuild run is a lot less likely to fail), but there's probably more to it. If you have any quick idea what might be wrong, I'd appreciate the hint, otherwise I'll be doing some more investigation.
Comment 17 Alexander Larsson 2012-06-29 12:53:21 UTC
gnome-contacts normally only shows the contacts in the primary persona-store (i.e. google contacts or e-d-s local addressbook). However, when searching it shows both, first the primary ones, then a separator/header then the rest. Not sure how you can do something like that in the shell though, although we can do the same sort.
Comment 18 Florian Müllner 2012-06-29 12:59:00 UTC
(In reply to comment #17)
> gnome-contacts normally only shows the contacts in the primary persona-store
> (i.e. google contacts or e-d-s local addressbook). However, when searching it
> shows both, first the primary ones, then a separator/header then the rest. Not
> sure how you can do something like that in the shell though, although we can do
> the same sort.

Yup, the current patch should do exactly that (minus the separator of course).
Comment 19 Alexander Larsson 2012-06-29 13:02:34 UTC
Do i need to do anything to get the shell to pick this up?
Comment 20 Florian Müllner 2012-06-29 13:03:00 UTC
Created attachment 217617 [details] [review]
Add search provider for GNOME Shell

Gah, forgot to chain up startup() ...
Comment 21 Alexander Larsson 2012-06-29 13:43:23 UTC
Attachment 217617 [details] pushed as 19751af - Add search provider for GNOME Shell
Comment 22 Alexander Larsson 2012-06-29 13:44:30 UTC
It lacked a service file and Name/Icon for the search provider file. I added that and i18n for the data files and pushed to master.
Comment 23 Florian Müllner 2012-06-29 13:49:32 UTC
Created attachment 217623 [details] [review]
Add search provider for GNOME Shell

(In reply to comment #19)
> Do i need to do anything to get the shell to pick this up?

First, I forgot to install a .service file to auto-activate the search provider - fixed here.

Then it gets tricky I'm afraid.

In general, this is how it's supposed to work:
 (1) on startup, shell parses provider .ini files in
     $dir/gnome-shell/search-providers for all directories
     in $XDG_DATA_DIRS
 (2) for each file that is succesfully parsed, a dbus proxy
     object is created
 (3) any time a search is started, dbus-daemon should auto-activate
     the appriate services

Now the tricky bits:
 (1) I'm using 'DesktopId' in the .ini file, which is only understood
     by the shell since 3.5.3; if you are not using gnome-shell from
     jhbuild or current rawhide, you need to add
        Title=Contacts
        Icon=x-office-address-book
     to the gnome-contacts-search-provider.ini.in
 (3) assuming gnome-contacts is run from jhbuild and dbus-daemon is not,
     auto-activation will fail; either hack the .service file to
     execute jhbuild run, or start the search provider manually with
     CONTACTS_SEARCH_PROVIDER_PERSIST=1
Comment 24 Florian Müllner 2012-06-29 13:53:39 UTC
(In reply to comment #22)
> It lacked [...] Name/Icon for the search provider file. I added
> that and i18n for the data files and pushed to master.

The plan here is that 'DesktopId' will supersede the Name/Icon combo, mostly to make the i18n glue unnecessary.
Comment 25 Alexander Larsson 2012-06-29 13:57:22 UTC
Ok. I'll remove that then.
Comment 26 Florian Müllner 2012-06-29 14:01:01 UTC
If you still want some compatibility with older shell versions ("older" == "< 3.5.3"), I'd suggest to keep Name/Icon, but leave it untranslated - newer shell versions will pick up translations from the .desktop file
Comment 27 Marc-Andre Lureau 2012-08-05 14:00:20 UTC
Review of attachment 217617 [details] [review]:

::: src/contacts-shell-search-provider.vala
@@ +113,3 @@
+
+    if (contact == null)
+      return;

I guess you want to app.release () before leaving that method.
Comment 28 Florian Müllner 2012-08-05 19:09:21 UTC
(In reply to comment #27)
> I guess you want to app.release () before leaving that method.

Right. Would you mind doing a patch?