all repos — dwm @ 35e65ea64095d4a2ef305b20aac9d72624af514c

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
 34Client *
 35getnext(Client *c) {
 36	for(; c && !isvisible(c); c = c->next);
 37	return c;
 38}
 39
 40Client *
 41getprev(Client *c) {
 42	for(; c && !isvisible(c); c = c->prev);
 43	return c;
 44}
 45
 46void
 47initrregs(void) {
 48	unsigned int i;
 49	regex_t *reg;
 50
 51	if(rreg)
 52		return;
 53	len = sizeof rule / sizeof rule[0];
 54	rreg = emallocz(len * sizeof(RReg));
 55	for(i = 0; i < len; i++) {
 56		if(rule[i].clpattern) {
 57			reg = emallocz(sizeof(regex_t));
 58			if(regcomp(reg, rule[i].clpattern, REG_EXTENDED))
 59				free(reg);
 60			else
 61				rreg[i].clregex = reg;
 62		}
 63		if(rule[i].tpattern) {
 64			reg = emallocz(sizeof(regex_t));
 65			if(regcomp(reg, rule[i].tpattern, REG_EXTENDED))
 66				free(reg);
 67			else
 68				rreg[i].tregex = reg;
 69		}
 70	}
 71}
 72
 73void
 74settags(Client *c, Client *trans) {
 75	char prop[512];
 76	unsigned int i, j;
 77	regmatch_t tmp;
 78	Bool matched = trans != NULL;
 79	XClassHint ch = { 0 };
 80
 81	if(matched) {
 82		for(i = 0; i < ntags; i++)
 83			c->tags[i] = trans->tags[i];
 84	}
 85	else {
 86		XGetClassHint(dpy, c->win, &ch);
 87		snprintf(prop, sizeof prop, "%s:%s:%s",
 88				ch.res_class ? ch.res_class : "",
 89				ch.res_name ? ch.res_name : "", c->name);
 90		for(i = 0; i < len; i++)
 91			if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
 92				c->isfloat = rule[i].isfloat;
 93				for(j = 0; rreg[i].tregex && j < ntags; j++) {
 94					if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
 95						matched = True;
 96						c->tags[j] = True;
 97					}
 98				}
 99			}
100		if(ch.res_class)
101			XFree(ch.res_class);
102		if(ch.res_name)
103			XFree(ch.res_name);
104	}
105	if(!matched)
106		for(i = 0; i < ntags; i++)
107			c->tags[i] = seltag[i];
108}
109
110void
111tag(Arg *arg) {
112	unsigned int i;
113
114	if(!sel)
115		return;
116	for(i = 0; i < ntags; i++)
117		sel->tags[i] = (arg->i == -1) ? True : False;
118	if(arg->i >= 0 && arg->i < ntags)
119		sel->tags[arg->i] = True;
120	arrange();
121}
122
123void
124toggletag(Arg *arg) {
125	unsigned int i;
126
127	if(!sel)
128		return;
129	sel->tags[arg->i] = !sel->tags[arg->i];
130	for(i = 0; i < ntags && !sel->tags[i]; i++);
131	if(i == ntags)
132		sel->tags[arg->i] = True;
133	arrange();
134}