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}