all repos — dwm @ b61f91361c81b3c619ef6dac6e80e19a64d5fcf3

fork of suckless dynamic window manager

tag.c (view raw)

  1/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
  2 * See LICENSE file for license details.
  3 */
  4#include "dwm.h"
  5#include <regex.h>
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <string.h>
  9#include <sys/types.h>
 10#include <X11/Xutil.h>
 11
 12
 13typedef struct {
 14	const char *clpattern;
 15	const char *tpattern;
 16	Bool isfloat;
 17} Rule;
 18
 19typedef struct {
 20	regex_t *clregex;
 21	regex_t *tregex;
 22} RReg;
 23
 24/* static */
 25
 26TAGS
 27RULES
 28
 29static RReg *rreg = NULL;
 30static unsigned int len = 0;
 31
 32/* extern */
 33
 34void
 35initrregs(void) {
 36	unsigned int i;
 37	regex_t *reg;
 38
 39	if(rreg)
 40		return;
 41	len = sizeof rule / sizeof rule[0];
 42	rreg = emallocz(len * sizeof(RReg));
 43	for(i = 0; i < len; i++) {
 44		if(rule[i].clpattern) {
 45			reg = emallocz(sizeof(regex_t));
 46			if(regcomp(reg, rule[i].clpattern, REG_EXTENDED))
 47				free(reg);
 48			else
 49				rreg[i].clregex = reg;
 50		}
 51		if(rule[i].tpattern) {
 52			reg = emallocz(sizeof(regex_t));
 53			if(regcomp(reg, rule[i].tpattern, REG_EXTENDED))
 54				free(reg);
 55			else
 56				rreg[i].tregex = reg;
 57		}
 58	}
 59}
 60
 61void
 62settags(Client *c, Client *trans) {
 63	char prop[512];
 64	unsigned int i, j;
 65	regmatch_t tmp;
 66	Bool matched = trans != NULL;
 67	XClassHint ch = { 0 };
 68
 69	if(matched)
 70		for(i = 0; i < ntags; i++)
 71			c->tags[i] = trans->tags[i];
 72	else {
 73		XGetClassHint(dpy, c->win, &ch);
 74		snprintf(prop, sizeof prop, "%s:%s:%s",
 75				ch.res_class ? ch.res_class : "",
 76				ch.res_name ? ch.res_name : "", c->name);
 77		for(i = 0; i < len; i++)
 78			if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
 79				c->isfloat = rule[i].isfloat;
 80				for(j = 0; rreg[i].tregex && j < ntags; j++) {
 81					if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
 82						matched = True;
 83						c->tags[j] = True;
 84					}
 85				}
 86			}
 87		if(ch.res_class)
 88			XFree(ch.res_class);
 89		if(ch.res_name)
 90			XFree(ch.res_name);
 91	}
 92	if(!matched)
 93		for(i = 0; i < ntags; i++)
 94			c->tags[i] = seltag[i];
 95}
 96
 97void
 98tag(Arg *arg) {
 99	unsigned int i;
100
101	if(!sel)
102		return;
103	for(i = 0; i < ntags; i++)
104		sel->tags[i] = (arg->i == -1) ? True : False;
105	if(arg->i >= 0 && arg->i < ntags)
106		sel->tags[arg->i] = True;
107	arrange();
108}
109
110void
111toggletag(Arg *arg) {
112	unsigned int i;
113
114	if(!sel)
115		return;
116	sel->tags[arg->i] = !sel->tags[arg->i];
117	for(i = 0; i < ntags && !sel->tags[i]; i++);
118	if(i == ntags)
119		sel->tags[arg->i] = True;
120	arrange();
121}