X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=dwm.c;h=a77f4c8ec8b4f73eda9084745de291f5d3db1b61;hb=7f70d90219c4a33c79ff93b49fb24ee7a6f62b4d;hp=9dd501a6ed836194fa07f7d550fda2ee6408eac1;hpb=721b208478a907e21193a738e8c3ed3f91048c1a;p=dwm.git diff --git a/dwm.c b/dwm.c index 9dd501a..a77f4c8 100644 --- a/dwm.c +++ b/dwm.c @@ -41,6 +41,8 @@ #include /* macros */ +#define MAX(a, b) ((a)>(b)?(a):(b)) +#define MIN(a, b) ((a)<(b)?(a):(b)) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask)) #define LENGTH(x) (sizeof x / sizeof x[0]) @@ -66,6 +68,7 @@ typedef struct Client Client; struct Client { char name[256]; int x, y, w, h; + int fx, fy, fw, fh; int basew, baseh, incw, inch, maxw, maxh, minw, minh; int minax, maxax, minay, maxay; long flags; @@ -142,7 +145,6 @@ void *emallocz(unsigned int size); void enternotify(XEvent *e); void eprint(const char *errstr, ...); void expose(XEvent *e); -void floating(void); /* default floating layout */ void focus(Client *c); void focusin(XEvent *e); void focusnext(const char *arg); @@ -208,10 +210,11 @@ int xerrorstart(Display *dpy, XErrorEvent *ee); void zoom(const char *arg); /* variables */ -char stext[256], buf[256]; +char stext[256]; int screen, sx, sy, sw, sh; int (*xerrorxlib)(Display *, XErrorEvent *); int bx, by, bw, bh, blw, bgw, mx, my, mw, mh, mox, moy, mow, moh, tx, ty, tw, th, wx, wy, ww, wh; +int viewtags_set = 0; double mfact; unsigned int numlockmask = 0; void (*handler[LASTEvent]) (XEvent *) = { @@ -231,22 +234,21 @@ void (*handler[LASTEvent]) (XEvent *) = { Atom wmatom[WMLast], netatom[NetLast]; Bool otherwm, readin; Bool running = True; -Bool *prevtags; Bool *seltags; +Bool *viewtags[2]; Client *clients = NULL; Client *sel = NULL; Client *stack = NULL; Cursor cursor[CurLast]; Display *dpy; DC dc = {0}; -Geom *geom = NULL; -Layout *lt = NULL; Window root, barwin; /* configuration, allows nested code to access above variables */ #include "config.h" #define TAGSZ (LENGTH(tags) * sizeof(Bool)) -static Bool tmp[LENGTH(tags)]; +Layout *lt = layouts; +Geom *geom = geoms; /* function implementations */ @@ -262,9 +264,8 @@ applyrules(Client *c) { for(i = 0; i < LENGTH(rules); i++) { r = &rules[i]; if((!r->title || strstr(c->name, r->title)) - && (!ch.res_class || !r->class || strstr(ch.res_class, r->class)) - && (!ch.res_name || !r->instance || strstr(ch.res_name, r->instance))) - { + && (!r->class || (ch.res_class && strstr(ch.res_class, r->class))) + && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) { c->isfloating = r->isfloating; if(r->tag) { c->tags[idxoftag(r->tag)] = True; @@ -285,13 +286,17 @@ arrange(void) { Client *c; for(c = clients; c; c = c->next) - if(isvisible(c)) + if(isvisible(c)) { unban(c); + if(lt->isfloating || c->isfloating) + resize(c, c->fx, c->fy, c->fw, c->fh, True); + } else ban(c); focus(NULL); - lt->arrange(); + if(lt->arrange) + lt->arrange(); restack(); } @@ -359,7 +364,7 @@ buttonpress(XEvent *e) { movemouse(c); } else if(ev->button == Button2) { - if((floating != lt->arrange) && c->isfloating) + if(!lt->isfloating && c->isfloating) togglefloating(NULL); else zoom(NULL); @@ -596,23 +601,23 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { int x, y, w, h; unsigned int len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + char buf[256]; XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); if(!text) return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; + olen = strlen(text); + len = MIN(olen, sizeof buf); memcpy(buf, text, len); - buf[len] = 0; + w = 0; h = dc.font.ascent + dc.font.descent; y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; + for(; len && (w = textnw(buf, len)) > dc.w - h; len--); + if (!len) + return; if(len < olen) { if(len > 1) buf[len - 1] = '.'; @@ -621,8 +626,6 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { if(len > 3) buf[len - 3] = '.'; } - if(w > dc.w) - return; /* too long */ XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); @@ -671,15 +674,6 @@ expose(XEvent *e) { } void -floating(void) { /* default floating layout */ - Client *c; - - for(c = clients; c; c = c->next) - if(isvisible(c)) - resize(c, c->x, c->y, c->w, c->h, True); -} - -void focus(Client *c) { if(!c || (c && !isvisible(c))) for(c = stack; c && !isvisible(c); c = c->snext); @@ -881,10 +875,8 @@ initfont(const char *fontstr) { font_extents = XExtentsOfFontSet(dc.font.set); n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) { - if(dc.font.ascent < (*xfonts)->ascent) - dc.font.ascent = (*xfonts)->ascent; - if(dc.font.descent < (*xfonts)->descent) - dc.font.descent = (*xfonts)->descent; + dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); + dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent); xfonts++; } } @@ -996,8 +988,8 @@ manage(Window w, XWindowAttributes *wa) { /* geometry */ c->x = wa->x; c->y = wa->y; - c->w = wa->width; - c->h = wa->height; + c->w = c->fw = wa->width; + c->h = c->fh = wa->height; c->oldbw = wa->border_width; if(c->w == sw && c->h == sh) { c->x = sx; @@ -1009,12 +1001,12 @@ manage(Window w, XWindowAttributes *wa) { c->x = wx + ww - c->w - 2 * c->bw; if(c->y + c->h + 2 * c->bw > wy + wh) c->y = wy + wh - c->h - 2 * c->bw; - if(c->x < wx) - c->x = wx; - if(c->y < wy) - c->y = wy; + c->x = MAX(c->x, wx); + c->y = MAX(c->y, wy); c->bw = BORDERPX; } + c->fx = c->x; + c->fy = c->y; wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc); @@ -1110,8 +1102,11 @@ movemouse(Client *c) { ny = wy + wh - c->h - 2 * c->bw; if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP)) togglefloating(NULL); - if((lt->isfloating) || c->isfloating) + if(lt->isfloating || c->isfloating) { + c->fx = nx; + c->fy = ny; resize(c, nx, ny, c->w, c->h, False); + } break; } } @@ -1162,11 +1157,10 @@ quit(const char *arg) { void reapply(const char *arg) { - static Bool zerotags[LENGTH(tags)] = { 0 }; Client *c; for(c = clients; c; c = c->next) { - memcpy(c->tags, zerotags, sizeof zerotags); + memset(c->tags, 0, TAGSZ); applyrules(c); } arrange(); @@ -1178,10 +1172,8 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) { if(sizehints) { /* set minimum possible */ - if(w < 1) - w = 1; - if(h < 1) - h = 1; + w = MAX(1, w); + h = MAX(1, h); /* temporarily remove base dimensions */ w -= c->basew; @@ -1207,14 +1199,14 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) { w += c->basew; h += c->baseh; - if(c->minw > 0 && w < c->minw) - w = c->minw; - if(c->minh > 0 && h < c->minh) - h = c->minh; - if(c->maxw > 0 && w > c->maxw) - w = c->maxw; - if(c->maxh > 0 && h > c->maxh) - h = c->maxh; + w = MAX(w, c->minw); + h = MAX(h, c->minh); + + if (c->maxw) + w = MIN(w, c->maxw); + + if (c->maxh) + h = MIN(h, c->maxh); } if(w <= 0 || h <= 0) return; @@ -1267,14 +1259,18 @@ resizemouse(Client *c) { break; case MotionNotify: XSync(dpy, False); - if((nw = ev.xmotion.x - ocx - 2 * c->bw + 1) <= 0) - nw = 1; - if((nh = ev.xmotion.y - ocy - 2 * c->bw + 1) <= 0) - nh = 1; - if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); + nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); + if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) { + c->fx = c->x; + c->fy = c->y; togglefloating(NULL); - if((lt->isfloating) || c->isfloating) + } + if((lt->isfloating) || c->isfloating) { resize(c, c->x, c->y, nw, nh, True); + c->fw = nw; + c->fh = nh; + } break; } } @@ -1294,16 +1290,11 @@ restack(void) { if(!lt->isfloating) { wc.stack_mode = Below; wc.sibling = barwin; - if(!sel->isfloating) { - XConfigureWindow(dpy, sel->win, CWSibling|CWStackMode, &wc); - wc.sibling = sel->win; - } - for(c = nexttiled(clients); c; c = nexttiled(c->next)) { - if(c == sel) - continue; - XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); - wc.sibling = c->win; - } + for(c = stack; c; c = c->snext) + if(!c->isfloating && isvisible(c)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } } XSync(dpy, False); while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); @@ -1483,7 +1474,6 @@ setup(void) { sh = DisplayHeight(dpy, screen); bh = dc.font.height + 2; mfact = MFACT; - geom = &geoms[0]; geom->apply(); /* init atoms */ @@ -1515,23 +1505,19 @@ setup(void) { XSetFont(dpy, dc.gc, dc.font.xfont->fid); /* init tags */ - seltags = emallocz(TAGSZ); - prevtags = emallocz(TAGSZ); - seltags[0] = prevtags[0] = True; - - /* init layouts */ - lt = &layouts[0]; + viewtags[0] = emallocz(TAGSZ); + viewtags[1] = emallocz(TAGSZ); + viewtags[0][0] = viewtags[1][0] = True; + seltags = viewtags[0]; /* init bar */ for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { w = textw(layouts[i].symbol); - if(w > blw) - blw = w; + blw = MAX(blw, w); } for(bgw = i = 0; LENGTH(geoms) > 1 && i < LENGTH(geoms); i++) { w = textw(geoms[i].symbol); - if(w > bgw) - bgw = w; + bgw = MAX(bgw, w); } wa.override_redirect = 1; @@ -1842,9 +1828,9 @@ updatewmhints(Client *c) { } } - void view(const char *arg) { + Bool tmp[LENGTH(tags)]; unsigned int i; for(i = 0; i < LENGTH(tags); i++) @@ -1852,18 +1838,17 @@ view(const char *arg) { tmp[idxoftag(arg)] = True; if(memcmp(seltags, tmp, TAGSZ) != 0) { - memcpy(prevtags, seltags, TAGSZ); + seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ memcpy(seltags, tmp, TAGSZ); arrange(); } + else + viewprevtag(NULL); } void viewprevtag(const char *arg) { - - memcpy(tmp, seltags, TAGSZ); - memcpy(seltags, prevtags, TAGSZ); - memcpy(prevtags, tmp, TAGSZ); + seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ arrange(); } @@ -1903,14 +1888,14 @@ void zoom(const char *arg) { Client *c = sel; - if(!sel || lt->isfloating || sel->isfloating) - return; if(c == nexttiled(clients)) - if(!(c = nexttiled(c->next))) + if(!c || !(c = nexttiled(c->next))) return; - detach(c); - attach(c); - focus(c); + if(!lt->isfloating && !sel->isfloating) { + detach(c); + attach(c); + focus(c); + } arrange(); } @@ -1934,3 +1919,4 @@ main(int argc, char *argv[]) { XCloseDisplay(dpy); return 0; } +