all repos — dwm @ 9fdd2cd1a9dbe9b533fab9a8a98b9849dc4c7b59

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