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 621393 - New widget: GtkLiveSearch
New widget: GtkLiveSearch
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2010-06-12 17:30 UTC by Xavier Claessens
Modified: 2013-10-15 01:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add GtkLiveEntry (35.90 KB, patch)
2011-03-01 09:07 UTC, Carlos Garcia Campos
none Details | Review
gtktreeview: Use GtkLiveEntry (28.57 KB, patch)
2011-03-01 09:09 UTC, Carlos Garcia Campos
none Details | Review
libview: Use GtkLivEntry for the goto-window in presentation mode (10.05 KB, patch)
2011-03-01 09:10 UTC, Carlos Garcia Campos
none Details | Review
typeahead-find: Use GtkLiveEntry (20.35 KB, patch)
2011-03-04 13:24 UTC, Carlos Garcia Campos
none Details | Review
Add GtkLiveEntry widget (37.44 KB, patch)
2011-03-28 08:24 UTC, Carlos Garcia Campos
none Details | Review
gtktreeview: Use GtkLiveEntry (29.17 KB, patch)
2011-03-28 08:25 UTC, Carlos Garcia Campos
none Details | Review

Description Xavier Claessens 2010-06-12 17:30:40 UTC
I've been working on the HildonLiveSearch widget you can see on N900. This is the entry you see when typing on the keyboard to filter your contact list for example.

Felix Kaser and I ported that widget to Empathy's main window. The code is in git master[1]. I would like to propose that widget to become GtkLiveSearch.

How it works: GtkLiveSearch is a widget you can pack anywhere in your window. It contains a GtkEntry and is hidden by default. You give a hook-widget to it, and it will listen for "key-press-event" on the hook widget, and it forward events to the hidden entry. Once the entry got a typed text, it gets shown automatically and the signal "notify::text" is emitted on the GtkLiveSearch. The UI you want to filter (probably a GtkTreeView using a GtkTreeModelFilter) can listen to that signal and refilter the model, for each row it can then call gtk_live_search_match(live_search, text_of_that_row); and that will tell if the text of that row should be visible. That match function does some UTF8 manipulations, to accept the row "élève" if the text searched is "ele" for example. This is making the implementation of the visible_func of your GtkTreeModelFilter really easy.

This feature is a bit redundant with the interactive search we already have on GtkTreeView, but it has advantage of having a much nicer user experience (smart matching algorithm, and filter the view instead of searching in it). And also GtkLiveSearch does not depends on GtkTreeView, you could use it your own way with any widget where it makes sense to search/filter.

If you agree that would be a great widget to have inside GTK, I can rename EmpathyLiveSearch to GtkLiveSearch and push it in a gtk branch, and start reviews (yes, gtk-doc is missing atm). Of course I'm open to any suggestion to improve it.

[1] http://git.gnome.org/browse/empathy/tree/libempathy-gtk/empathy-live-search.c
Comment 1 Javier Jardón (IRC: jjardon) 2010-06-12 17:49:56 UTC
Only point that this could be used by yelp instead its own live search implementation
Comment 2 Milan Bouchet-Valat 2010-06-13 09:21:36 UTC
I think that would be very interesting to have, notably because UTF-8 manipulations are very hard to get right in all projects separately.

While your design seems really nice, I'm wondering whether this couldn't be implemented as a more generic object, instead of a GtkEntry. This might be useful for cases where the entry is e.g. a combo box entry, or to use it e.g. in GNOME Shell, where the entry is a Clutter actor.

Wouldn't it be easy using GBinding to connect any widget with a 'text' property to this new live search object, that would then be connected to e.g. a tree view, or possibly other widgets?
Comment 3 Xavier Claessens 2010-06-13 09:54:43 UTC
In the current implementation, the GtkLiveSearch (actually EmpathyLiveSearch) is a GtkHBox subclass containing only a GtkEntry. Maybe I should change this to be a subclass of GtkBin.

But the idea is that the GtkEntry is private and you don't have direct access to it, so it shouldn't be too hard to add an API that allow using a GtkComboBoxEntry instead, for example.
Comment 4 Xavier Claessens 2010-06-13 10:02:31 UTC
(In reply to comment #2)
> I think that would be very interesting to have, notably because UTF-8
> manipulations are very hard to get right in all projects separately.

Note that it is extremely difficult, if not impossible, to get this right. I blogged about it, comments are interesting: http://blogs.gnome.org/xclaesse/2010/06/07/need-help-with-non-latin-alphabet/
Comment 5 Nelson Benitez 2010-12-09 12:39:39 UTC
Hi, just a question.. will this search from beginnig of string or in any part of string.. I mean, if I have the following three items:

abalore
casa
lorena

and I search for 'lore' will match on abalore or on lorena?

If the answer is 'depends how you do it in your own filter function'.. then is it possible to have a filter function that will return the first word that matches AT START of string and if doesn't find anyone then will find again but matching IN MIDDLE of string ?

that was a feature request for current typeahead nautilus search function, search for files that start with searched string and if don't find anyone then search for files that have the searched string in any part of the filename. 

That was not possible with current gtktreeview typeahead and I was wondering if it could be done with your widget.
Comment 6 Xavier Claessens 2010-12-10 07:20:35 UTC
It match start of each word. For example if you have an item "Xavier Claessens" and you type "Cla xa" it will match, but if you type "vier" it won't. Matching middle/end of words is not wanted in most case otherwise you get too many row that match.

Note that the code does not force you using its matching algorithm, you can implement your own.
Comment 7 Carlos Garcia Campos 2011-02-16 14:53:16 UTC
I see two different things here, one is the search algorithm, that can be used to search or filter on any  widget, and the other one is the widget containing an entry that appears when you type, that can be used for other things than searching, like the one used by evince to jump to a random page in presentation mode (based on gtktreeview live search dialog), see:

http://git.gnome.org/browse/evince/tree/libview/ev-view-presentation.c#n554

The search part could be an object associated to a GtkEntry (or even any GtkEditable widget) that connects to changed signal and provides a match function. This way it could be used also by other widgets like a find bar or a search dialog. 
The entry dialog might be a generic widget contaning a GtkEntry with a get_text() method that it's shown when the associated widget receives key press events.
Comment 8 Xavier Claessens 2011-02-25 10:03:31 UTC
Note that with empathy's code, you can use the matching algorithm without having a EmpathyLiveSearch widget. You can use that API:

gboolean empathy_live_search_match_string (const gchar *string, const gchar *prefix);

It will search for @prefix inside @string, doing the smart words prefix matching. That part of the code could be splited into a different file if needed.
Comment 9 Carlos Garcia Campos 2011-03-01 09:07:29 UTC
Created attachment 182161 [details] [review]
Add GtkLiveEntry

This is a widget based on Empathy, GtkTreeView and evince code to show a popup window with an entry when typing on a hook widget. API doc is still missing, but I think the API is simple enough. I'll attach here the patches for GtkTreeView and Evince that show how it works.
Comment 10 Carlos Garcia Campos 2011-03-01 09:09:10 UTC
Created attachment 182162 [details] [review]
gtktreeview: Use GtkLiveEntry

This patch uses GtkLiveEntry in GtkTreeView to implement the interactive search dialog.
Comment 11 Carlos Garcia Campos 2011-03-01 09:10:39 UTC
Created attachment 182163 [details] [review]
libview: Use GtkLivEntry for the goto-window in presentation mode

And this is the patch that evince would use to implement the goto window in presentation mode
Comment 12 Xavier Claessens 2011-03-01 09:27:44 UTC
From a very quick look, I don't like it being a GtkWindow subclass. That means you can't nicely embed it into your window. I like empathy's way of the entry appearing below the treeview. Maybe we can have GtkLiveEntry being a GtkBox subclass (like empathy implementation) and GtkLiveEntryWindow being a GtkWindow embedding a GtkLiveEntry?
Comment 13 Carlos Garcia Campos 2011-03-04 11:09:45 UTC
(In reply to comment #12)
> From a very quick look, I don't like it being a GtkWindow subclass. That means
> you can't nicely embed it into your window. I like empathy's way of the entry
> appearing below the treeview.

You can set a position func and place the window at any point.

> Maybe we can have GtkLiveEntry being a GtkBox
> subclass (like empathy implementation) and GtkLiveEntryWindow being a GtkWindow
> embedding a GtkLiveEntry?

Unfortunately it's not that easy, the way we forward the key events from the hook widget to the entry is different in both cases. When using a popup window we need to move the window offscreen and then send the key event, while when packed you can assume the parent window is visible because hook widget is receiving key events and live entry is packed in the same window than the hook widget. So we would have to implement mostly the same code in both cases, and the live entry would need to know whether its parent is a live entry window or not. I think it isn't worth it when you can have a single widget that is flexible enough and can be placed anywhere.
Comment 14 Carlos Garcia Campos 2011-03-04 13:24:13 UTC
Created attachment 182461 [details] [review]
typeahead-find: Use GtkLiveEntry

This would be the patch for nautilus
Comment 15 Carlos Garcia Campos 2011-03-28 08:24:05 UTC
Created attachment 184423 [details] [review]
Add GtkLiveEntry widget

Reposting this as it seems it was lost due to bugzilla issues last week. This patch fixes a couple of regressions I've noticed compared to current gtktreeview code (see bugs #169534 and #71868)
Comment 16 Carlos Garcia Campos 2011-03-28 08:25:51 UTC
Created attachment 184424 [details] [review]
gtktreeview: Use GtkLiveEntry

Update treeview patch to use GtkLiveEntry, compared to previous one it simply removes unused code.
Comment 17 Matthias Clasen 2011-04-30 00:49:19 UTC
Taking a first look at this. Initial impression from just reading the patches:

- I very much approve of unifying several copies of not quite kosher code poking into GTK+ internals into a single supported implementation

- Not a fan of the naming here. Both 'GtkLiveEntry' and 'hook-widget' sound bad to me. I don't have great alternatives though. Maybe 'GtkInteractiveSearch' or 'GtkSearchPopup' ? and maybe 'base' instead of 'hook' ? Better proposals welcome...

- Wrt. window or not: One use case that we should probably keep in mind is putting the entry in one of those newfangled GeditOverlays ? Would be good to support that nicely
Comment 18 Carlos Garcia Campos 2011-05-04 07:28:18 UTC
(In reply to comment #17)
> Taking a first look at this. Initial impression from just reading the patches:
> 
> - I very much approve of unifying several copies of not quite kosher code
> poking into GTK+ internals into a single supported implementation
> 
> - Not a fan of the naming here. Both 'GtkLiveEntry' and 'hook-widget' sound bad
> to me. I don't have great alternatives though. Maybe 'GtkInteractiveSearch' or
> 'GtkSearchPopup' ? and maybe 'base' instead of 'hook' ? Better proposals
> welcome...

The thing is that it's not necessarily used to search, for example, in Evince we use it to jump to another page in presentation mode. Maybe GtkInteractiveWindow or GtkInteractivePopup.

> - Wrt. window or not: One use case that we should probably keep in mind is
> putting the entry in one of those newfangled GeditOverlays ? Would be good to
> support that nicely

I think we need two different widgets to support both.
Comment 19 Kristian Rietveld 2011-11-09 10:15:52 UTC
Putting this on my review queue.
Comment 20 Matthias Clasen 2012-03-02 13:42:37 UTC
didn't make 3.2, obviously
Comment 21 Kristian Rietveld 2012-07-15 12:53:31 UTC
I have promised to give some comments on what direction you may want to take here, so here we go.

When I first looked at this I was pretty confused about the relationship between EmpathyLiveSearch and the patch for a GtkLiveEntry. For now, I am assuming that GtkLiveEntry is a GTK+ adaptation of EmpathyLiveSearch.

I tend to pretty much agree with Carlos' comment 7, which says that you want to separate the search algorithm from the entry/window mechanics. Secondly, you want to design the entry/window mechanics such that it can be re-used by many widgets.

So what we have now is not really a GtkLiveSearch, but an entry popup that can be used for live search as in filtering and for search as in browsing through a widget's contents.  Like Matthias is mentioning in comment 17, a different name is in order.

Matthias also mentions that we do not want to force to using an entry in a window. He mentions possibly using GeditOverlays.  We also used to have a bug which requested the possibility to pack the GtkTreeView search entry elsewhere in the interface (I cannot find the bug number anymore).

Perhaps you want to have a model like the following:

1. A GtkLiveSearch or GtkSearch object which can be instantiating with different widgets (GtkEntry, GtkComboBoxEntry, ClutterEntry, ...).
2. The GtkSearch is then either packed into a special "GtkSearchPopup" or somewhere else e.g. "GtkSearchBar"/"GtkSearchWidget".
3. A separate class containing the search helper functions.

An issue with 1. could be that you risk having code inside GtkSearch to be able to deal with different types of entry widgets.  If this becomes too nasty, GtkSearch needs to be separated from the actual entry widgets to be used with it in a different way.

"hook-widget" can perhaps be replaced with "monitor-widget", "search-content-widget" or "content-widget".


Some quick comments on the code:

 * In the original Empathy code, I am not sure if you really want to re-use/overload the notify::text signal for communicating when to update the filter.  GtkLiveSearch appears to use a separated "changed" signal for this.

 * GtkLiveEntry: general comments, see above: restricted to popup window, restricted to GtkEntry, API needs different naming.

 * GtkLiveEntry uses code taken from gtkwindow.c and GtkTreeView without attributing this in Copyright.

 * Should we continue to copy send_focus_change() around?  Though at least now we would have it only in gtkwindow.c and in the search code which is probably fair enough.

 * "query" signal is probably clearer with a different name?

 * I am slightly concerned about GtkLiveEntry monitoring all key-press-events and deciding which ones it handles, in terms of breaking the widget being monitored.  It should be mostly safe as it is however.


In summary, I am definitely not be opposed to moving this code out of GtkTreeView into something generic, as long as all functionality and handling of corner cases is preserved.
Comment 22 Xavier Claessens 2013-10-09 15:20:00 UTC
GtkSearchBar landed in GTK 3.10 with lots of similar features than the initially proposed EmpathyLiveSearch here. I'm closing this bug, if something is missing I think they should be filled as separate bug on GtkSearchBar.
Comment 23 Xavier Claessens 2013-10-09 18:55:11 UTC
I've reported bug #709753 for the matching algorithm part.
Comment 24 Allison Karlitskaya (desrt) 2013-10-15 01:20:01 UTC
Bug 709753 is done.