From 6db8831e30c46762673435ca82272b75da6c4b55 Mon Sep 17 00:00:00 2001 From: Matt Vollrath Date: Mon, 11 May 2020 21:03:02 -0400 Subject: [PATCH] Add WM_NAME rule matching --- doc/bspwm.1 | 4 ++-- src/messages.c | 2 ++ src/rule.c | 21 +++++++++++++++++---- src/rule.h | 1 + src/types.h | 3 +++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/bspwm.1 b/doc/bspwm.1 index e1ae476..9719f04 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -1041,12 +1041,12 @@ rule \fICOMMANDS\fR \fBCommands\fR .RS 4 .PP -\fB\-a\fR, \fB\-\-add\fR (|*)[:(|*)] [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y] +\fB\-a\fR, \fB\-\-add\fR (|*)[:(|*)][:(|*)] [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y] .RS 4 Create a new rule\&. .RE .PP -\fB\-r\fR, \fB\-\-remove\fR ^|head|tail|(|*)[:(|*)]\&... +\fB\-r\fR, \fB\-\-remove\fR ^|head|tail|(|*)[:(|*)][:(|*)]\&... .RS 4 Remove the given rules\&. .RE diff --git a/src/messages.c b/src/messages.c index a819892..7c34c0f 100644 --- a/src/messages.c +++ b/src/messages.c @@ -1138,8 +1138,10 @@ void cmd_rule(char **args, int num, FILE *rsp) rule_t *rule = make_rule(); char *class_name = strtok(*args, COL_TOK); char *instance_name = strtok(NULL, COL_TOK); + char *name = strtok(NULL, COL_TOK); snprintf(rule->class_name, sizeof(rule->class_name), "%s", class_name); snprintf(rule->instance_name, sizeof(rule->instance_name), "%s", instance_name==NULL?MATCH_ANY:instance_name); + snprintf(rule->name, sizeof(rule->name), "%s", name==NULL?MATCH_ANY:name); num--, args++; size_t i = 0; while (num > 0) { diff --git a/src/rule.c b/src/rule.c index b0d4c0b..43a0ccd 100644 --- a/src/rule.c +++ b/src/rule.c @@ -39,7 +39,7 @@ rule_t *make_rule(void) { rule_t *r = calloc(1, sizeof(rule_t)); - r->class_name[0] = r->instance_name[0] = r->effect[0] = '\0'; + r->class_name[0] = r->instance_name[0] = r->name[0] = r->effect[0] = '\0'; r->next = r->prev = NULL; r->one_shot = false; return r; @@ -83,10 +83,12 @@ void remove_rule_by_cause(char *cause) rule_t *r = rule_head; char *class_name = strtok(cause, COL_TOK); char *instance_name = strtok(NULL, COL_TOK); + char *name = strtok(NULL, COL_TOK); while (r != NULL) { rule_t *next = r->next; if ((class_name != NULL && (streq(class_name, MATCH_ANY) || streq(r->class_name, class_name))) && - (instance_name == NULL || streq(instance_name, MATCH_ANY) || streq(r->instance_name, instance_name))) { + (instance_name == NULL || streq(instance_name, MATCH_ANY) || streq(r->instance_name, instance_name)) && + (name == NULL || streq(name, MATCH_ANY) || streq(r->name, name))) { remove_rule(r); } r = next; @@ -281,6 +283,15 @@ void _apply_class(xcb_window_t win, rule_consequence_t *csq) } } +void _apply_name(xcb_window_t win, rule_consequence_t *csq) +{ + xcb_icccm_get_text_property_reply_t reply; + if (xcb_icccm_get_wm_name_reply(dpy, xcb_icccm_get_wm_name(dpy, win), &reply, NULL) == 1) { + snprintf(csq->name, sizeof(csq->name), "%s", reply.name); + xcb_icccm_get_text_property_reply_wipe(&reply); + } +} + void parse_keys_values(char *buf, rule_consequence_t *csq) { char *key = strtok(buf, CSQ_BLK); @@ -299,12 +310,14 @@ void apply_rules(xcb_window_t win, rule_consequence_t *csq) _apply_transient(win, csq); _apply_hints(win, csq); _apply_class(win, csq); + _apply_name(win, csq); rule_t *rule = rule_head; while (rule != NULL) { rule_t *next = rule->next; if ((streq(rule->class_name, MATCH_ANY) || streq(rule->class_name, csq->class_name)) && - (streq(rule->instance_name, MATCH_ANY) || streq(rule->instance_name, csq->instance_name))) { + (streq(rule->instance_name, MATCH_ANY) || streq(rule->instance_name, csq->instance_name)) && + (streq(rule->name, MATCH_ANY) || streq(rule->name, csq->name))) { char effect[MAXLEN]; snprintf(effect, sizeof(effect), "%s", rule->effect); parse_keys_values(effect, csq); @@ -424,6 +437,6 @@ void parse_key_value(char *key, char *value, rule_consequence_t *csq) void list_rules(FILE *rsp) { for (rule_t *r = rule_head; r != NULL; r = r->next) { - fprintf(rsp, "%s:%s %c> %s\n", r->class_name, r->instance_name, r->one_shot?'-':'=', r->effect); + fprintf(rsp, "%s:%s:%s %c> %s\n", r->class_name, r->instance_name, r->name, r->one_shot?'-':'=', r->effect); } } diff --git a/src/rule.h b/src/rule.h index 402da80..d87d4b0 100644 --- a/src/rule.h +++ b/src/rule.h @@ -44,6 +44,7 @@ void _apply_window_state(xcb_window_t win, rule_consequence_t *csq); void _apply_transient(xcb_window_t win, rule_consequence_t *csq); void _apply_hints(xcb_window_t win, rule_consequence_t *csq); void _apply_class(xcb_window_t win, rule_consequence_t *csq); +void _apply_name(xcb_window_t win, rule_consequence_t *csq); void parse_keys_values(char *buf, rule_consequence_t *csq); void apply_rules(xcb_window_t win, rule_consequence_t *csq); bool schedule_rules(xcb_window_t win, rule_consequence_t *csq); diff --git a/src/types.h b/src/types.h index 9da6565..07c3093 100644 --- a/src/types.h +++ b/src/types.h @@ -210,6 +210,7 @@ struct icccm_props_t { typedef struct { char class_name[3 * SMALEN / 2]; char instance_name[3 * SMALEN / 2]; + char name[3 * SMALEN / 2]; unsigned int border_width; bool urgent; bool shown; @@ -341,6 +342,7 @@ typedef struct rule_t rule_t; struct rule_t { char class_name[MAXLEN]; char instance_name[MAXLEN]; + char name[MAXLEN]; char effect[MAXLEN]; bool one_shot; rule_t *prev; @@ -350,6 +352,7 @@ struct rule_t { typedef struct { char class_name[3 * SMALEN / 2]; char instance_name[3 * SMALEN / 2]; + char name[3 * SMALEN / 2]; char monitor_desc[MAXLEN]; char desktop_desc[MAXLEN]; char node_desc[MAXLEN]; -- 2.44.0