mouse buttons are now configurable for click on tag names

This commit is contained in:
Julien Danjou 2007-11-11 15:40:01 +01:00
parent 7604fa70b5
commit a75c7f694a
4 changed files with 120 additions and 26 deletions

View File

@ -115,6 +115,39 @@ rules
mouse mouse
{ {
modkey = "Mod4" 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 keys

View File

@ -50,6 +50,13 @@ typedef struct
KeySym keysym; KeySym keysym;
} KeyMod; } 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 */ /** List of available UI bindable callbacks and functions */
const NameFuncLink UicbList[] = { const NameFuncLink UicbList[] = {
/* util.c */ /* util.c */
@ -111,6 +118,16 @@ static const KeyMod KeyModList[] =
{NULL, 0} {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 */ /** List of available layouts and link between name and functions */
static const NameFuncLink LayoutsList[] = static const NameFuncLink LayoutsList[] =
{ {
@ -138,6 +155,23 @@ key_mask_lookup(const char *keyname)
return 0; 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 /** Parse configuration file and initialize some stuff
* \param disp Display ref * \param disp Display ref
* \param scr Screen number * \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_SEC((char *) "key", key_opts, CFGF_MULTI),
CFG_END() 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[] = static cfg_opt_t mouse_opts[] =
{ {
CFG_STR((char *) "modkey", (char *) "Mod4", CFGF_NONE), CFG_STR((char *) "modkey", (char *) "Mod4", CFGF_NONE),
CFG_SEC((char *) "tag", mouse_tag_opts, CFGF_MULTI),
CFG_END() CFG_END()
}; };
static cfg_opt_t opts[] = static cfg_opt_t opts[] =
@ -247,7 +288,6 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf)
unsigned int j = 0; unsigned int j = 0;
const char *tmp, *homedir; const char *tmp, *homedir;
char *confpath, buf[2]; char *confpath, buf[2];
KeySym tmp_key;
ssize_t confpath_len; ssize_t confpath_len;
if(confpatharg) if(confpatharg)
@ -363,7 +403,6 @@ parse_config(const char *confpatharg, awesome_config *awesomeconf)
compileregs(awesomeconf->rules, awesomeconf->nrules); compileregs(awesomeconf->rules, awesomeconf->nrules);
/* Tags */ /* Tags */
awesomeconf->ntags = cfg_size(cfg_tags, "tag"); awesomeconf->ntags = cfg_size(cfg_tags, "tag");
awesomeconf->tags = p_new(Tag, awesomeconf->ntags); awesomeconf->tags = p_new(Tag, awesomeconf->ntags);
for(i = 0; i < awesomeconf->ntags; i++) 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].selected = True;
awesomeconf->tags[0].was_selected = True; awesomeconf->tags[0].was_selected = True;
/* Keys */ /* Mouse */
tmp_key = key_mask_lookup(cfg_getstr(cfg_mouse, "modkey")); if(!(awesomeconf->modkey = key_mask_lookup(cfg_getstr(cfg_mouse, "modkey"))))
awesomeconf->modkey = tmp_key ? tmp_key : Mod4Mask; awesomeconf->modkey = Mod4Mask;
awesomeconf->numlockmask = get_numlockmask(awesomeconf->display);
/* 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->nkeys = cfg_size(cfg_keys, "key");
awesomeconf->keys = p_new(Key, awesomeconf->nkeys); awesomeconf->keys = p_new(Key, awesomeconf->nkeys);
for(i = 0; i < awesomeconf->nkeys; i++) for(i = 0; i < awesomeconf->nkeys; i++)

View File

@ -61,6 +61,15 @@ typedef struct
char *arg; char *arg;
} Key; } Key;
typedef struct Button Button;
struct Button
{
unsigned long mod;
unsigned int button;
void (*func) (awesome_config *, char *);
char *arg;
};
/** Status bar */ /** Status bar */
typedef struct typedef struct
{ {
@ -161,8 +170,14 @@ struct awesome_config
Rule *rules; Rule *rules;
/** Number of rules in *rules */ /** Number of rules in *rules */
int nrules; int nrules;
/** Keys binding list */ /** Keys bindings list */
Key *keys; Key *keys;
/** Mouse bindings list */
struct
{
Button *tag;
int ntag;
} buttons;
/** Number of keys binding in *keys */ /** Number of keys binding in *keys */
int nkeys; int nkeys;
/** Default modkey */ /** Default modkey */

31
event.c
View File

@ -140,11 +140,11 @@ resizemouse(Client * c, awesome_config *awesomeconf)
void void
handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf) 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; unsigned int udummy;
Client *c; Client *c;
Window wdummy; Window wdummy;
char buf[256]; char arg[256];
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
for(screen = 0; screen < get_screen_count(e->xany.display); screen++) 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); x += textwidth(e->xany.display, awesomeconf[screen].font, awesomeconf[screen].tags[i].name);
if(ev->x < x) if(ev->x < x)
{ {
snprintf(buf, sizeof(buf), "%d", i + 1); snprintf(arg, sizeof(arg), "%d", i + 1);
if(ev->button == Button1) for(j = 0; j < awesomeconf[screen].buttons.ntag; j++)
{ {
if(ev->state & awesomeconf[screen].modkey) if(ev->button == awesomeconf[screen].buttons.tag[j].button
uicb_tag(&awesomeconf[screen], buf); && (ev->state == awesomeconf[screen].buttons.tag[j].mod
else || ev->state == (awesomeconf[screen].buttons.tag[j].mod | awesomeconf[screen].numlockmask))
uicb_view(&awesomeconf[screen], buf); && 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; return;
} }
} }