implement xproperty rule matching (FS#5)

This commit is contained in:
Julien Danjou 2008-01-02 12:23:01 +01:00
parent 0cf4ff6d9f
commit 346a383258
3 changed files with 40 additions and 18 deletions

View File

@ -607,6 +607,8 @@ config_parse(const char *confpatharg)
}; };
static cfg_opt_t rule_opts[] = static cfg_opt_t rule_opts[] =
{ {
CFG_STR((char *) "xproperty_name", NULL, CFGF_NONE),
CFG_STR((char *) "xproperty_value", NULL, CFGF_NONE),
CFG_STR((char *) "name", (char *) "", CFGF_NONE), CFG_STR((char *) "name", (char *) "", CFGF_NONE),
CFG_STR((char *) "tags", (char *) "", CFGF_NONE), CFG_STR((char *) "tags", (char *) "", CFGF_NONE),
CFG_STR((char *) "icon", (char *) "", CFGF_NONE), CFG_STR((char *) "icon", (char *) "", CFGF_NONE),
@ -714,6 +716,8 @@ config_parse(const char *confpatharg)
rule->isfloating = cfg_getbool(cfgsectmp, "float"); rule->isfloating = cfg_getbool(cfgsectmp, "float");
rule->screen = cfg_getint(cfgsectmp, "screen"); rule->screen = cfg_getint(cfgsectmp, "screen");
rule->not_master = cfg_getbool(cfgsectmp, "not_master"); rule->not_master = cfg_getbool(cfgsectmp, "not_master");
rule->xprop = a_strdup(cfg_getstr(cfgsectmp, "xproperty_name"));
rule->xprop_val = a_strdup(cfg_getstr(cfgsectmp, "xproperty_value"));
if(rule->screen >= get_screen_count()) if(rule->screen >= get_screen_count())
rule->screen = 0; rule->screen = 0;

View File

@ -43,11 +43,14 @@ struct Rule
char *prop; char *prop;
char *tags; char *tags;
char *icon; char *icon;
char *xprop;
char *xprop_val;
int screen; int screen;
Bool isfloating; Bool isfloating;
Bool not_master; Bool not_master;
regex_t *propregex; regex_t *propregex;
regex_t *tagregex; regex_t *tagregex;
regex_t *xpropvalregex;
Rule *next; Rule *next;
}; };

51
rules.c
View File

@ -21,44 +21,50 @@
#include "util.h" #include "util.h"
#include "rules.h" #include "rules.h"
#include "xutil.h"
extern AwesomeConf globalconf; extern AwesomeConf globalconf;
static regex_t *
compile_regex(char *val)
{
regex_t *reg;
if(val)
{
reg = p_new(regex_t, 1);
if(regcomp(reg, val, REG_EXTENDED))
p_delete(&reg);
else
return reg;
}
return NULL;
}
void void
compileregs(Rule *rules) compileregs(Rule *rules)
{ {
Rule *r; Rule *r;
regex_t *reg;
for(r = rules; r; r = r->next) for(r = rules; r; r = r->next)
{ {
if(r->prop) r->propregex = compile_regex(r->prop);
{ r->tagregex = compile_regex(r->tags);
reg = p_new(regex_t, 1); r->xpropvalregex = compile_regex(r->xprop_val);
if(regcomp(reg, r->prop, REG_EXTENDED))
p_delete(&reg);
else
r->propregex = reg;
}
if(r->tags)
{
reg = p_new(regex_t, 1);
if(regcomp(reg, r->tags, REG_EXTENDED))
p_delete(&reg);
else
r->tagregex = reg;
}
} }
} }
Bool Bool
client_match_rule(Client *c, Rule *r) client_match_rule(Client *c, Rule *r)
{ {
char *prop; char *prop, buf[512];
regmatch_t tmp; regmatch_t tmp;
ssize_t len; ssize_t len;
XClassHint ch = { 0, 0 }; XClassHint ch = { 0, 0 };
Bool ret; Bool ret;
/* first try to match on name */
XGetClassHint(globalconf.display, c->win, &ch); XGetClassHint(globalconf.display, c->win, &ch);
len = a_strlen(ch.res_class) + a_strlen(ch.res_name) + a_strlen(c->name); len = a_strlen(ch.res_class) + a_strlen(ch.res_name) + a_strlen(c->name);
@ -77,6 +83,15 @@ client_match_rule(Client *c, Rule *r)
if(ch.res_name) if(ch.res_name)
XFree(ch.res_name); XFree(ch.res_name);
if(ret)
return True;
if(r->xprop
&& xgettextprop(globalconf.display, c->win,
XInternAtom(globalconf.display, r->xprop, False),
buf, ssizeof(buf)))
ret = (r->xpropvalregex && !regexec(r->xpropvalregex, buf, 1, &tmp, 0));
return ret; return ret;
} }