aewl

annotate tag.c @ 192:30b321919a93

fixed dmenu link (thx to deifl)
author arg@10ksloc.org
date Fri, 04 Aug 2006 15:47:50 +0200
parents e848966a1ac6
children 655e38416bb8
rev   line source
garbeam@75 1 /*
garbeam@75 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
garbeam@75 3 * See LICENSE file for license details.
garbeam@75 4 */
garbeam@76 5 #include "dwm.h"
arg@114 6 #include <regex.h>
arg@114 7 #include <stdio.h>
arg@191 8 #include <stdlib.h>
garbeam@75 9 #include <string.h>
arg@114 10 #include <sys/types.h>
garbeam@75 11 #include <X11/Xutil.h>
garbeam@75 12
garbeam@76 13
arg@114 14 typedef struct {
arg@191 15 const char *clpattern;
arg@191 16 const char *tpattern;
arg@114 17 Bool isfloat;
arg@114 18 } Rule;
arg@114 19
arg@191 20 typedef struct {
arg@191 21 regex_t *clregex;
arg@191 22 regex_t *tregex;
arg@191 23 } RReg;
arg@191 24
arg@191 25 /* static */
arg@191 26
arg@146 27 TAGS
arg@146 28 RULES
garbeam@84 29
arg@191 30 static RReg *rreg = NULL;
arg@191 31 static unsigned int len = 0;
arg@191 32
arg@156 33 void (*arrange)(Arg *) = DEFMODE;
arg@125 34
arg@125 35 /* extern */
arg@125 36
garbeam@76 37 void
garbeam@76 38 appendtag(Arg *arg)
garbeam@75 39 {
garbeam@76 40 if(!sel)
garbeam@76 41 return;
garbeam@75 42
arg@173 43 sel->tags[arg->i] = True;
garbeam@75 44 arrange(NULL);
garbeam@75 45 }
garbeam@75 46
garbeam@75 47 void
garbeam@75 48 dofloat(Arg *arg)
garbeam@75 49 {
garbeam@75 50 Client *c;
garbeam@75 51
garbeam@75 52 for(c = clients; c; c = c->next) {
arg@124 53 c->ismax = False;
garbeam@95 54 if(c->tags[tsel]) {
arg@99 55 resize(c, True, TopLeft);
garbeam@95 56 }
garbeam@75 57 else
garbeam@75 58 ban(c);
garbeam@75 59 }
garbeam@75 60 if(sel && !sel->tags[tsel]) {
arg@142 61 if((sel = getnext(clients))) {
garbeam@75 62 higher(sel);
garbeam@75 63 focus(sel);
garbeam@75 64 }
arg@143 65 else
arg@143 66 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
garbeam@75 67 }
garbeam@75 68 drawall();
garbeam@75 69 }
garbeam@75 70
garbeam@75 71 void
garbeam@75 72 dotile(Arg *arg)
garbeam@75 73 {
arg@123 74 int n, i, w, h;
garbeam@75 75 Client *c;
garbeam@75 76
garbeam@75 77 w = sw - mw;
garbeam@75 78 for(n = 0, c = clients; c; c = c->next)
garbeam@80 79 if(c->tags[tsel] && !c->isfloat)
garbeam@75 80 n++;
garbeam@75 81
garbeam@75 82 if(n > 1)
garbeam@75 83 h = (sh - bh) / (n - 1);
garbeam@75 84 else
garbeam@75 85 h = sh - bh;
garbeam@75 86
garbeam@75 87 for(i = 0, c = clients; c; c = c->next) {
arg@124 88 c->ismax = False;
garbeam@75 89 if(c->tags[tsel]) {
garbeam@80 90 if(c->isfloat) {
garbeam@75 91 higher(c);
arg@99 92 resize(c, True, TopLeft);
garbeam@75 93 continue;
garbeam@75 94 }
garbeam@75 95 if(n == 1) {
arg@115 96 c->x = sx;
arg@115 97 c->y = sy + bh;
arg@164 98 c->w = sw - 2;
arg@164 99 c->h = sh - 2 - bh;
garbeam@75 100 }
garbeam@75 101 else if(i == 0) {
arg@115 102 c->x = sx;
arg@115 103 c->y = sy + bh;
arg@164 104 c->w = mw - 2;
arg@164 105 c->h = sh - 2 - bh;
garbeam@75 106 }
arg@104 107 else if(h > bh) {
arg@115 108 c->x = sx + mw;
arg@115 109 c->y = sy + (i - 1) * h + bh;
arg@164 110 c->w = w - 2;
arg@164 111 c->h = h - 2;
garbeam@75 112 }
arg@104 113 else { /* fallback if h < bh */
arg@115 114 c->x = sx + mw;
arg@115 115 c->y = sy + bh;
arg@164 116 c->w = w - 2;
arg@164 117 c->h = sh - 2 - bh;
arg@104 118 }
arg@99 119 resize(c, False, TopLeft);
garbeam@75 120 i++;
garbeam@75 121 }
garbeam@75 122 else
garbeam@75 123 ban(c);
garbeam@75 124 }
garbeam@75 125 if(!sel || (sel && !sel->tags[tsel])) {
arg@142 126 if((sel = getnext(clients))) {
garbeam@75 127 higher(sel);
garbeam@75 128 focus(sel);
garbeam@75 129 }
arg@143 130 else
arg@143 131 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
garbeam@75 132 }
garbeam@75 133 drawall();
garbeam@75 134 }
garbeam@75 135
garbeam@76 136 Client *
arg@142 137 getnext(Client *c)
garbeam@75 138 {
arg@142 139 for(; c && !c->tags[tsel]; c = c->next);
garbeam@76 140 return c;
garbeam@75 141 }
garbeam@75 142
arg@127 143 Client *
arg@127 144 getprev(Client *c)
arg@127 145 {
arg@127 146 for(; c && !c->tags[tsel]; c = c->prev);
arg@127 147 return c;
arg@127 148 }
arg@127 149
garbeam@75 150 void
arg@191 151 initrregs()
arg@191 152 {
arg@191 153 unsigned int i;
arg@191 154 regex_t *reg;
arg@191 155
arg@191 156 if(rreg)
arg@191 157 return;
arg@191 158 len = sizeof(rule) / sizeof(rule[0]);
arg@191 159 rreg = emallocz(len * sizeof(RReg));
arg@191 160
arg@191 161 for(i = 0; i < len; i++) {
arg@191 162 if(rule[i].clpattern) {
arg@191 163 reg = emallocz(sizeof(regex_t));
arg@191 164 if(regcomp(reg, rule[i].clpattern, 0))
arg@191 165 free(reg);
arg@191 166 else
arg@191 167 rreg[i].clregex = reg;
arg@191 168 }
arg@191 169 if(rule[i].tpattern) {
arg@191 170 reg = emallocz(sizeof(regex_t));
arg@191 171 if(regcomp(reg, rule[i].tpattern, 0))
arg@191 172 free(reg);
arg@191 173 else
arg@191 174 rreg[i].tregex = reg;
arg@191 175 }
arg@191 176 }
arg@191 177 }
arg@191 178
arg@191 179 void
garbeam@75 180 replacetag(Arg *arg)
garbeam@75 181 {
garbeam@75 182 int i;
arg@123 183
garbeam@75 184 if(!sel)
garbeam@75 185 return;
garbeam@75 186
arg@178 187 for(i = 0; i < ntags; i++)
arg@173 188 sel->tags[i] = False;
garbeam@75 189 appendtag(arg);
garbeam@75 190 }
garbeam@75 191
garbeam@76 192 void
garbeam@76 193 settags(Client *c)
garbeam@76 194 {
arg@114 195 char classinst[256];
arg@191 196 unsigned int i, j;
arg@114 197 regmatch_t tmp;
garbeam@76 198 Bool matched = False;
arg@114 199 XClassHint ch;
garbeam@76 200
garbeam@76 201 if(XGetClassHint(dpy, c->win, &ch)) {
arg@114 202 snprintf(classinst, sizeof(classinst), "%s:%s",
arg@114 203 ch.res_class ? ch.res_class : "",
arg@114 204 ch.res_name ? ch.res_name : "");
arg@191 205 for(i = 0; !matched && i < len; i++)
arg@191 206 if(rreg[i].clregex && !regexec(rreg[i].clregex, classinst, 1, &tmp, 0)) {
arg@191 207 c->isfloat = rule[i].isfloat;
arg@191 208 for(j = 0; rreg[i].tregex && j < ntags; j++) {
arg@191 209 if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
arg@191 210 matched = True;
arg@191 211 c->tags[j] = True;
arg@191 212 }
garbeam@76 213 }
arg@114 214 }
garbeam@76 215 if(ch.res_class)
garbeam@76 216 XFree(ch.res_class);
garbeam@76 217 if(ch.res_name)
garbeam@76 218 XFree(ch.res_name);
garbeam@76 219 }
garbeam@76 220 if(!matched)
arg@173 221 c->tags[tsel] = True;
garbeam@76 222 }
garbeam@76 223
garbeam@76 224 void
arg@124 225 togglemode(Arg *arg)
arg@124 226 {
arg@124 227 arrange = arrange == dofloat ? dotile : dofloat;
arg@124 228 arrange(NULL);
arg@124 229 }
arg@124 230
arg@124 231 void
garbeam@76 232 view(Arg *arg)
garbeam@76 233 {
garbeam@76 234 tsel = arg->i;
garbeam@76 235 arrange(NULL);
garbeam@76 236 drawall();
garbeam@76 237 }
arg@144 238
arg@144 239 void
arg@144 240 viewnext(Arg *arg)
arg@144 241 {
arg@178 242 arg->i = (tsel < ntags-1) ? tsel+1 : 0;
arg@144 243 view(arg);
arg@144 244 }
arg@144 245
arg@144 246 void
arg@144 247 viewprev(Arg *arg)
arg@144 248 {
arg@178 249 arg->i = (tsel > 0) ? tsel-1 : ntags-1;
arg@144 250 view(arg);
arg@144 251 }