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