Revision 05366e96d1813c0303ee7b52586f8e98e8a85670
sadrul at pidgin.im
sadrul at pidgin.im
Wed Mar 7 07:43:14 EST 2007
o -----------------------------------------------------------------
| Revision: 05366e96d1813c0303ee7b52586f8e98e8a85670
| Ancestor: b108b039af0c7494cb982002b428ea9d2fcd7de4
| Author: sadrul at pidgin.im
| Date: 2007-03-07T12:58:34
| Branch: im.pidgin.pidgin
|
| Modified files:
| console/libgnt/gntbindable.c console/libgnt/gntkeys.c
| console/libgnt/gntkeys.h console/libgnt/gntmain.c
| console/libgnt/gntwm.c console/libgnt/gntwm.h
|
| ChangeLog:
|
| 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.
|
| ============================================================
| --- console/libgnt/gntbindable.c c67dfa77a00ccc5d309030609e8b75c18dd3e468
| +++ console/libgnt/gntbindable.c 5aea477bb5e2b0aeb98158764a3be87509d16e56
| @@ -155,6 +155,7 @@ register_binding(GntBindableClass *klass
|
| if (name == NULL || *name == '\0') {
| g_hash_table_remove(klass->bindings, (char*)trigger);
| + gnt_keys_del_combination(trigger);
| return;
| }
|
| @@ -171,6 +172,7 @@ register_binding(GntBindableClass *klass
| 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,
| ============================================================
| --- console/libgnt/gntkeys.c 250339eba2cef3d9bb3f677eba66438cacc66d28
| +++ console/libgnt/gntkeys.c 1824b596048d2450d4bc705f2790cb47da77e0b2
| @@ -1,5 +1,6 @@
| #include "gntkeys.h"
|
| +#include <glib.h>
| #include <stdlib.h>
| #include <string.h>
|
| @@ -8,7 +9,6 @@ char *gnt_key_cright;
| char *gnt_key_cleft;
| char *gnt_key_cright;
|
| -
| static const char *term;
|
| void gnt_init_keys()
| @@ -48,3 +48,101 @@ void gnt_keys_refine(char *text)
| }
| }
|
| +/**
| + * 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");
| +}
| +
| ============================================================
| --- console/libgnt/gntkeys.h a0d51d2e193ab717ac9bd43974e5ed39b3d02686
| +++ console/libgnt/gntkeys.h 94ecd340747dd609c5ecf449bf6e877416639a58
| @@ -82,7 +82,11 @@ void gnt_keys_refine(char *text);
| 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 <term.h>.
| * #undef them to make life easier for everyone. */
|
| ============================================================
| --- console/libgnt/gntmain.c b16dfe5d58954e5593a7d5c555075dcbe3455811
| +++ console/libgnt/gntmain.c 51763c45c696a9aced50314725cc02ee474a0d4a
| @@ -181,6 +181,8 @@ io_invoke(GIOChannel *source, GIOConditi
| {
| 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 @@ io_invoke(GIOChannel *source, GIOConditi
| else if (rd == 0)
| {
| endwin();
| + return;
| printf("EOF\n");
| raise(SIGABRT);
| }
| @@ -201,9 +204,20 @@ io_invoke(GIOChannel *source, GIOConditi
|
| 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;
| }
|
| ============================================================
| --- console/libgnt/gntwm.c 9441f768edcb853f6067dc9fea5c83a5eb353841
| +++ console/libgnt/gntwm.c e136d8a3f24641ab8ac336daec08bee90f906997
| @@ -875,6 +875,8 @@ gnt_wm_class_init(GntWMClass *klass)
| 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 @@ gnt_wm_class_init(GntWMClass *klass)
| "\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 @@ time_t gnt_wm_get_idle_time()
| 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 @@ void gnt_wm_process_input(GntWM *wm, con
| 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 @@ void gnt_wm_process_input(GntWM *wm, con
| 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 @@ void gnt_wm_process_input(GntWM *wm, con
| 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 @@ void gnt_wm_process_input(GntWM *wm, con
| 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
| ============================================================
| --- console/libgnt/gntwm.h 35afc169a156b4dc90dafb0cebc36ebf31e0b0ab
| +++ console/libgnt/gntwm.h 8fbfeb952f9b58cabd43172e85dd60145ae5b05f
| @@ -151,7 +151,7 @@ void gnt_wm_window_close(GntWM *wm, GntW
|
| 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);
|
To get the patch for this revision, please do this:
mtn log --last 1 --diffs --from 05366e96d1813c0303ee7b52586f8e98e8a85670
More information about the Commits
mailing list