all repos — dwm @ d934296476be7345842fec1a2630d1752c704078

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