# HG changeset patch # User Sadrul Habib Chowdhury # Date 1173272314 0 # Node ID c2c2a854f5b3419c551c58d5714c34d1baaaff44 # Parent 909e59dae1236c135a728b5ae36a4599c3fb5552 Change a bit how the keystrokes are processed. When a lot of keystrokes come in at the same time, the shortest key-combination is processed first. This should make typing fast over a very slow connection work properly. diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntbindable.c --- a/console/libgnt/gntbindable.c Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntbindable.c Wed Mar 07 12:58:34 2007 +0000 @@ -155,6 +155,7 @@ if (name == NULL || *name == '\0') { g_hash_table_remove(klass->bindings, (char*)trigger); + gnt_keys_del_combination(trigger); return; } @@ -171,6 +172,7 @@ param->action = action; param->list = list; g_hash_table_replace(klass->bindings, g_strdup(trigger), param); + gnt_keys_add_combination(trigger); } void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntkeys.c --- a/console/libgnt/gntkeys.c Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntkeys.c Wed Mar 07 12:58:34 2007 +0000 @@ -1,5 +1,6 @@ #include "gntkeys.h" +#include #include #include @@ -8,7 +9,6 @@ char *gnt_key_cleft; char *gnt_key_cright; - static const char *term; void gnt_init_keys() @@ -48,3 +48,101 @@ } } +/** + * The key-bindings will be saved in a tree. When a keystroke happens, GNT will + * find the longest sequence that matches a binding and return the length. + */ +#define SIZE 256 + +#define HAS_CHILD 1 << 0 +struct _node +{ + struct _node *next[SIZE]; + int ref; + int flags; +}; + +static struct _node root = {.ref = 1, .flags = HAS_CHILD}; + +static void add_path(struct _node *node, const char *path) +{ + struct _node *n = NULL; + if (!path || !*path) + return; + while (*path && node->next[*path]) { + node = node->next[*path]; + node->ref++; + path++; + } + if (!*path) + return; + n = g_new0(struct _node, 1); + n->ref = 1; + node->next[*path++] = n; + node->flags |= HAS_CHILD; + add_path(n, path); +} + +void gnt_keys_add_combination(const char *path) +{ + add_path(&root, path); +} + +static void del_path(struct _node *node, const char *path) +{ + struct _node *next = NULL; + + if (!*path) + return; + next = node->next[*path]; + if (!next) + return; + del_path(next, path + 1); + next->ref--; + if (next->ref == 0) { + node->next[*path] = NULL; + g_free(next); + } +} + +void gnt_keys_del_combination(const char *path) +{ + del_path(&root, path); +} + +int gnt_keys_find_combination(const char *path) +{ + int depth = 0; + struct _node *n = &root; + + while (*path && n->next[*path] && (n->flags & HAS_CHILD)) { + n = n->next[*path++]; + depth++; + } + + if (n->flags & HAS_CHILD) + depth = 0; + return depth; +} + +static void +print_path(struct _node *node, int depth) +{ + int i; + for (i = 0; i < SIZE; i++) { + if (node->next[i]) { + g_printerr("%*c (%d:%d)\n", depth, i, node->next[i]->ref, + node->next[i]->flags); + print_path(node->next[i], depth + 1); + } + } +} + +/* this is purely for debugging purposes. */ +void gnt_keys_print_combinations() +{ + g_printerr("--------\n"); + print_path(&root, 1); + g_printerr("--------\n"); +} + diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntkeys.h --- a/console/libgnt/gntkeys.h Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntkeys.h Wed Mar 07 12:58:34 2007 +0000 @@ -82,6 +82,10 @@ void gnt_init_keys(); void gnt_keys_refine(char *text); +void gnt_keys_add_combination(const char *path); +void gnt_keys_del_combination(const char *path); +int gnt_keys_find_combination(const char *path); + /* A lot of commonly used variable names are defined in . * #undef them to make life easier for everyone. */ diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntmain.c --- a/console/libgnt/gntmain.c Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntmain.c Wed Mar 07 12:58:34 2007 +0000 @@ -181,6 +181,8 @@ { char keys[256]; int rd = read(STDIN_FILENO, keys, sizeof(keys) - 1); + int processed; + char *k; if (rd < 0) { int ch = getch(); /* This should return ERR, but let's see what it really returns */ @@ -192,6 +194,7 @@ else if (rd == 0) { endwin(); + return; printf("EOF\n"); raise(SIGABRT); } @@ -201,8 +204,19 @@ if (mouse_enabled && detect_mouse_action(keys)) return TRUE; - - gnt_wm_process_input(wm, keys); + + processed = 0; + k = keys; + while (rd) { + char back; + int p = MAX(1, gnt_keys_find_combination(k)); + back = k[p]; + k[p] = '\0'; + gnt_wm_process_input(wm, k); + k[p] = back; + rd -= p; + k += p; + } return TRUE; } diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntwm.c --- a/console/libgnt/gntwm.c Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntwm.c Wed Mar 07 12:58:34 2007 +0000 @@ -875,6 +875,8 @@ static void gnt_wm_class_init(GntWMClass *klass) { + int i; + klass->new_window = gnt_wm_new_window_real; klass->decorate_window = NULL; klass->close_window = NULL; @@ -1004,6 +1006,14 @@ "\033" GNT_KEY_CTRL_K, NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); + + /* Make sure Alt+x are detected properly. */ + for (i = '0'; i <= '9'; i++) { + char str[] = "\033X"; + str[1] = i; + gnt_keys_add_combination(str); + } + GNTDEBUG; } @@ -1209,14 +1219,16 @@ return time(NULL) - last_active_time; } -void gnt_wm_process_input(GntWM *wm, const char *keys) +gboolean gnt_wm_process_input(GntWM *wm, const char *keys) { + gboolean ret = FALSE; + keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys); idle_update = TRUE; if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) - return; + return TRUE; /* Do some manual checking */ if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) { @@ -1247,7 +1259,7 @@ if (ox != x || oy != y) { gnt_screen_move_widget(widget, x, y); window_reverse(widget, TRUE, wm); - return; + return TRUE; } } else if (wm->mode == GNT_KP_MODE_RESIZE) { if (strcmp(keys, GNT_KEY_LEFT) == 0) { @@ -1264,14 +1276,14 @@ if (oh != h || ow != w) { gnt_screen_resize_widget(widget, w, h); window_reverse(widget, TRUE, wm); - return; + return TRUE; } } if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) { window_reverse(widget, FALSE, wm); wm->mode = GNT_KP_MODE_NORMAL; } - return; + return TRUE; } wm->event_stack = TRUE; @@ -1281,7 +1293,7 @@ if (wm->_list.window) { gnt_widget_destroy(wm->_list.window); wm->event_stack = FALSE; - return; + return TRUE; } } else if (keys[0] == '\033' && isdigit(keys[1]) && keys[2] == '\0') { /* Alt+x for quick switch */ @@ -1294,16 +1306,17 @@ list = g_list_append(list, GINT_TO_POINTER(n - 1)); switch_window_n(GNT_BINDABLE(wm), list); g_list_free(list); - return; + return TRUE; } if (wm->menu) - gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); + ret = gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); else if (wm->_list.window) - gnt_widget_key_pressed(wm->_list.window, keys); + ret = gnt_widget_key_pressed(wm->_list.window, keys); else if (wm->ordered) - gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys); + ret = gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys); wm->event_stack = FALSE; + return ret; } static void diff -r 909e59dae123 -r c2c2a854f5b3 console/libgnt/gntwm.h --- a/console/libgnt/gntwm.h Tue Mar 06 07:17:27 2007 +0000 +++ b/console/libgnt/gntwm.h Wed Mar 07 12:58:34 2007 +0000 @@ -151,7 +151,7 @@ void gnt_wm_window_close(GntWM *wm, GntWidget *widget); -void gnt_wm_process_input(GntWM *wm, const char *string); +gboolean gnt_wm_process_input(GntWM *wm, const char *string); gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget);