X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=dwm.c;h=39b0a51097d2876e4122114ecd57b5bc030b07a0;hp=05ab119df8a0fb5399ff284ba292c5ff34f45613;hb=0f1f30daca0eaf0a400fd3f8d274594c07b32a51;hpb=2255bf46a0af475e70fb4cc90d912b435f21eb5e diff --git a/dwm.c b/dwm.c index 05ab119..39b0a51 100644 --- a/dwm.c +++ b/dwm.c @@ -42,7 +42,7 @@ /* macros */ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) -#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask)) +#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -289,31 +289,31 @@ applyrules(Client *c) { unsigned int i; const Rule *r; Monitor *m; - XClassHint ch = { 0 }; + XClassHint ch = { NULL, NULL }; /* rule matching */ c->isfloating = c->tags = 0; - if(XGetClassHint(dpy, c->win, &ch)) { - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; - for(i = 0; i < LENGTH(rules); i++) { - r = &rules[i]; - if((!r->title || strstr(c->name, r->title)) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; - for(m = mons; m && m->num != r->monitor; m = m->next); - if(m) - c->mon = m; - } + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; + + for(i = 0; i < LENGTH(rules); i++) { + r = &rules[i]; + if((!r->title || strstr(c->name, r->title)) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; + for(m = mons; m && m->num != r->monitor; m = m->next); + if(m) + c->mon = m; } - if(ch.res_class) - XFree(ch.res_class); - if(ch.res_name) - XFree(ch.res_name); } + if(ch.res_class) + XFree(ch.res_class); + if(ch.res_name) + XFree(ch.res_name); c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; } @@ -389,7 +389,6 @@ arrange(Monitor *m) { showhide(m->stack); else for(m = mons; m; m = m->next) showhide(m->stack); - focus(NULL); if(m) arrangemon(m); else for(m = mons; m; m = m->next) @@ -433,16 +432,16 @@ buttonpress(XEvent *e) { } if(ev->window == selmon->barwin) { i = x = 0; - do { + do x += TEXTW(tags[i]); - } while(ev->x >= x && ++i < LENGTH(tags)); + while(ev->x >= x && ++i < LENGTH(tags)); if(i < LENGTH(tags)) { click = ClkTagBar; arg.ui = 1 << i; } else if(ev->x < x + blw) click = ClkLtSymbol; - else if(ev->x > selmon->wx + selmon->ww - TEXTW(stext)) + else if(ev->x > selmon->ww - TEXTW(stext)) click = ClkStatusText; else click = ClkWinTitle; @@ -529,7 +528,7 @@ clientmessage(XEvent *e) { if(!c) return; if(cme->message_type == netatom[NetWMState] && cme->data.l[1] == netatom[NetWMFullscreen]) { - if(cme->data.l[0]) { + if(cme->data.l[0] && !c->isfullscreen) { XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); c->isfullscreen = True; @@ -585,17 +584,20 @@ void configurenotify(XEvent *e) { Monitor *m; XConfigureEvent *ev = &e->xconfigure; + Bool dirty; if(ev->window == root) { + dirty = (sw != ev->width); sw = ev->width; sh = ev->height; - if(updategeom()) { + if(updategeom() || dirty) { if(dc.drawable != 0) XFreePixmap(dpy, dc.drawable); dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); updatebars(); for(m = mons; m; m = m->next) XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + focus(NULL); arrange(NULL); } } @@ -613,18 +615,26 @@ configurerequest(XEvent *e) { c->bw = ev->border_width; else if(c->isfloating || !selmon->lt[selmon->sellt]->arrange) { m = c->mon; - if(ev->value_mask & CWX) + if(ev->value_mask & CWX) { + c->oldx = c->x; c->x = m->mx + ev->x; - if(ev->value_mask & CWY) + } + if(ev->value_mask & CWY) { + c->oldy = c->y; c->y = m->my + ev->y; - if(ev->value_mask & CWWidth) + } + if(ev->value_mask & CWWidth) { + c->oldw = c->w; c->w = ev->width; - if(ev->value_mask & CWHeight) + } + if(ev->value_mask & CWHeight) { + c->oldh = c->h; c->h = ev->height; + } if((c->x + c->w) > m->mx + m->mw && c->isfloating) - c->x = m->mx + (m->mw / 2 - c->w / 2); /* center in x direction */ + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ if((c->y + c->h) > m->my + m->mh && c->isfloating) - c->y = m->my + (m->mh / 2 - c->h / 2); /* center in y direction */ + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) configure(c); if(ISVISIBLE(c)) @@ -710,12 +720,10 @@ dirtomon(int dir) { if(!(m = selmon->next)) m = mons; } - else { - if(selmon == mons) - for(m = mons; m->next; m = m->next); - else - for(m = mons; m->next != selmon; m = m->next); - } + else if(selmon == mons) + for(m = mons; m->next; m = m->next); + else + for(m = mons; m->next != selmon; m = m->next); return m; } @@ -781,7 +789,7 @@ void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { int x; - XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); + XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); x = (dc.font.ascent + dc.font.descent + 2) / 4; if(filled) XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1); @@ -818,16 +826,21 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { void enternotify(XEvent *e) { + Client *c; Monitor *m; XCrossingEvent *ev = &e->xcrossing; if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; - if((m = wintomon(ev->window)) && m != selmon) { + c = wintoclient(ev->window); + m = c ? c->mon : wintomon(ev->window); + if(m != selmon) { unfocus(selmon->sel, True); selmon = m; } - focus((wintoclient(ev->window))); + else if(!c || c == selmon->sel) + return; + focus(c); } void @@ -1002,12 +1015,11 @@ grabkeys(void) { KeyCode code; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) { + for(i = 0; i < LENGTH(keys); i++) if((code = XKeysymToKeycode(dpy, keys[i].keysym))) for(j = 0; j < LENGTH(modifiers); j++) XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); - } } } @@ -1016,7 +1028,6 @@ initfont(const char *fontstr) { char *def, **missing; int n; - missing = NULL; dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) { while(n--) @@ -1106,13 +1117,13 @@ manage(Window w, XWindowAttributes *wa) { applyrules(c); } /* geometry */ - c->x = c->oldx = wa->x + c->mon->wx; - c->y = c->oldy = wa->y + c->mon->wy; + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; c->oldbw = wa->border_width; if(c->w == c->mon->mw && c->h == c->mon->mh) { - c->isfloating = True; + c->isfloating = True; // regression with flash, XXXX c->x = c->mon->mx; c->y = c->mon->my; c->bw = 0; @@ -1143,9 +1154,13 @@ manage(Window w, XWindowAttributes *wa) { attach(c); attachstack(c); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - XMapWindow(dpy, c->win); setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, False); + c->mon->sel = c; arrange(c->mon); + XMapWindow(dpy, c->win); + focus(NULL); } void @@ -1296,6 +1311,7 @@ ptrtomon(int x, int y) { return m; return selmon; } + void quit(const Arg *arg) { running = False; @@ -1400,10 +1416,9 @@ run(void) { XEvent ev; /* main event loop */ XSync(dpy, False); - while(running && !XNextEvent(dpy, &ev)) { + while(running && !XNextEvent(dpy, &ev)) if(handler[ev.type]) handler[ev.type](&ev); /* call handler */ - } } void @@ -1610,6 +1625,7 @@ void tag(const Arg *arg) { if(selmon->sel && arg->ui & TAGMASK) { selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); arrange(selmon); } } @@ -1648,9 +1664,9 @@ tile(Monitor *m) { if(--n == 0) return; /* tile stack */ - x = (m->wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : m->wx + mw; + x = (m->wx > c->x) ? c->x + mw + 2 * c->bw : m->wx + mw; y = m->wy; - w = (m->wx + mw > c->x + c->w) ? m->wx + m->ww - x : m->ww - mw; + w = (m->wx > c->x) ? m->wx + m->ww - x : m->ww - mw; h = m->wh / n; if(h < bh) h = m->wh; @@ -1690,6 +1706,7 @@ toggletag(const Arg *arg) { newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); if(newtags) { selmon->sel->tags = newtags; + focus(NULL); arrange(selmon); } } @@ -1700,6 +1717,7 @@ toggleview(const Arg *arg) { if(newtagset) { selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); arrange(selmon); } } @@ -1743,8 +1761,12 @@ unmapnotify(XEvent *e) { Client *c; XUnmapEvent *ev = &e->xunmap; - if((c = wintoclient(ev->window))) - unmanage(c, False); + if((c = wintoclient(ev->window))) { + if(ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, False); + } } void @@ -1965,6 +1987,7 @@ view(const Arg *arg) { selmon->seltags ^= 1; /* toggle sel tagset */ if(arg->ui & TAGMASK) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focus(NULL); arrange(selmon); } @@ -2034,7 +2057,6 @@ zoom(const Arg *arg) { Client *c = selmon->sel; if(!selmon->lt[selmon->sellt]->arrange - || selmon->lt[selmon->sellt]->arrange == monocle || (selmon->sel && selmon->sel->isfloating)) return; if(c == nexttiled(selmon->clients)) @@ -2046,7 +2068,7 @@ zoom(const Arg *arg) { int main(int argc, char *argv[]) { if(argc == 2 && !strcmp("-v", argv[1])) - die("dwm-"VERSION", © 2006-2010 dwm engineers, see LICENSE for details\n"); + die("dwm-"VERSION", © 2006-2011 dwm engineers, see LICENSE for details\n"); else if(argc != 1) die("usage: dwm [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())