all repos — dwm @ 92cb5ebb7cb4e6a067474dae94c7a70977194f5d

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;
 80
 81	if(matched) {
 82		for(i = 0; i < ntags; i++)
 83			c->tags[i] = trans->tags[i];
 84	}
 85	else if(XGetClassHint(dpy, c->win, &ch)) {
 86		snprintf(prop, sizeof prop, "%s:%s:%s",
 87				ch.res_class ? ch.res_class : "",
 88				ch.res_name ? ch.res_name : "", c->name);
 89		for(i = 0; i < len; i++)
 90			if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
 91				c->isfloat = rule[i].isfloat;
 92				for(j = 0; rreg[i].tregex && j < ntags; j++) {
 93					if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
 94						matched = True;
 95						c->tags[j] = True;
 96					}
 97				}
 98			}
 99		if(ch.res_class)
100			XFree(ch.res_class);
101		if(ch.res_name)
102			XFree(ch.res_name);
103	}
104	if(!matched)
105		for(i = 0; i < ntags; i++)
106			c->tags[i] = seltag[i];
107}
108
109void
110tag(Arg *arg) {
111	unsigned int i;
112
113	if(!sel)
114		return;
115	for(i = 0; i < ntags; i++)
116		sel->tags[i] = (arg->i == -1) ? True : False;
117	if(arg->i >= 0 && arg->i < ntags)
118		sel->tags[arg->i] = True;
119	arrange();
120}
121
122void
123toggletag(Arg *arg) {
124	unsigned int i;
125
126	if(!sel)
127		return;
128	sel->tags[arg->i] = !sel->tags[arg->i];
129	for(i = 0; i < ntags && !sel->tags[i]; i++);
130	if(i == ntags)
131		sel->tags[arg->i] = True;
132	arrange();
133}