diff -Naur old/src/appfinder-model.c new/src/appfinder-model.c --- old/src/appfinder-model.c 2015-02-21 16:14:20.000000000 +0300 +++ new/src/appfinder-model.c 2016-11-19 03:53:24.212954227 +0300 @@ -101,6 +101,8 @@ static void xfce_appfinder_model_bookmarks_monitor (XfceAppfinderModel *model, const gchar *path); +static gboolean xfce_appfinder_model_fuzzy_match (const gchar *source, + const gchar *token); struct _XfceAppfinderModelClass @@ -2020,7 +2022,7 @@ if (string != NULL && item->key != NULL) - return strstr (item->key, string) != NULL; + return xfce_appfinder_model_fuzzy_match (item->key, string); } else /* command item */ { @@ -2030,7 +2032,7 @@ return FALSE; if (string != NULL) - return strstr (item->command, string) != NULL; + return xfce_appfinder_model_fuzzy_match (item->command, string); } return TRUE; @@ -2059,8 +2061,8 @@ } if (item->command != NULL && string != NULL) - return strncmp (item->command, string, strlen (string)) == 0; - + return xfce_appfinder_model_fuzzy_match(item->command, string); + return FALSE; } @@ -2421,7 +2423,7 @@ static gsize old_len = 0; GString *contents; gchar *filename; - gboolean succeed; + gboolean succeed=FALSE; GtkTreePath *path; gint idx; GtkTreeIter iter; @@ -2549,3 +2551,53 @@ return category; } + + + +gboolean +xfce_appfinder_model_fuzzy_match (const gchar *source, + const gchar *token) +{ + const guint token_size=strlen(token); + const guint cmd_part_size=token_size+1; + guint index; + gboolean match=FALSE; + gboolean contain_uppercase=FALSE; + + // length is chosen because of ".* *.*(?i).*" pattern format + // "(?i)" is optional part + gchar pattern[token_size+14]; + gchar cmd_part[cmd_part_size]; + gchar *param_part; + + if(strcmp(token,"")==0) + return TRUE; + + for(index=1;!match &&(index<=token_size);index++) + { + memset(cmd_part,0,cmd_part_size); + strncpy(cmd_part,token,index); + cmd_part[index+1]='\0'; + + contain_uppercase=FALSE; + param_part=(gchar*) token+index; + + while(!contain_uppercase && (*param_part!='\0')) + { + contain_uppercase=g_ascii_isupper(*param_part); + param_part++; + } + + memset(pattern,0,sizeof(pattern)); + g_sprintf(pattern,".*%s *.*%s%s.*",cmd_part, + (contain_uppercase)? "(?-i)" : "(?i)", + token+index); + match=g_regex_match_simple(pattern,source,0,0); + if(match) + { + APPFINDER_DEBUG("Fuzzy match: regexp=%s ; source=%s",pattern,source); + } + } + + return match; +} diff -Naur old/src/appfinder-window.c new/src/appfinder-window.c --- old/src/appfinder-window.c 2015-02-21 16:14:20.000000000 +0300 +++ new/src/appfinder-window.c 2016-11-19 03:42:16.141974374 +0300 @@ -112,8 +112,6 @@ static void xfce_appfinder_window_execute (XfceAppfinderWindow *window, gboolean close_on_succeed); - - struct _XfceAppfinderWindowClass { GtkWindowClass __parent__; @@ -294,7 +292,7 @@ gtk_entry_completion_set_match_func (completion, xfce_appfinder_window_completion_match_func, window, NULL); gtk_entry_completion_set_text_column (completion, XFCE_APPFINDER_MODEL_COLUMN_COMMAND); gtk_entry_completion_set_popup_completion (completion, TRUE); - gtk_entry_completion_set_popup_single_match (completion, FALSE); + gtk_entry_completion_set_popup_single_match (completion, TRUE); gtk_entry_completion_set_inline_completion (completion, TRUE); window->bin_collapsed = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); @@ -571,7 +569,7 @@ static void xfce_appfinder_window_set_item_width (XfceAppfinderWindow *window) { - gint width; + gint width=0; XfceAppfinderIconSize icon_size; GtkOrientation item_orientation = GTK_ORIENTATION_VERTICAL; GList *renderers; @@ -1555,10 +1553,12 @@ gpointer data) { XfceAppfinderWindow *window = XFCE_APPFINDER_WINDOW (data); + /* don't use the casefolded key generated by gtk */ + const gchar *filter_string= gtk_entry_get_text (GTK_ENTRY (window->entry)); return xfce_appfinder_model_get_visible (XFCE_APPFINDER_MODEL (model), iter, window->filter_category, - window->filter_text); + filter_string); }