diff -r 699b25e7dd64 dwm.c --- a/dwm.c Sun Nov 11 22:42:35 2007 +0100 +++ b/dwm.c Sun Nov 11 22:43:46 2007 +0100 @@ -125,6 +125,7 @@ void configure(Client *c); void configure(Client *c); void configurenotify(XEvent *e); void configurerequest(XEvent *e); +void deinitpertag(void); void destroynotify(XEvent *e); void detach(Client *c); void detachstack(Client *c); @@ -195,12 +196,11 @@ void zoom(const char *arg); /* variables */ char stext[256]; -double mwfact; -unsigned int nmaster; int screen, sx, sy, sw, sh, wax, way, waw, wah; int (*xerrorxlib)(Display *, XErrorEvent *); -unsigned int bh, bpos; +unsigned int bh; unsigned int blw = 0; +unsigned int csel = 0; unsigned int numlockmask = 0; void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = buttonpress, @@ -231,6 +231,11 @@ Layout *layout = NULL; Layout *layout = NULL; Window barwin, root; Regs *regs = NULL; + +unsigned int *bpos; +unsigned int *ltidxs; +unsigned int *nmasters; +double *mwfacts; /* configuration, allows nested code to access above variables */ #include "config.h" @@ -278,7 +283,7 @@ arrange(void) { unban(c); else ban(c); - layout->arrange(); + layouts[ltidxs[csel]].arrange(); focus(NULL); restack(); } @@ -339,20 +344,20 @@ buttonpress(XEvent *e) { if(CLEANMASK(ev->state) != MODKEY) return; if(ev->button == Button1) { - if((layout->arrange == floating) || c->isfloating) + if((layouts[ltidxs[csel]].arrange == floating) || c->isfloating) restack(); else togglefloating(NULL); movemouse(c); } else if(ev->button == Button2) { - if((floating != layout->arrange) && c->isfloating) + if((floating != layouts[ltidxs[csel]].arrange) && c->isfloating) togglefloating(NULL); else zoom(NULL); } else if(ev->button == Button3 && !c->isfixed) { - if((floating == layout->arrange) || c->isfloating) + if((floating == layouts[ltidxs[csel]].arrange) || c->isfloating) restack(); else togglefloating(NULL); @@ -397,6 +402,7 @@ cleanup(void) { XFreeCursor(dpy, cursor[CurMove]); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XSync(dpy, False); + deinitpertag(); } void @@ -468,7 +474,7 @@ configurerequest(XEvent *e) { c->ismax = False; if(ev->value_mask & CWBorderWidth) c->border = ev->border_width; - if(c->isfixed || c->isfloating || (floating == layout->arrange)) { + if(c->isfixed || c->isfloating || (floating == layouts[ltidxs[csel]].arrange)) { if(ev->value_mask & CWX) c->x = ev->x; if(ev->value_mask & CWY) @@ -501,6 +507,15 @@ configurerequest(XEvent *e) { XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); } XSync(dpy, False); +} + +void +deinitpertag(void) +{ + free(bpos); + free(ltidxs); + free(mwfacts); + free(nmasters); } void @@ -549,7 +564,7 @@ drawbar(void) { dc.x += dc.w; } dc.w = blw; - drawtext(layout->symbol, dc.norm); + drawtext(layouts[ltidxs[csel]].symbol, dc.norm); x = dc.x + dc.w; dc.w = textw(stext); dc.x = sw - dc.w; @@ -1266,9 +1281,9 @@ restack(void) { drawbar(); if(!sel) return; - if(sel->isfloating || (layout->arrange == floating)) + if(sel->isfloating || (layouts[ltidxs[csel]].arrange == floating)) XRaiseWindow(dpy, sel->win); - if(layout->arrange != floating) { + if(layouts[ltidxs[csel]].arrange != floating) { wc.stack_mode = Below; wc.sibling = barwin; if(!sel->isfloating) { @@ -1386,8 +1401,8 @@ setlayout(const char *arg) { unsigned int i; if(!arg) { - if(++layout == &layouts[LENGTH(layouts)]) - layout = &layouts[0]; + if(&layouts[++ltidxs[csel]] == &layouts[LENGTH(layouts)]) + ltidxs[csel] = 0;; } else { for(i = 0; i < LENGTH(layouts); i++) @@ -1395,7 +1410,7 @@ setlayout(const char *arg) { break; if(i == LENGTH(layouts)) return; - layout = &layouts[i]; + ltidxs[csel] = i; } if(sel) arrange(); @@ -1411,16 +1426,16 @@ setmwfact(const char *arg) { return; /* arg handling, manipulate mwfact */ if(arg == NULL) - mwfact = MWFACT; + mwfacts[csel] = MWFACT; else if(sscanf(arg, "%lf", &delta) == 1) { if(arg[0] == '+' || arg[0] == '-') - mwfact += delta; + mwfacts[csel] += delta; else - mwfact = delta; - if(mwfact < 0.1) - mwfact = 0.1; - else if(mwfact > 0.9) - mwfact = 0.9; + mwfacts[csel] = delta; + if(mwfacts[csel] < 0.1) + mwfacts[csel] = 0.1; + else if(mwfacts[csel] > 0.9) + mwfacts[csel] = 0.9; } arrange(); } @@ -1429,15 +1444,15 @@ setnmaster(const char *arg) { setnmaster(const char *arg) { int i; - if(layout->arrange != tile) + if(layouts[ltidxs[csel]].arrange != tile) return; if(!arg) - nmaster = NMASTER; + nmasters[csel] = NMASTER; else { i = atoi(arg); - if((nmaster + i) < 1 || wah / (nmaster + i) <= 2 * BORDERPX) + if((nmasters[csel] + i) < 1 || wah / (nmasters[csel] + i) <= 2 * BORDERPX) return; - nmaster += i; + nmasters[csel] += i; } if(sel) arrange(); @@ -1508,9 +1523,15 @@ setup(void) { dc.h = bh = dc.font.height + 2; /* init layouts */ - mwfact = MWFACT; - nmaster = NMASTER; - layout = &layouts[0]; + ltidxs = (unsigned int*)emallocz(sizeof(unsigned int) * LENGTH(tags)); + mwfacts = (double*)emallocz(sizeof(double) * LENGTH(tags)); + nmasters = (unsigned int*)emallocz(sizeof(unsigned int) * LENGTH(tags)); + for(i = 0; i < LENGTH(tags); i++) + { + ltidxs[i] = 0; + mwfacts[i] = MWFACT; + nmasters[i] = NMASTER; + } for(blw = i = 0; i < LENGTH(layouts); i++) { j = textw(layouts[i].symbol); if(j > blw) @@ -1518,7 +1539,9 @@ setup(void) { } /* init bar */ - bpos = BARPOS; + bpos = (unsigned int*)emallocz(sizeof(unsigned int) * LENGTH(tags)); + for(i = 0; i < LENGTH(tags); i++) + bpos[i] = BARPOS; wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ButtonPressMask | ExposureMask; @@ -1601,10 +1624,10 @@ tile(void) { n++; /* window geoms */ - mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; - mw = (n <= nmaster) ? waw : mwfact * waw; - th = (n > nmaster) ? wah / (n - nmaster) : 0; - if(n > nmaster && th < bh) + mh = (n <= nmasters[csel]) ? wah / (n > 0 ? n : 1) : wah / nmasters[csel]; + mw = (n == 1) ? waw : mwfacts[csel] * waw; + th = (n > nmasters[csel]) ? wah / (n - nmasters[csel]) : 0; + if(n > nmasters[csel] && th < bh) th = wah; nx = wax; @@ -1612,17 +1635,17 @@ tile(void) { nw = 0; /* gcc stupidity requires this */ for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next), i++) { c->ismax = False; - if(i < nmaster) { /* master */ + if(i < nmasters[csel]) { /* master */ ny = way + i * mh; nw = mw - 2 * c->border; nh = wah - 2 * c->border; nh = mh; - if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ + if(i + 1 == (n < nmasters[csel] ? n : nmasters[csel])) /* remainder */ nh = wah - mh * i; nh -= 2 * c->border; } else { /* tile window */ - if(i == nmaster) { + if(i == nmasters[csel]) { ny = way; nx += mc->w + 2 * mc->border; nw = waw - nx - 2 * c->border; @@ -1636,17 +1659,17 @@ tile(void) { if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw))) /* client doesn't accept size constraints */ resize(c, nx, ny, nw, nh, False); - if(n > nmaster && th != wah) + if(n > nmasters[csel] && th != wah) ny = c->y + c->h + 2 * c->border; } } void togglebar(const char *arg) { - if(bpos == BarOff) - bpos = (BARPOS == BarOff) ? BarTop : BARPOS; + if(bpos[csel] == BarOff) + bpos[csel] = (BARPOS == BarOff) ? BarTop : BARPOS; else - bpos = BarOff; + bpos[csel] = BarOff; updatebarpos(); arrange(); } @@ -1668,7 +1691,7 @@ togglemax(const char *arg) { if(!sel || sel->isfixed) return; if((sel->ismax = !sel->ismax)) { - if((layout->arrange == floating) || sel->isfloating) + if((layouts[ltidxs[csel]].arrange == floating) || sel->isfloating) sel->wasfloating = True; else { togglefloating(NULL); @@ -1710,8 +1733,12 @@ toggleview(const char *arg) { i = idxoftag(arg); seltags[i] = !seltags[i]; for(j = 0; j < LENGTH(tags) && !seltags[j]; j++); - if(j == LENGTH(tags)) + if(j == LENGTH(tags)) { seltags[i] = True; /* at least one tag must be viewed */ + j = i; + } + if(csel == i) + csel = j; arrange(); } @@ -1763,7 +1790,7 @@ updatebarpos(void) { way = sy; wah = sh; waw = sw; - switch(bpos) { + switch(bpos[csel]) { default: wah -= bh; way += bh; @@ -1873,22 +1900,33 @@ xerrorstart(Display *dsply, XErrorEvent void view(const char *arg) { - unsigned int i; + unsigned int i, prevcsel; memcpy(prevtags, seltags, sizeof seltags); for(i = 0; i < LENGTH(tags); i++) seltags[i] = (NULL == arg); seltags[idxoftag(arg)] = True; + prevcsel = csel; + csel = idxoftag(arg); + if (bpos[prevcsel] != bpos[csel]) + updatebarpos(); arrange(); } void viewprevtag(const char *arg) { static Bool tmp[LENGTH(tags)]; + unsigned int i, prevcsel; + i = 0; + while(i < LENGTH(tags) && !prevtags[i]) i++; + prevcsel = csel; + csel = i; memcpy(tmp, seltags, sizeof seltags); memcpy(seltags, prevtags, sizeof seltags); memcpy(prevtags, tmp, sizeof seltags); + if (bpos[prevcsel] != bpos[csel]) + updatebarpos(); arrange(); }