all repos — dwm @ e1deda9e040c052af62aecc2fb4ee770fb2496a2

fork of suckless dynamic window manager

tag.c (view raw)

  1/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
  2 * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
  3 * © 2007 Premysl Hruby <dfenze at gmail dot com>
  4 * See LICENSE file for license details. */
  5#include "dwm.h"
  6#include <regex.h>
  7#include <stdio.h>
  8#include <stdlib.h>
  9#include <X11/Xutil.h>
 10
 11/* static */
 12
 13typedef struct {
 14	const char *prop;
 15	const char *tags;
 16	Bool isfloating;
 17} Rule;
 18
 19typedef struct {
 20	regex_t *propregex;
 21	regex_t *tagregex;
 22} Regs;
 23
 24TAGS
 25RULES
 26
 27static Regs *regs = NULL;
 28static unsigned int nrules = 0;
 29
 30/* extern */
 31
 32void
 33compileregs(void) {
 34	unsigned int i;
 35	regex_t *reg;
 36
 37	if(regs)
 38		return;
 39	nrules = sizeof rule / sizeof rule[0];
 40	regs = emallocz(nrules * sizeof(Regs));
 41	for(i = 0; i < nrules; i++) {
 42		if(rule[i].prop) {
 43			reg = emallocz(sizeof(regex_t));
 44			if(regcomp(reg, rule[i].prop, REG_EXTENDED))
 45				free(reg);
 46			else
 47				regs[i].propregex = reg;
 48		}
 49		if(rule[i].tags) {
 50			reg = emallocz(sizeof(regex_t));
 51			if(regcomp(reg, rule[i].tags, REG_EXTENDED))
 52				free(reg);
 53			else
 54				regs[i].tagregex = reg;
 55		}
 56	}
 57}
 58
 59Bool
 60isvisible(Client *c) {
 61	unsigned int i;
 62
 63	for(i = 0; i < ntags; i++)
 64		if(c->tags[i] && seltag[i])
 65			return True;
 66	return False;
 67}
 68
 69void
 70settags(Client *c, Client *trans) {
 71	char prop[512];
 72	unsigned int i, j;
 73	regmatch_t tmp;
 74	Bool matched = trans != NULL;
 75	XClassHint ch = { 0 };
 76
 77	if(matched)
 78		for(i = 0; i < ntags; i++)
 79			c->tags[i] = trans->tags[i];
 80	else {
 81		XGetClassHint(dpy, c->win, &ch);
 82		snprintf(prop, sizeof prop, "%s:%s:%s",
 83				ch.res_class ? ch.res_class : "",
 84				ch.res_name ? ch.res_name : "", c->name);
 85		for(i = 0; i < nrules; i++)
 86			if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
 87				c->isfloating = rule[i].isfloating;
 88				for(j = 0; regs[i].tagregex && j < ntags; j++) {
 89					if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
 90						matched = True;
 91						c->tags[j] = True;
 92					}
 93				}
 94			}
 95		if(ch.res_class)
 96			XFree(ch.res_class);
 97		if(ch.res_name)
 98			XFree(ch.res_name);
 99	}
100	if(!matched)
101		for(i = 0; i < ntags; i++)
102			c->tags[i] = seltag[i];
103}
104
105void
106tag(const char *arg) {
107	int i;
108
109	if(!sel)
110		return;
111	for(i = 0; i < ntags; i++)
112		sel->tags[i] = arg == NULL;
113	i = arg ? atoi(arg) : 0;
114	if(i >= 0 && i < ntags)
115		sel->tags[i] = True;
116	lt->arrange();
117}
118
119void
120toggletag(const char *arg) {
121	int i, j;
122
123	if(!sel)
124		return;
125	i = arg ? atoi(arg) : 0;
126	sel->tags[i] = !sel->tags[i];
127	for(j = 0; j < ntags && !sel->tags[j]; j++);
128	if(j == ntags)
129		sel->tags[i] = True;
130	lt->arrange();
131}
132
133void
134toggleview(const char *arg) {
135	int i, j;
136
137	i = arg ? atoi(arg) : 0;
138	seltag[i] = !seltag[i];
139	for(j = 0; j < ntags && !seltag[j]; j++);
140	if(j == ntags)
141		seltag[i] = True; /* cannot toggle last view */
142	lt->arrange();
143}
144
145void
146view(const char *arg) {
147	int i;
148
149	for(i = 0; i < ntags; i++)
150		seltag[i] = arg == NULL;
151	i = arg ? atoi(arg) : 0;
152	if(i >= 0 && i < ntags)
153		seltag[i] = True;
154	lt->arrange();
155}