From a75c7f694a21a0f8c1e7d890cf7b42b524448c38 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Sun, 11 Nov 2007 15:40:01 +0100 Subject: [PATCH] mouse buttons are now configurable for click on tag names --- awesomerc | 33 ++++++++++++++++++++++++++++ config.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++----- config.h | 17 ++++++++++++++- event.c | 31 ++++++++++---------------- 4 files changed, 120 insertions(+), 26 deletions(-) diff --git a/awesomerc b/awesomerc index d6bc8281..6efa5811 100644 --- a/awesomerc +++ b/awesomerc @@ -115,6 +115,39 @@ rules mouse { modkey = "Mod4" + # For click on tag + tag + { + button = "1" + command = "view" + } + tag + { + button = "1" + modkey = {"Mod4"} + command = "tag" + } + tag + { + button = "3" + command = "toggleview" + } + tag + { + button = "3" + modkey = {"Mod4"} + command = "toggletag" + } + tag + { + button = "4" + command = "view_tag_next" + } + tag + { + button = "5" + command = "view_tag_previous" + } } keys diff --git a/config.c b/config.c index ac36499d..6a85a2d2 100644 --- a/config.c +++ b/config.c @@ -50,6 +50,13 @@ typedef struct KeySym keysym; } KeyMod; +/** Link a name to a mouse button symbol */ +typedef struct +{ + const char *name; + unsigned int button; +} MouseButton; + /** List of available UI bindable callbacks and functions */ const NameFuncLink UicbList[] = { /* util.c */ @@ -111,6 +118,16 @@ static const KeyMod KeyModList[] = {NULL, 0} }; +/** List of button name and corresponding X11 mask codes */ +static const MouseButton MouseButtonList[] = +{ + {"1", Button1}, + {"2", Button2}, + {"3", Button3}, + {"4", Button4}, + {"5", Button5}, + {NULL, 0} +}; /** List of available layouts and link between name and functions */ static const NameFuncLink LayoutsList[] = { @@ -138,6 +155,23 @@ key_mask_lookup(const char *keyname) return 0; } +/** Lookup for a mouse button from its name + * \param button Mouse button name + * \return Mouse button or 0 if not found + */ +static unsigned int +mouse_button_lookup(const char *button) +{ + int i; + + if(button) + for(i = 0; MouseButtonList[i].name; i++) + if(!a_strcmp(button, MouseButtonList[i].name)) + return MouseButtonList[i].button; + + return 0; +} + /** Parse configuration file and initialize some stuff * \param disp Display ref * \param scr Screen number @@ -228,9 +262,16 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf) CFG_SEC((char *) "key", key_opts, CFGF_MULTI), CFG_END() }; + static cfg_opt_t mouse_tag_opts[] = + { + CFG_STR_LIST((char *) "modkey", (char *) "{}", CFGF_NONE), + CFG_STR((char *) "button", (char *) "None", CFGF_NONE), + CFG_STR((char *) "command", (char *) "", CFGF_NONE), + }; static cfg_opt_t mouse_opts[] = { CFG_STR((char *) "modkey", (char *) "Mod4", CFGF_NONE), + CFG_SEC((char *) "tag", mouse_tag_opts, CFGF_MULTI), CFG_END() }; static cfg_opt_t opts[] = @@ -247,7 +288,6 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf) unsigned int j = 0; const char *tmp, *homedir; char *confpath, buf[2]; - KeySym tmp_key; ssize_t confpath_len; if(confpatharg) @@ -363,7 +403,6 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf) compileregs(awesomeconf->rules, awesomeconf->nrules); /* Tags */ - awesomeconf->ntags = cfg_size(cfg_tags, "tag"); awesomeconf->tags = p_new(Tag, awesomeconf->ntags); for(i = 0; i < awesomeconf->ntags; i++) @@ -392,11 +431,25 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf) awesomeconf->tags[0].selected = True; awesomeconf->tags[0].was_selected = True; - /* Keys */ - tmp_key = key_mask_lookup(cfg_getstr(cfg_mouse, "modkey")); - awesomeconf->modkey = tmp_key ? tmp_key : Mod4Mask; - awesomeconf->numlockmask = get_numlockmask(awesomeconf->display); + /* Mouse */ + if(!(awesomeconf->modkey = key_mask_lookup(cfg_getstr(cfg_mouse, "modkey")))) + awesomeconf->modkey = Mod4Mask; + /* Mouse: tags click bindings */ + awesomeconf->buttons.ntag = cfg_size(cfg_mouse, "tag"); + awesomeconf->buttons.tag = p_new(Button, awesomeconf->buttons.ntag); + for(i = 0; i < awesomeconf->buttons.ntag; i++) + { + cfgsectmp = cfg_getnsec(cfg_mouse, "tag", i); + for(j = 0; j < cfg_size(cfgsectmp, "modkey"); j++) + awesomeconf->buttons.tag[i].mod |= key_mask_lookup(cfg_getnstr(cfgsectmp, "modkey", j)); + awesomeconf->buttons.tag[i].button = mouse_button_lookup(cfg_getstr(cfgsectmp, "button")); + awesomeconf->buttons.tag[i].func = name_func_lookup(cfg_getstr(cfgsectmp, "command"), UicbList); + awesomeconf->buttons.tag[i].arg = NULL; /* for now */ + } + + /* Keys */ + awesomeconf->numlockmask = get_numlockmask(awesomeconf->display); awesomeconf->nkeys = cfg_size(cfg_keys, "key"); awesomeconf->keys = p_new(Key, awesomeconf->nkeys); for(i = 0; i < awesomeconf->nkeys; i++) diff --git a/config.h b/config.h index 9ceac720..0ffbdc4a 100644 --- a/config.h +++ b/config.h @@ -61,6 +61,15 @@ typedef struct char *arg; } Key; +typedef struct Button Button; +struct Button +{ + unsigned long mod; + unsigned int button; + void (*func) (awesome_config *, char *); + char *arg; +}; + /** Status bar */ typedef struct { @@ -161,8 +170,14 @@ struct awesome_config Rule *rules; /** Number of rules in *rules */ int nrules; - /** Keys binding list */ + /** Keys bindings list */ Key *keys; + /** Mouse bindings list */ + struct + { + Button *tag; + int ntag; + } buttons; /** Number of keys binding in *keys */ int nkeys; /** Default modkey */ diff --git a/event.c b/event.c index 86e190de..5d01d81b 100644 --- a/event.c +++ b/event.c @@ -140,11 +140,11 @@ resizemouse(Client * c, awesome_config *awesomeconf) void handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf) { - int i, screen, x = 0, y = 0; + int i, j, screen, x = 0, y = 0; unsigned int udummy; Client *c; Window wdummy; - char buf[256]; + char arg[256]; XButtonPressedEvent *ev = &e->xbutton; for(screen = 0; screen < get_screen_count(e->xany.display); screen++) @@ -155,25 +155,18 @@ handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf) x += textwidth(e->xany.display, awesomeconf[screen].font, awesomeconf[screen].tags[i].name); if(ev->x < x) { - snprintf(buf, sizeof(buf), "%d", i + 1); - if(ev->button == Button1) + snprintf(arg, sizeof(arg), "%d", i + 1); + for(j = 0; j < awesomeconf[screen].buttons.ntag; j++) { - if(ev->state & awesomeconf[screen].modkey) - uicb_tag(&awesomeconf[screen], buf); - else - uicb_view(&awesomeconf[screen], buf); + if(ev->button == awesomeconf[screen].buttons.tag[j].button + && (ev->state == awesomeconf[screen].buttons.tag[j].mod + || ev->state == (awesomeconf[screen].buttons.tag[j].mod | awesomeconf[screen].numlockmask)) + && awesomeconf[screen].buttons.tag[j].func) + { + awesomeconf[screen].buttons.tag[j].func(&awesomeconf[screen], arg); + return; + } } - else if(ev->button == Button3) - { - if(ev->state & awesomeconf[screen].modkey) - uicb_toggletag(&awesomeconf[screen], awesomeconf[screen].tags[i].name); - else - uicb_toggleview(&awesomeconf[screen], awesomeconf[screen].tags[i].name); - } - else if(ev->button == Button4) - uicb_tag_viewnext(&awesomeconf[screen], NULL); - else if(ev->button == Button5) - uicb_tag_viewprev(&awesomeconf[screen], NULL); return; } }