Proper support for Ctrl/Shift/Alt modifiers in key & mouse mappings
This commit is contained in:
		
							parent
							
								
									ab28c9a8b9
								
							
						
					
					
						commit
						b2eae528ed
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| VERSION = git-20131231 | ||||
| VERSION = git-20140102 | ||||
| 
 | ||||
| PREFIX    = /usr/local | ||||
| MANPREFIX = $(PREFIX)/share/man | ||||
|  | ||||
| @ -27,15 +27,14 @@ typedef void* arg_t; | ||||
| typedef bool (*command_f)(arg_t); | ||||
| 
 | ||||
| typedef struct { | ||||
| 	bool ctrl; | ||||
| 	unsigned int mask; | ||||
| 	KeySym ksym; | ||||
| 	command_f cmd; | ||||
| 	arg_t arg; | ||||
| } keymap_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	bool ctrl; | ||||
| 	bool shift; | ||||
| 	unsigned int mask; | ||||
| 	unsigned int button; | ||||
| 	command_f cmd; | ||||
| 	arg_t arg; | ||||
|  | ||||
							
								
								
									
										161
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								config.def.h
									
									
									
									
									
								
							| @ -76,113 +76,112 @@ static const bool RENDER_WHITE_ALPHA = false; | ||||
| 
 | ||||
| /* keyboard mappings for image and thumbnail mode: */ | ||||
| static const keymap_t keys[] = { | ||||
| 	/* ctrl   key               function              argument */ | ||||
| 	{ false,  XK_q,             it_quit,              (arg_t) None }, | ||||
| 	{ false,  XK_Return,        it_switch_mode,       (arg_t) None }, | ||||
| 	{ false,  XK_f,             it_toggle_fullscreen, (arg_t) None }, | ||||
| 	{ false,  XK_b,             it_toggle_bar,        (arg_t) None }, | ||||
| 	/* modifiers    key               function              argument */ | ||||
| 	{ 0,            XK_q,             it_quit,              (arg_t) None }, | ||||
| 	{ 0,            XK_Return,        it_switch_mode,       (arg_t) None }, | ||||
| 	{ 0,            XK_f,             it_toggle_fullscreen, (arg_t) None }, | ||||
| 	{ 0,            XK_b,             it_toggle_bar,        (arg_t) None }, | ||||
| 
 | ||||
| 	{ false,  XK_r,             it_reload_image,      (arg_t) None }, | ||||
| 	{ false,  XK_R,             t_reload_all,         (arg_t) None }, | ||||
| 	{ false,  XK_D,             it_remove_image,      (arg_t) None }, | ||||
| 	{ 0,            XK_r,             it_reload_image,      (arg_t) None }, | ||||
| 	{ 0,            XK_R,             t_reload_all,         (arg_t) None }, | ||||
| 	{ 0,            XK_D,             it_remove_image,      (arg_t) None }, | ||||
| 
 | ||||
| 	{ false,  XK_n,             i_navigate,           (arg_t) +1 }, | ||||
| 	{ false,  XK_space,         i_navigate,           (arg_t) +1 }, | ||||
| 	{ false,  XK_p,             i_navigate,           (arg_t) -1 }, | ||||
| 	{ false,  XK_BackSpace,     i_navigate,           (arg_t) -1 }, | ||||
| 	{ false,  XK_bracketright,  i_navigate,           (arg_t) +10 }, | ||||
| 	{ false,  XK_bracketleft,   i_navigate,           (arg_t) -10 }, | ||||
| 	{ true,   XK_6,             i_alternate,          (arg_t) None }, | ||||
| 	{ false,  XK_g,             it_first,             (arg_t) None }, | ||||
| 	{ false,  XK_G,             it_n_or_last,         (arg_t) None }, | ||||
| 	{ 0,            XK_n,             i_navigate,           (arg_t) +1 }, | ||||
| 	{ 0,            XK_space,         i_navigate,           (arg_t) +1 }, | ||||
| 	{ 0,            XK_p,             i_navigate,           (arg_t) -1 }, | ||||
| 	{ 0,            XK_BackSpace,     i_navigate,           (arg_t) -1 }, | ||||
| 	{ 0,            XK_bracketright,  i_navigate,           (arg_t) +10 }, | ||||
| 	{ 0,            XK_bracketleft,   i_navigate,           (arg_t) -10 }, | ||||
| 	{ ControlMask,  XK_6,             i_alternate,          (arg_t) None }, | ||||
| 	{ 0,            XK_g,             it_first,             (arg_t) None }, | ||||
| 	{ 0,            XK_G,             it_n_or_last,         (arg_t) None }, | ||||
| 
 | ||||
| 	{ true,   XK_n,             i_navigate_frame,     (arg_t) +1 }, | ||||
| 	{ true,   XK_p,             i_navigate_frame,     (arg_t) -1 }, | ||||
| 	{ true,   XK_space,         i_toggle_animation,   (arg_t) None }, | ||||
| 	{ ControlMask,  XK_n,             i_navigate_frame,     (arg_t) +1 }, | ||||
| 	{ ControlMask,  XK_p,             i_navigate_frame,     (arg_t) -1 }, | ||||
| 	{ ControlMask,  XK_space,         i_toggle_animation,   (arg_t) None }, | ||||
| 
 | ||||
| 	{ false,  XK_m,             it_toggle_image_mark, (arg_t) None }, | ||||
| 	{ false,  XK_M,             it_reverse_marks,     (arg_t) None }, | ||||
| 	{ false,  XK_N,             it_navigate_marked,   (arg_t) +1 }, | ||||
| 	{ false,  XK_P,             it_navigate_marked,   (arg_t) -1 }, | ||||
| 	{ 0,            XK_m,             it_toggle_image_mark, (arg_t) None }, | ||||
| 	{ 0,            XK_M,             it_reverse_marks,     (arg_t) None }, | ||||
| 	{ 0,            XK_N,             it_navigate_marked,   (arg_t) +1 }, | ||||
| 	{ 0,            XK_P,             it_navigate_marked,   (arg_t) -1 }, | ||||
| 
 | ||||
| 	{ false,  XK_h,             it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ false,  XK_Left,          it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ false,  XK_j,             it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ false,  XK_Down,          it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ false,  XK_k,             it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ false,  XK_Up,            it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ false,  XK_l,             it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 	{ false,  XK_Right,         it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 	{ 0,            XK_h,             it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ 0,            XK_Left,          it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ 0,            XK_j,             it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ 0,            XK_Down,          it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ 0,            XK_k,             it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ 0,            XK_Up,            it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ 0,            XK_l,             it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 	{ 0,            XK_Right,         it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 
 | ||||
| 	{ true,   XK_h,             it_scroll_screen,     (arg_t) DIR_LEFT }, | ||||
| 	{ true,   XK_Left,          it_scroll_screen,     (arg_t) DIR_LEFT }, | ||||
| 	{ true,   XK_j,             it_scroll_screen,     (arg_t) DIR_DOWN }, | ||||
| 	{ true,   XK_Down,          it_scroll_screen,     (arg_t) DIR_DOWN }, | ||||
| 	{ true,   XK_k,             it_scroll_screen,     (arg_t) DIR_UP }, | ||||
| 	{ true,   XK_Up,            it_scroll_screen,     (arg_t) DIR_UP }, | ||||
| 	{ true,   XK_l,             it_scroll_screen,     (arg_t) DIR_RIGHT }, | ||||
| 	{ true,   XK_Right,         it_scroll_screen,     (arg_t) DIR_RIGHT }, | ||||
| 	{ ControlMask,  XK_h,             it_scroll_screen,     (arg_t) DIR_LEFT }, | ||||
| 	{ ControlMask,  XK_Left,          it_scroll_screen,     (arg_t) DIR_LEFT }, | ||||
| 	{ ControlMask,  XK_j,             it_scroll_screen,     (arg_t) DIR_DOWN }, | ||||
| 	{ ControlMask,  XK_Down,          it_scroll_screen,     (arg_t) DIR_DOWN }, | ||||
| 	{ ControlMask,  XK_k,             it_scroll_screen,     (arg_t) DIR_UP }, | ||||
| 	{ ControlMask,  XK_Up,            it_scroll_screen,     (arg_t) DIR_UP }, | ||||
| 	{ ControlMask,  XK_l,             it_scroll_screen,     (arg_t) DIR_RIGHT }, | ||||
| 	{ ControlMask,  XK_Right,         it_scroll_screen,     (arg_t) DIR_RIGHT }, | ||||
| 
 | ||||
| 	{ false,  XK_H,             i_scroll_to_edge,     (arg_t) DIR_LEFT }, | ||||
| 	{ false,  XK_J,             i_scroll_to_edge,     (arg_t) DIR_DOWN }, | ||||
| 	{ false,  XK_K,             i_scroll_to_edge,     (arg_t) DIR_UP }, | ||||
| 	{ false,  XK_L,             i_scroll_to_edge,     (arg_t) DIR_RIGHT }, | ||||
| 	{ 0,            XK_H,             i_scroll_to_edge,     (arg_t) DIR_LEFT }, | ||||
| 	{ 0,            XK_J,             i_scroll_to_edge,     (arg_t) DIR_DOWN }, | ||||
| 	{ 0,            XK_K,             i_scroll_to_edge,     (arg_t) DIR_UP }, | ||||
| 	{ 0,            XK_L,             i_scroll_to_edge,     (arg_t) DIR_RIGHT }, | ||||
| 
 | ||||
| 	{ false,  XK_plus,          i_zoom,               (arg_t) +1 }, | ||||
| 	{ false,  XK_KP_Add,        i_zoom,               (arg_t) +1 }, | ||||
| 	{ false,  XK_minus,         i_zoom,               (arg_t) -1 }, | ||||
| 	{ false,  XK_KP_Subtract,   i_zoom,               (arg_t) -1 }, | ||||
| 	{ false,  XK_equal,         i_set_zoom,           (arg_t) 100 }, | ||||
| 	{ false,  XK_w,             i_fit_to_win,         (arg_t) SCALE_FIT }, | ||||
| 	{ false,  XK_e,             i_fit_to_win,         (arg_t) SCALE_WIDTH }, | ||||
| 	{ false,  XK_E,             i_fit_to_win,         (arg_t) SCALE_HEIGHT }, | ||||
| 	{ false,  XK_W,             i_fit_to_img,         (arg_t) None }, | ||||
| 	{ 0,            XK_plus,          i_zoom,               (arg_t) +1 }, | ||||
| 	{ 0,            XK_KP_Add,        i_zoom,               (arg_t) +1 }, | ||||
| 	{ 0,            XK_minus,         i_zoom,               (arg_t) -1 }, | ||||
| 	{ 0,            XK_KP_Subtract,   i_zoom,               (arg_t) -1 }, | ||||
| 	{ 0,            XK_equal,         i_set_zoom,           (arg_t) 100 }, | ||||
| 	{ 0,            XK_w,             i_fit_to_win,         (arg_t) SCALE_FIT }, | ||||
| 	{ 0,            XK_e,             i_fit_to_win,         (arg_t) SCALE_WIDTH }, | ||||
| 	{ 0,            XK_E,             i_fit_to_win,         (arg_t) SCALE_HEIGHT }, | ||||
| 	{ 0,            XK_W,             i_fit_to_img,         (arg_t) None }, | ||||
| 
 | ||||
| 	{ false,  XK_less,          i_rotate,             (arg_t) DEGREE_270 }, | ||||
| 	{ false,  XK_greater,       i_rotate,             (arg_t) DEGREE_90 }, | ||||
| 	{ false,  XK_question,      i_rotate,             (arg_t) DEGREE_180 }, | ||||
| 	{ 0,            XK_less,          i_rotate,             (arg_t) DEGREE_270 }, | ||||
| 	{ 0,            XK_greater,       i_rotate,             (arg_t) DEGREE_90 }, | ||||
| 	{ 0,            XK_question,      i_rotate,             (arg_t) DEGREE_180 }, | ||||
| 
 | ||||
| 	{ false,  XK_bar,           i_flip,               (arg_t) FLIP_HORIZONTAL }, | ||||
| 	{ false,  XK_underscore,    i_flip,               (arg_t) FLIP_VERTICAL }, | ||||
| 	{ 0,            XK_bar,           i_flip,               (arg_t) FLIP_HORIZONTAL }, | ||||
| 	{ 0,            XK_underscore,    i_flip,               (arg_t) FLIP_VERTICAL }, | ||||
| 
 | ||||
| 	{ false,  XK_a,             i_toggle_antialias,   (arg_t) None }, | ||||
| 	{ false,  XK_A,             it_toggle_alpha,      (arg_t) None }, | ||||
| 	{ 0,            XK_a,             i_toggle_antialias,   (arg_t) None }, | ||||
| 	{ 0,            XK_A,             it_toggle_alpha,      (arg_t) None }, | ||||
| 
 | ||||
| 	/* decrease/increase/reset gamma */ | ||||
| 	{ false,  XK_braceleft,     i_change_gamma,       (arg_t) -1 }, | ||||
| 	{ false,  XK_braceright,    i_change_gamma,       (arg_t) +1 }, | ||||
| 	{ true,   XK_G,             i_change_gamma,       (arg_t)  0 }, | ||||
| 	{ 0,            XK_braceleft,     i_change_gamma,       (arg_t) -1 }, | ||||
| 	{ 0,            XK_braceright,    i_change_gamma,       (arg_t) +1 }, | ||||
| 	{ ControlMask,  XK_G,             i_change_gamma,       (arg_t)  0 }, | ||||
| 
 | ||||
| 	/* open current image with given program: */ | ||||
| 	{ true,   XK_g,             it_open_with,         (arg_t) "gimp" }, | ||||
| 	{ ControlMask,  XK_g,             it_open_with,         (arg_t) "gimp" }, | ||||
| 
 | ||||
| 	/* run shell command line on current file ("$SXIV_IMG"): */ | ||||
| 	{ true,   XK_less,          it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_less,          it_shell_cmd,         (arg_t) \ | ||||
| 			"mogrify -rotate -90 \"$SXIV_IMG\"" }, | ||||
| 	{ true,   XK_greater,       it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_greater,       it_shell_cmd,         (arg_t) \ | ||||
| 			"mogrify -rotate +90 \"$SXIV_IMG\"" }, | ||||
| 	{ true,   XK_question,      it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_question,      it_shell_cmd,         (arg_t) \ | ||||
| 			"mogrify -rotate 180 \"$SXIV_IMG\"" }, | ||||
| 	{ true,   XK_comma,         it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_comma,         it_shell_cmd,         (arg_t) \ | ||||
| 			"jpegtran -rotate 270 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" }, | ||||
| 	{ true,   XK_period,        it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_period,        it_shell_cmd,         (arg_t) \ | ||||
| 			"jpegtran -rotate  90 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" }, | ||||
| 	{ true,   XK_slash,         it_shell_cmd,         (arg_t) \ | ||||
| 	{ ControlMask,  XK_slash,         it_shell_cmd,         (arg_t) \ | ||||
| 			"jpegtran -rotate 180 -copy all -outfile \"$SXIV_IMG\" \"$SXIV_IMG\"" }, | ||||
| }; | ||||
| 
 | ||||
| /* mouse button mappings for image mode: */ | ||||
| static const button_t buttons[] = { | ||||
| 	/* ctrl   shift   button    function              argument */ | ||||
| 	{ false,  false,  Button1,  i_navigate,           (arg_t) +1 }, | ||||
| 	{ false,  false,  Button3,  i_navigate,           (arg_t) -1 }, | ||||
| 	{ false,  false,  Button2,  i_drag,               (arg_t) None }, | ||||
| 	{ false,  false,  Button4,  it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ false,  false,  Button5,  it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ false,  true,   Button4,  it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ false,  true,   Button5,  it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 	{ true,   false,  Button4,  i_zoom,               (arg_t) +1 }, | ||||
| 	{ true,   false,  Button5,  i_zoom,               (arg_t) -1 }, | ||||
| 	/* modifiers    button            function              argument */ | ||||
| 	{ 0,            Button1,          i_navigate,           (arg_t) +1 }, | ||||
| 	{ 0,            Button3,          i_navigate,           (arg_t) -1 }, | ||||
| 	{ 0,            Button2,          i_drag,               (arg_t) None }, | ||||
| 	{ 0,            Button4,          it_scroll_move,       (arg_t) DIR_UP }, | ||||
| 	{ 0,            Button5,          it_scroll_move,       (arg_t) DIR_DOWN }, | ||||
| 	{ ShiftMask,    Button4,          it_scroll_move,       (arg_t) DIR_LEFT }, | ||||
| 	{ ShiftMask,    Button5,          it_scroll_move,       (arg_t) DIR_RIGHT }, | ||||
| 	{ ControlMask,  Button4,          i_zoom,               (arg_t) +1 }, | ||||
| 	{ ControlMask,  Button5,          i_zoom,               (arg_t) -1 }, | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										30
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								main.c
									
									
									
									
									
								
							| @ -418,30 +418,28 @@ void clear_resize(void) | ||||
| 	resized = false; | ||||
| } | ||||
| 
 | ||||
| bool keymask(const keymap_t *k, unsigned int state) | ||||
| { | ||||
| 	return (k->ctrl ? ControlMask : 0) == (state & ControlMask); | ||||
| } | ||||
| 
 | ||||
| bool buttonmask(const button_t *b, unsigned int state) | ||||
| { | ||||
| 	return ((b->ctrl ? ControlMask : 0) | (b->shift ? ShiftMask : 0)) == | ||||
| 	       (state & (ControlMask | ShiftMask)); | ||||
| } | ||||
| #define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask)) | ||||
| 
 | ||||
| void on_keypress(XKeyEvent *kev) | ||||
| { | ||||
| 	int i; | ||||
| 	KeySym ksym; | ||||
| 	unsigned int sh; | ||||
| 	KeySym ksym, shksym; | ||||
| 	char key; | ||||
| 
 | ||||
| 	if (kev == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (kev->state & ShiftMask) { | ||||
| 		kev->state &= ~ShiftMask; | ||||
| 		XLookupString(kev, &key, 1, &shksym, NULL); | ||||
| 		kev->state |= ShiftMask; | ||||
| 	} | ||||
| 	XLookupString(kev, &key, 1, &ksym, NULL); | ||||
| 	sh = (kev->state & ShiftMask) && ksym != shksym ? ShiftMask : 0; | ||||
| 
 | ||||
| 	if ((ksym == XK_Escape || (key >= '0' && key <= '9')) && | ||||
| 	    (kev->state & ControlMask) == 0) | ||||
| 	if ((ksym == XK_Escape && MODMASK(kev->state) == 0) || | ||||
| 		  (key >= '0' && key <= '9')) | ||||
| 	{ | ||||
| 		/* number prefix for commands */ | ||||
| 		prefix = ksym == XK_Escape ? 0 : prefix * 10 + (int) (key - '0'); | ||||
| @ -449,7 +447,9 @@ void on_keypress(XKeyEvent *kev) | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < ARRLEN(keys); i++) { | ||||
| 		if (keys[i].ksym == ksym && keymask(&keys[i], kev->state)) { | ||||
| 		if (keys[i].ksym == ksym && | ||||
| 		    MODMASK(keys[i].mask | sh) == MODMASK(kev->state)) | ||||
| 		{ | ||||
| 			if (keys[i].cmd != NULL && keys[i].cmd(keys[i].arg)) | ||||
| 				redraw(); | ||||
| 			prefix = 0; | ||||
| @ -471,7 +471,7 @@ void on_buttonpress(XButtonEvent *bev) | ||||
| 
 | ||||
| 		for (i = 0; i < ARRLEN(buttons); i++) { | ||||
| 			if (buttons[i].button == bev->button && | ||||
| 			    buttonmask(&buttons[i], bev->state)) | ||||
| 			    MODMASK(buttons[i].mask) == MODMASK(bev->state)) | ||||
| 			{ | ||||
| 				if (buttons[i].cmd != NULL && buttons[i].cmd(buttons[i].arg)) | ||||
| 					redraw(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert Münnich
						Bert Münnich