X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=dwm.c;h=487fafb8a7896039c34ee8eee99ed646b9baa578;hb=13577b15e5ef15fb151d4a1444f6d07a689f967c;hp=726e7975b7bd1dba93a31401af189631c64dac93;hpb=fe2775a15ba2d4900788c57194da2bad3d19cfaf;p=dwm.git diff --git a/dwm.c b/dwm.c index 726e797..487fafb 100644 --- a/dwm.c +++ b/dwm.c @@ -27,14 +27,15 @@ */ #include #include -#include #include #include #include #include #include #include +#include #include +#include #include #include #include @@ -62,9 +63,9 @@ struct Client { int rx, ry, rw, rh; /* revert geometry */ int basew, baseh, incw, inch, maxw, maxh, minw, minh; int minax, maxax, minay, maxay; - long flags; + long flags; unsigned int border, oldborder; - Bool isbanned, isfixed, ismax, isfloating; + Bool isbanned, isfixed, ismax, isfloating, wasfloating; Bool *tags; Client *next; Client *prev; @@ -110,7 +111,7 @@ typedef struct { regex_t *tagregex; } Regs; -/* forward declarations */ +/* function declarations */ void applyrules(Client *c); void arrange(void); void attach(Client *c); @@ -184,6 +185,7 @@ void updatebarpos(void); void updatesizehints(Client *c); void updatetitle(Client *c); void view(const char *arg); +void viewprevtag(const char *arg); /* views previous selected tags */ int xerror(Display *dpy, XErrorEvent *ee); int xerrordummy(Display *dsply, XErrorEvent *ee); int xerrorstart(Display *dsply, XErrorEvent *ee); @@ -194,7 +196,7 @@ char stext[256]; double mwfact; int screen, sx, sy, sw, sh, wax, way, waw, wah; int (*xerrorxlib)(Display *, XErrorEvent *); -unsigned int bh, bpos, ntags; +unsigned int bh, bpos; unsigned int blw = 0; unsigned int ltidx = 0; /* default */ unsigned int nlayouts = 0; @@ -217,7 +219,6 @@ void (*handler[LASTEvent]) (XEvent *) = { Atom wmatom[WMLast], netatom[NetLast]; Bool otherwm, readin; Bool running = True; -Bool *seltags; Bool selscreen = True; Client *clients = NULL; Client *sel = NULL; @@ -231,7 +232,11 @@ Regs *regs = NULL; /* configuration, allows nested code to access above variables */ #include "config.h" -/* functions*/ +#define NTAGS (sizeof tags / sizeof tags[0]) +Bool seltags[NTAGS] = {[0] = True}; +Bool prevtags[NTAGS] = {[0] = True}; + +/* function implementations */ void applyrules(Client *c) { static char buf[512]; @@ -248,7 +253,7 @@ applyrules(Client *c) { for(i = 0; i < nrules; i++) if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) { c->isfloating = rules[i].isfloating; - for(j = 0; regs[i].tagregex && j < ntags; j++) { + for(j = 0; regs[i].tagregex && j < NTAGS; j++) { if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { matched = True; c->tags[j] = True; @@ -260,8 +265,7 @@ applyrules(Client *c) { if(ch.res_name) XFree(ch.res_name); if(!matched) - for(i = 0; i < ntags; i++) - c->tags[i] = seltags[i]; + memcpy(c->tags, seltags, sizeof seltags); } void @@ -308,7 +312,7 @@ buttonpress(XEvent *e) { if(barwin == ev->window) { x = 0; - for(i = 0; i < ntags; i++) { + for(i = 0; i < NTAGS; i++) { x += textw(tags[i]); if(ev->x < x) { if(ev->button == Button1) { @@ -334,23 +338,23 @@ buttonpress(XEvent *e) { if(CLEANMASK(ev->state) != MODKEY) return; if(ev->button == Button1) { - if(!isarrange(floating) && !c->isfloating) - togglefloating(NULL); - else + if(isarrange(floating) || c->isfloating) restack(); + else + togglefloating(NULL); movemouse(c); } else if(ev->button == Button2) { - if(isarrange(tile) && !c->isfixed && c->isfloating) + if((ISTILE) && !c->isfixed && c->isfloating) togglefloating(NULL); else zoom(NULL); } else if(ev->button == Button3 && !c->isfixed) { - if(!isarrange(floating) && !c->isfloating) - togglefloating(NULL); - else + if(isarrange(floating) || c->isfloating) restack(); + else + togglefloating(NULL); resizemouse(c); } } @@ -392,7 +396,6 @@ cleanup(void) { XFreeCursor(dpy, cursor[CurMove]); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XSync(dpy, False); - free(seltags); } void @@ -444,7 +447,7 @@ void configurenotify(XEvent *e) { XConfigureEvent *ev = &e->xconfigure; - if (ev->window == root && (ev->width != sw || ev->height != sh)) { + if(ev->window == root && (ev->width != sw || ev->height != sh)) { sw = ev->width; sh = ev->height; XFreePixmap(dpy, dc.drawable); @@ -533,7 +536,7 @@ drawbar(void) { int i, x; dc.x = dc.y = 0; - for(i = 0; i < ntags; i++) { + for(i = 0; i < NTAGS; i++) { dc.w = textw(tags[i]); if(seltags[i]) { drawtext(tags[i], dc.sel); @@ -843,10 +846,8 @@ unsigned int idxoftag(const char *tag) { unsigned int i; - for(i = 0; i < ntags; i++) - if(tags[i] == tag) - return i; - return 0; + for(i = 0; (i < NTAGS) && (tags[i] != tag); i++); + return (i < NTAGS) ? i : 0; } void @@ -883,7 +884,7 @@ initfont(const char *fontstr) { XFreeFont(dpy, dc.font.xfont); dc.font.xfont = NULL; if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) - || !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) + && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) eprint("error, cannot load font: '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; @@ -926,7 +927,7 @@ Bool isvisible(Client *c) { unsigned int i; - for(i = 0; i < ntags; i++) + for(i = 0; i < NTAGS; i++) if(c->tags[i] && seltags[i]) return True; return False; @@ -998,14 +999,13 @@ leavenotify(XEvent *e) { void manage(Window w, XWindowAttributes *wa) { - unsigned int i; Client *c, *t = NULL; Window trans; Status rettrans; XWindowChanges wc; c = emallocz(sizeof(Client)); - c->tags = emallocz(ntags * sizeof(Bool)); + c->tags = emallocz(sizeof seltags); c->win = w; c->x = wa->x; c->y = wa->y; @@ -1040,8 +1040,7 @@ manage(Window w, XWindowAttributes *wa) { if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) for(t = clients; t && t->win != trans; t = t->next); if(t) - for(i = 0; i < ntags; i++) - c->tags[i] = t->tags[i]; + memcpy(c->tags, t->tags, sizeof seltags); applyrules(c); if(!c->isfloating) c->isfloating = (rettrans == Success) || c->isfixed; @@ -1138,7 +1137,7 @@ propertynotify(XEvent *e) { default: break; case XA_WM_TRANSIENT_FOR: XGetTransientForHint(dpy, c->win, &trans); - if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL))) + if(!c->isfloating && (c->isfloating = (NULL != getclient(trans)))) arrange(); break; case XA_WM_NORMAL_HINTS: @@ -1160,43 +1159,45 @@ quit(const char *arg) { void resize(Client *c, int x, int y, int w, int h, Bool sizehints) { - double dx, dy, max, min, ratio; - XWindowChanges wc; + XWindowChanges wc; if(sizehints) { - if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0 && (w - c->basew) > 0) { - dx = (double)(w - c->basew); - dy = (double)(h - c->baseh); - min = (double)(c->minax) / (double)(c->minay); - max = (double)(c->maxax) / (double)(c->maxay); - ratio = dx / dy; - if(max > 0 && min > 0 && ratio > 0) { - if(ratio < min) { - dy = (dx * min + dy) / (min * min + 1); - dx = dy * min; - w = (int)dx + c->basew; - h = (int)dy + c->baseh; - } - else if(ratio > max) { - dy = (dx * min + dy) / (max * max + 1); - dx = dy * min; - w = (int)dx + c->basew; - h = (int)dy + c->baseh; - } - } + /* set minimum possible */ + if (w < 1) + w = 1; + if (h < 1) + h = 1; + + /* temporarily remove base dimensions */ + w -= c->basew; + h -= c->baseh; + + /* adjust for aspect limits */ + if (c->minay > 0 && c->maxay > 0 && c->minax > 0 && c->maxax > 0) { + if (w * c->maxay > h * c->maxax) + w = h * c->maxax / c->maxay; + else if (w * c->minay < h * c->minax) + h = w * c->minay / c->minax; } - if(c->minw && w < c->minw) + + /* adjust for increment value */ + if(c->incw) + w -= w % c->incw; + if(c->inch) + h -= h % c->inch; + + /* restore base dimensions */ + w += c->basew; + h += c->baseh; + + if(c->minw > 0 && w < c->minw) w = c->minw; - if(c->minh && h < c->minh) + if(c->minh > 0 && h < c->minh) h = c->minh; - if(c->maxw && w > c->maxw) + if(c->maxw > 0 && w > c->maxw) w = c->maxw; - if(c->maxh && h > c->maxh) + if(c->maxh > 0 && h > c->maxh) h = c->maxh; - if(c->incw) - w -= (w - c->basew) % c->incw; - if(c->inch) - h -= (h - c->baseh) % c->inch; } if(w <= 0 || h <= 0) return; @@ -1398,16 +1399,16 @@ void setmwfact(const char *arg) { double delta; - if(!isarrange(tile)) + if(!(ISTILE)) return; /* arg handling, manipulate mwfact */ if(arg == NULL) mwfact = MWFACT; else if(1 == sscanf(arg, "%lf", &delta)) { - if(arg[0] != '+' && arg[0] != '-') - mwfact = delta; - else + if(arg[0] == '+' || arg[0] == '-') mwfact += delta; + else + mwfact = delta; if(mwfact < 0.1) mwfact = 0.1; else if(mwfact > 0.9) @@ -1418,6 +1419,7 @@ setmwfact(const char *arg) { void setup(void) { + int d; unsigned int i, j, mask; Window w; XModifierKeymap *modmap; @@ -1465,9 +1467,6 @@ setup(void) { /* init tags */ compileregs(); - for(ntags = 0; tags[ntags]; ntags++); - seltags = emallocz(sizeof(Bool) * ntags); - seltags[0] = True; /* init appearance */ dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); @@ -1507,7 +1506,7 @@ setup(void) { XSetFont(dpy, dc.gc, dc.font.xfont->fid); /* multihead support */ - selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); + selscreen = XQueryPointer(dpy, root, &w, &w, &d, &d, &d, &d, &mask); } void @@ -1540,11 +1539,9 @@ tag(const char *arg) { if(!sel) return; - for(i = 0; i < ntags; i++) - sel->tags[i] = arg == NULL; - i = idxoftag(arg); - if(i >= 0 && i < ntags) - sel->tags[i] = True; + for(i = 0; i < NTAGS; i++) + sel->tags[i] = (NULL == arg); + sel->tags[idxoftag(arg)] = True; arrange(); } @@ -1567,7 +1564,7 @@ textw(const char *text) { void tile(void) { unsigned int i, n, nx, ny, nw, nh, mw, th; - Client *c; + Client *c, *mc; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) n++; @@ -1580,7 +1577,8 @@ tile(void) { nx = wax; ny = way; - for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { + nw = 0; /* gcc stupidity requires this */ + for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next), i++) { c->ismax = False; if(i == 0) { /* master */ nw = mw - 2 * c->border; @@ -1589,17 +1587,20 @@ tile(void) { else { /* tile window */ if(i == 1) { ny = way; - nx += mw; + nx += mc->w + 2 * mc->border; + nw = waw - nx - 2 * c->border; } - nw = waw - mw - 2 * c->border; if(i + 1 == n) /* remainder */ nh = (way + wah) - ny - 2 * c->border; else nh = th - 2 * c->border; } - resize(c, nx, ny, nw, nh, RESIZEHINTS); + resize(c, nx, ny, nw, nh, True); + if((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 > 1 && th != wah) - ny += nh + 2 * c->border; + ny = c->y + c->h + 2 * c->border; } } @@ -1627,17 +1628,26 @@ void togglemax(const char *arg) { XEvent ev; - if(!sel || (!isarrange(floating) && !sel->isfloating) || sel->isfixed) + if(!sel || sel->isfixed) return; if((sel->ismax = !sel->ismax)) { + if(isarrange(floating) || sel->isfloating) + sel->wasfloating = True; + else { + togglefloating(NULL); + sel->wasfloating = False; + } sel->rx = sel->x; sel->ry = sel->y; sel->rw = sel->w; sel->rh = sel->h; resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True); } - else + else { resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True); + if(!sel->wasfloating) + togglefloating(NULL); + } drawbar(); while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } @@ -1650,9 +1660,9 @@ toggletag(const char *arg) { return; i = idxoftag(arg); sel->tags[i] = !sel->tags[i]; - for(j = 0; j < ntags && !sel->tags[j]; j++); - if(j == ntags) - sel->tags[i] = True; + for(j = 0; j < NTAGS && !sel->tags[j]; j++); + if(j == NTAGS) + sel->tags[i] = True; /* at least one tag must be enabled */ arrange(); } @@ -1662,9 +1672,9 @@ toggleview(const char *arg) { i = idxoftag(arg); seltags[i] = !seltags[i]; - for(j = 0; j < ntags && !seltags[j]; j++); - if(j == ntags) - seltags[i] = True; /* cannot toggle last view */ + for(j = 0; j < NTAGS && !seltags[j]; j++); + if(j == NTAGS) + seltags[i] = True; /* at least one tag must be viewed */ arrange(); } @@ -1828,11 +1838,20 @@ void view(const char *arg) { unsigned int i; - for(i = 0; i < ntags; i++) + memcpy(prevtags, seltags, sizeof seltags); + for(i = 0; i < NTAGS; i++) seltags[i] = arg == NULL; - i = idxoftag(arg); - if(i >= 0 && i < ntags) - seltags[i] = True; + seltags[idxoftag(arg)] = True; + arrange(); +} + +void +viewprevtag(const char *arg) { + static Bool tmptags[sizeof tags / sizeof tags[0]]; + + memcpy(tmptags, seltags, sizeof seltags); + memcpy(seltags, prevtags, sizeof seltags); + memcpy(prevtags, tmptags, sizeof seltags); arrange(); } @@ -1840,7 +1859,7 @@ void zoom(const char *arg) { Client *c; - if(!sel || !isarrange(tile) || sel->isfloating) + if(!sel || !(ISTILE) || sel->isfloating) return; if((c = sel) == nexttiled(clients)) if(!(c = nexttiled(c->next)))