From 537ea5a5724bad821d55f90f731e6acac9194027 Mon Sep 17 00:00:00 2001
From: Daniel Carl <danielcarl@gmx.de>
Date: Sat, 29 Jun 2013 01:06:11 +0200
Subject: [PATCH] Removed direct reading of tree by select function.

This seems to be the better way to get the text of the current active
completion items instead of moving the cursor to the new item and that try to
get the text of it.
---
 gmon.out         | Bin 21650 -> 0 bytes
 src/completion.c | 117 +++++++++++++++++++----------------------------
 2 files changed, 48 insertions(+), 69 deletions(-)
 delete mode 100644 gmon.out

diff --git a/gmon.out b/gmon.out
deleted file mode 100644
index b8c8afe6643f3141abc883e1308294547fcd2d59..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 21650
zcmeI4%WG3n5QlH-Ju-@gg0F&zMXjyxXhB->Q5V`&TP*bzd`4}nh_->c5Q>tO7TnZT
z-3Ubx3U1;qE`)%axREY=M1)%KK^96EB1&!1-#M8Z4zBzIeu0qt-I+5p=es9a=F+u+
z{#fwOEAujx#;ZoIGz38pVuQUG2l{&kqpZqBbc3HXKm#;D12jMbG(ZD1Km#;D12jMb
zG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1
zKm#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12piz24drHL)kGM
zN()xRihv`lj5Jy3DwZQREffG(KZLR?g5sx8=0|Ylb13%j^jzAL$xwD$2;PM<x5kJo
zkOj1(h=V**Y{aG2qU@KY3c~;!aeZVelsg>?B{Z}V*R&Z8Uz}IC0k9D_!7yO!1%;{E
zP<{srB|v8cNnAXf)2XG($RxJy3e+q#vZBVwJiCQDz`h9LfVRaN>C!Z}Cb7&&0C#Rb
zDZr0foh=PWE>|c3hL&ib4DQ~G(()_IAhu~9qpaShPvJ(Lk=NUGO?Iu3T(!dGdW^Ep
z$c$Z+Xhdn;SYTnqhoTRy>&t1bPi{lGKxo%YY%GJ@Pim8q*?80k@G+*42CRt2xeu@t
zxHaQ|Zj^VB^CNjc0rFj>2xx;l2X&i`)PC1U7I5p0LJsf%hoW2!aIr%n4|s$}?;-`j
zp9KmjIGe_9U1Vy9k<pzB@fIUvZ5}+|t<a3f)<X)dfa&P@Sa|<R$4LMNqNZIoE$U<8
zI^M47FfP90klVkCj7<Rc_h}@7QEX(PjTF%RZjVOddyMq<Dx`cE@ge6!$%mS~UV&C0
zG6#%wG->H9Acw=`1}y>7?F!8aBbV`Z5qmL%sDrVC9t6--iDWvB96zjI%_3k?w~^&`
za~1~A7^#Y2?z9K<BZ)TcMN0cv7($wBYC%pKamUia)1-cXEZjcf!L#EyfKi`nAI==}
zBK3eu>EbC5z8&?T_N)h^=M;Wn@y`aWHjW+@NMn==jA2N7DBRCe9{Z0)&on^UEdVDZ
Pi^p!kjg#y%@>t<7x~113

diff --git a/src/completion.c b/src/completion.c
index 3e2df42..742025c 100644
--- a/src/completion.c
+++ b/src/completion.c
@@ -31,16 +31,22 @@
 extern VbCore vb;
 
 static struct {
-    int   count;
-    char  *prefix;
-    int   active;
-} comps;
+    int   count;   /* command count before the completed content */
+    char  *prefix; /* prefix that marks the completion ':', '/', ':open', ... */
+    int   active;  /* number of the current active tree item */
+    char  *text;   /* text of the current active tree item */
+} comp;
+
+typedef struct {
+    GtkTreeView *tree;
+    gboolean    back;
+} cursor;
 
 static gboolean init_completion(GList *source);
 static void show(GtkTreeView *tree);
 static void update(GtkTreeView *tree, gboolean back);
-static void echo_selection(GtkTreeSelection *sel);
-static char *get_text(GtkTreeView *tree);
+static gboolean tree_selection_func(GtkTreeSelection *selection,
+    GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data);
 
 gboolean completion_complete(gboolean back)
 {
@@ -53,15 +59,11 @@ gboolean completion_complete(gboolean back)
     type  = vb_get_input_parts(input, &prefix, &suffix);
 
     if (vb.state.mode & VB_MODE_COMPLETE) {
-        char *text = get_text(GTK_TREE_VIEW(vb.gui.compbox));
-        if (!strcmp(input, text)) {
+        if (comp.text && !strcmp(input, comp.text)) {
             /* step through the next/prev completion item */
             update(GTK_TREE_VIEW(vb.gui.compbox), back);
-            g_free(text);
-
             return true;
         }
-        g_free(text);
         /* if current input isn't the content of the completion item, stop
          * completion and start it after that again */
         completion_clean();
@@ -90,7 +92,7 @@ gboolean completion_complete(gboolean back)
     } else if (type == VB_INPUT_COMMAND) {
         char *command = NULL;
         /* remove counts before command and save it to print it later in inputbox */
-        comps.count = g_ascii_strtoll(suffix, &command, 10);
+        comp.count = g_ascii_strtoll(suffix, &command, 10);
 
         source = g_list_sort(command_get_by_prefix(command), (GCompareFunc)g_strcmp0);
         hasItems = init_completion(source);
@@ -107,7 +109,7 @@ gboolean completion_complete(gboolean back)
 
     vb_set_mode(VB_MODE_COMMAND | VB_MODE_COMPLETE, false);
 
-    OVERWRITE_STRING(comps.prefix, prefix);
+    OVERWRITE_STRING(comp.prefix, prefix);
     show(GTK_TREE_VIEW(vb.gui.compbox));
 
     return true;
@@ -119,9 +121,10 @@ void completion_clean(void)
         gtk_widget_destroy(vb.gui.compbox);
         vb.gui.compbox = NULL;
     }
-    OVERWRITE_STRING(comps.prefix, NULL);
-    comps.count = 0;
-    comps.active = 0;
+    OVERWRITE_STRING(comp.prefix, NULL);
+    OVERWRITE_STRING(comp.text, NULL);
+    comp.count = 0;
+    comp.active = 0;
 
     /* remove completion flag from mode */
     vb.state.mode &= ~VB_MODE_COMPLETE;
@@ -151,6 +154,10 @@ static gboolean init_completion(GList *source)
         NULL
     );
 
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gui->compbox));
+    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
+    gtk_tree_selection_set_select_function(selection, tree_selection_func, NULL, NULL);
+
     VB_WIDGET_OVERRIDE_COLOR(gui->compbox, GTK_STATE_NORMAL, &vb.style.comp_fg[VB_COMP_NORMAL]);
     VB_WIDGET_OVERRIDE_TEXT(gui->compbox, GTK_STATE_NORMAL, &vb.style.comp_fg[VB_COMP_NORMAL]);
     VB_WIDGET_OVERRIDE_BASE(gui->compbox, GTK_STATE_NORMAL, &vb.style.comp_bg[VB_COMP_NORMAL]);
@@ -161,9 +168,6 @@ static gboolean init_completion(GList *source)
     VB_WIDGET_OVERRIDE_BASE(gui->compbox, GTK_STATE_ACTIVE, &vb.style.comp_bg[VB_COMP_ACTIVE]);
     VB_WIDGET_OVERRIDE_BACKGROUND(gui->compbox, GTK_STATE_ACTIVE, &vb.style.comp_bg[VB_COMP_ACTIVE]);
 
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gui->compbox));
-    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
-
     gtk_tree_view_insert_column_with_attributes(
         GTK_TREE_VIEW(gui->compbox), -1, "", renderer, "text", COMP_ITEM, NULL
     );
@@ -194,10 +198,9 @@ static gboolean init_completion(GList *source)
     return hasItems;
 }
 
-/* allow to chenge the direction of display */
+/* allow to change the direction of display */
 static void show(GtkTreeView *tree)
 {
-    GtkTreeSelection *selection;
     GtkTreePath *path;
 
     /* this prevents the first item to be placed out of view if the completion
@@ -209,85 +212,61 @@ static void show(GtkTreeView *tree)
 
     /* select the first completion item */
     path = gtk_tree_path_new_from_indices(0, -1);
-
     gtk_tree_view_set_cursor(tree, path, NULL, false);
     gtk_tree_path_free(path);
-
-    selection = gtk_tree_view_get_selection(tree);
-
-    echo_selection(selection);
 }
 
 static void update(GtkTreeView *tree, gboolean back)
 {
     int rows;
-    GtkTreeSelection *selection;
     GtkTreePath *path;
 
     rows = gtk_tree_model_iter_n_children(gtk_tree_view_get_model(tree), NULL);
     if (back) {
         /* step back */
-        if (--comps.active < 0) {
-            comps.active = rows - 1;
+        if (--comp.active < 0) {
+            comp.active = rows - 1;
         }
     } else {
         /* step forward */
-        if (++comps.active >= rows) {
-            comps.active = 0;
+        if (++comp.active >= rows) {
+            comp.active = 0;
         }
     }
 
+    while (gtk_events_pending()) {
+        gtk_main_iteration();
+    }
     /* get new path and move cursor to it */
-    path = gtk_tree_path_new_from_indices(comps.active, -1);
+    path = gtk_tree_path_new_from_indices(comp.active, -1);
     gtk_tree_view_set_cursor(tree, path, NULL, false);
     gtk_tree_path_free(path);
-
-    selection = gtk_tree_view_get_selection(tree);
-    echo_selection(selection);
 }
 
-static void echo_selection(GtkTreeSelection *sel)
+static gboolean tree_selection_func(GtkTreeSelection *selection,
+    GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data)
 {
+    char *value;
     GtkTreeIter iter;
-    GtkTreeModel *model;
 
-    if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
-        char *value;
+    /* if not selected means the item is going to be selected which we are
+     * interested in */
+    if (!selected && gtk_tree_model_get_iter(model, &iter, path)) {
         gtk_tree_model_get(model, &iter, COMP_ITEM, &value, -1);
-        if (comps.count) {
-            vb_echo_force(VB_MSG_NORMAL, false, "%s%d%s", comps.prefix, comps.count, value);
-        } else {
-            vb_echo_force(VB_MSG_NORMAL, false, "%s%s", comps.prefix, value);
+        /* save the content of the selected item so wen can access it easy */
+        if (comp.text) {
+            g_free(comp.text);
+            comp.text = NULL;
         }
-        g_free(value);
-    }
-}
-
-/**
- * Retrieves the full new allocated entry text for selected tree view item.
- * Returnes string must be freed.
- */
-static char *get_text(GtkTreeView *tree)
-{
-    char *text = NULL;
-    GtkTreeIter iter;
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-
-    /* select the first completion item */
-    model     = gtk_tree_view_get_model(tree);
-    selection = gtk_tree_view_get_selection(tree);
-
-    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
-        char *value;
-        gtk_tree_model_get(model, &iter, COMP_ITEM, &value, -1);
-        if (comps.count) {
-            text = g_strdup_printf("%s%d%s", comps.prefix, comps.count, value);
+        if (comp.count) {
+            comp.text = g_strdup_printf("%s%d%s", comp.prefix, comp.count, value);
         } else {
-            text = g_strdup_printf("%s%s", comps.prefix, value);
+            comp.text = g_strdup_printf("%s%s", comp.prefix, value);
         }
+        /* print the text also into inputbox */
+        vb_echo_force(VB_MSG_NORMAL, false, "%s", comp.text);
         g_free(value);
     }
 
-    return text;
+    return true;
 }
-- 
2.20.1