dwm-meillo

annotate tag.c @ 262:d659a2dce2b5

implemented viewextend and added M-S-C-n shortcuts for extending the current view... updated man page (works great!) nice feature
author Anselm R.Garbe <arg@10ksloc.org>
date Fri, 11 Aug 2006 19:26:12 +0200
parents d6fd632d861c
children 118d3e010e5e
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;
arg@261 54 if(isvisible(c)) {
arg@99 55 resize(c, True, TopLeft);
garbeam@95 56 }
garbeam@75 57 else
garbeam@75 58 ban(c);
garbeam@75 59 }
arg@194 60 if((sel = getnext(clients))) {
arg@194 61 higher(sel);
arg@194 62 focus(sel);
garbeam@75 63 }
arg@194 64 else
arg@194 65 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
garbeam@75 66 drawall();
garbeam@75 67 }
garbeam@75 68
garbeam@75 69 void
garbeam@75 70 dotile(Arg *arg)
garbeam@75 71 {
arg@123 72 int n, i, w, h;
garbeam@75 73 Client *c;
garbeam@75 74
garbeam@75 75 w = sw - mw;
garbeam@75 76 for(n = 0, c = clients; c; c = c->next)
arg@261 77 if(isvisible(c) && !c->isfloat)
garbeam@75 78 n++;
garbeam@75 79
garbeam@75 80 if(n > 1)
garbeam@75 81 h = (sh - bh) / (n - 1);
garbeam@75 82 else
garbeam@75 83 h = sh - bh;
garbeam@75 84
garbeam@75 85 for(i = 0, c = clients; c; c = c->next) {
arg@124 86 c->ismax = False;
arg@261 87 if(isvisible(c)) {
garbeam@80 88 if(c->isfloat) {
garbeam@75 89 higher(c);
arg@99 90 resize(c, True, TopLeft);
garbeam@75 91 continue;
garbeam@75 92 }
garbeam@75 93 if(n == 1) {
arg@115 94 c->x = sx;
arg@115 95 c->y = sy + bh;
arg@164 96 c->w = sw - 2;
arg@164 97 c->h = sh - 2 - bh;
garbeam@75 98 }
garbeam@75 99 else if(i == 0) {
arg@115 100 c->x = sx;
arg@115 101 c->y = sy + bh;
arg@164 102 c->w = mw - 2;
arg@164 103 c->h = sh - 2 - bh;
garbeam@75 104 }
arg@104 105 else if(h > bh) {
arg@115 106 c->x = sx + mw;
arg@115 107 c->y = sy + (i - 1) * h + bh;
arg@164 108 c->w = w - 2;
arg@240 109 if(i + 1 == n)
arg@240 110 c->h = sh - c->y - 2;
arg@240 111 else
arg@240 112 c->h = h - 2;
garbeam@75 113 }
arg@104 114 else { /* fallback if h < bh */
arg@115 115 c->x = sx + mw;
arg@115 116 c->y = sy + bh;
arg@164 117 c->w = w - 2;
arg@164 118 c->h = sh - 2 - bh;
arg@104 119 }
arg@99 120 resize(c, False, TopLeft);
garbeam@75 121 i++;
garbeam@75 122 }
garbeam@75 123 else
garbeam@75 124 ban(c);
garbeam@75 125 }
arg@194 126 if((sel = getnext(clients))) {
arg@194 127 higher(sel);
arg@194 128 focus(sel);
garbeam@75 129 }
arg@194 130 else
arg@194 131 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
garbeam@75 132 drawall();
garbeam@75 133 }
garbeam@75 134
garbeam@76 135 Client *
arg@142 136 getnext(Client *c)
garbeam@75 137 {
arg@261 138 for(; c && !isvisible(c); c = c->next);
garbeam@76 139 return c;
garbeam@75 140 }
garbeam@75 141
arg@127 142 Client *
arg@127 143 getprev(Client *c)
arg@127 144 {
arg@261 145 for(; c && !isvisible(c); c = c->prev);
arg@127 146 return c;
arg@127 147 }
arg@127 148
garbeam@75 149 void
arg@191 150 initrregs()
arg@191 151 {
arg@191 152 unsigned int i;
arg@191 153 regex_t *reg;
arg@191 154
arg@191 155 if(rreg)
arg@191 156 return;
arg@191 157 len = sizeof(rule) / sizeof(rule[0]);
arg@191 158 rreg = emallocz(len * sizeof(RReg));
arg@191 159
arg@191 160 for(i = 0; i < len; i++) {
arg@191 161 if(rule[i].clpattern) {
arg@191 162 reg = emallocz(sizeof(regex_t));
arg@191 163 if(regcomp(reg, rule[i].clpattern, 0))
arg@191 164 free(reg);
arg@191 165 else
arg@191 166 rreg[i].clregex = reg;
arg@191 167 }
arg@191 168 if(rule[i].tpattern) {
arg@191 169 reg = emallocz(sizeof(regex_t));
arg@191 170 if(regcomp(reg, rule[i].tpattern, 0))
arg@191 171 free(reg);
arg@191 172 else
arg@191 173 rreg[i].tregex = reg;
arg@191 174 }
arg@191 175 }
arg@191 176 }
arg@191 177
arg@261 178 Bool
arg@261 179 isvisible(Client *c)
arg@261 180 {
arg@261 181 unsigned int i;
arg@261 182
arg@261 183 for(i = 0; i < ntags; i++)
arg@262 184 if(c->tags[i] && seltag[i])
arg@261 185 return True;
arg@261 186 return False;
arg@261 187 }
arg@261 188
arg@191 189 void
garbeam@75 190 replacetag(Arg *arg)
garbeam@75 191 {
garbeam@75 192 int i;
arg@123 193
garbeam@75 194 if(!sel)
garbeam@75 195 return;
garbeam@75 196
arg@178 197 for(i = 0; i < ntags; i++)
arg@173 198 sel->tags[i] = False;
garbeam@75 199 appendtag(arg);
garbeam@75 200 }
garbeam@75 201
garbeam@76 202 void
garbeam@76 203 settags(Client *c)
garbeam@76 204 {
arg@114 205 char classinst[256];
arg@191 206 unsigned int i, j;
arg@114 207 regmatch_t tmp;
garbeam@76 208 Bool matched = False;
arg@114 209 XClassHint ch;
garbeam@76 210
garbeam@76 211 if(XGetClassHint(dpy, c->win, &ch)) {
arg@114 212 snprintf(classinst, sizeof(classinst), "%s:%s",
arg@114 213 ch.res_class ? ch.res_class : "",
arg@114 214 ch.res_name ? ch.res_name : "");
arg@191 215 for(i = 0; !matched && i < len; i++)
arg@191 216 if(rreg[i].clregex && !regexec(rreg[i].clregex, classinst, 1, &tmp, 0)) {
arg@191 217 c->isfloat = rule[i].isfloat;
arg@191 218 for(j = 0; rreg[i].tregex && j < ntags; j++) {
arg@191 219 if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
arg@191 220 matched = True;
arg@191 221 c->tags[j] = True;
arg@191 222 }
garbeam@76 223 }
arg@114 224 }
garbeam@76 225 if(ch.res_class)
garbeam@76 226 XFree(ch.res_class);
garbeam@76 227 if(ch.res_name)
garbeam@76 228 XFree(ch.res_name);
garbeam@76 229 }
garbeam@76 230 if(!matched)
arg@261 231 for(i = 0; i < ntags; i++)
arg@262 232 c->tags[i] = seltag[i];
garbeam@76 233 }
garbeam@76 234
garbeam@76 235 void
arg@124 236 togglemode(Arg *arg)
arg@124 237 {
arg@124 238 arrange = arrange == dofloat ? dotile : dofloat;
arg@124 239 arrange(NULL);
arg@124 240 }
arg@124 241
arg@124 242 void
garbeam@76 243 view(Arg *arg)
garbeam@76 244 {
arg@261 245 unsigned int i;
arg@261 246
arg@261 247 for(i = 0; i < ntags; i++)
arg@262 248 seltag[i] = False;
arg@262 249 seltag[arg->i] = True;
arg@262 250 arrange(NULL);
arg@262 251 drawall();
arg@262 252 }
arg@262 253
arg@262 254 void
arg@262 255 viewextend(Arg *arg)
arg@262 256 {
arg@262 257 unsigned int i;
arg@262 258
arg@262 259 seltag[arg->i] = !seltag[arg->i];
arg@262 260 for(i = 0; !seltag[i] && i < ntags; i++);
arg@262 261 if(i == ntags)
arg@262 262 seltag[arg->i] = True; /* cannot toggle last view */
garbeam@76 263 arrange(NULL);
garbeam@76 264 drawall();
garbeam@76 265 }
arg@144 266
arg@144 267 void
arg@144 268 viewnext(Arg *arg)
arg@144 269 {
arg@261 270 unsigned int i;
arg@261 271
arg@262 272 for(i = 0; !seltag[i]; i++);
arg@261 273 arg->i = (i < ntags-1) ? i+1 : 0;
arg@144 274 view(arg);
arg@144 275 }
arg@144 276
arg@144 277 void
arg@144 278 viewprev(Arg *arg)
arg@144 279 {
arg@261 280 unsigned int i;
arg@261 281
arg@262 282 for(i = 0; !seltag[i]; i++);
arg@261 283 arg->i = (i > 0) ? i-1 : ntags-1;
arg@144 284 view(arg);
arg@144 285 }