JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
some cleanups
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index 2e13241..9e049c6 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -11,9 +11,9 @@
  * in O(1) time.
  *
  * Each child of the root window is called a client, except windows which have
- * set the override_redirect flag.  Clients are organized in a global
- * linked client list, the focus history is remembered through a global
- * stack list. Each client contains a bit array to indicate the tags of a
+ * set the override_redirect flag.  Clients are organized in a linked client
+ * list on each monitor, the focus history is remembered through a stack list
+ * on each monitor. Each client contains a bit array to indicate the tags of a
  * client.
  *
  * Keys and tagging rules are organized as arrays and defined in config.h.
@@ -164,6 +164,7 @@ static void destroynotify(XEvent *e);
 static void detach(Client *c);
 static void detachstack(Client *c);
 static void die(const char *errstr, ...);
+static Monitor *dirtomon(int dir);
 static void drawbar(Monitor *m);
 static void drawbars(void);
 static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
@@ -180,7 +181,6 @@ static long getstate(Window w);
 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 static void grabbuttons(Client *c, Bool focused);
 static void grabkeys(void);
-static Monitor *idxtomon(unsigned int n);
 static void initfont(const char *fontstr);
 static Bool isprotodel(Client *c);
 static void keypress(XEvent *e);
@@ -237,7 +237,7 @@ static void zoom(const Arg *arg);
 /* variables */
 static char stext[256];
 static int screen;
-static int sw, sh;   /* X display screen geometry x, y, width, height */
+static int sw, sh;           /* X display screen geometry x, y, width, height */
 static int bh, blw = 0;      /* bar geometry */
 static int (*xerrorxlib)(Display *, XErrorEvent *);
 static unsigned int numlockmask = 0;
@@ -264,6 +264,7 @@ static DC dc;
 static Layout *lt[] = { NULL, NULL };
 static Monitor *mons = NULL, *selmon = NULL;
 static Window root;
+
 /* configuration, allows nested code to access above variables */
 #include "config.h"
 
@@ -284,7 +285,8 @@ applyrules(Client *c) {
                        r = &rules[i];
                        if((!r->title || strstr(c->name, r->title))
                        && (!r->class || (ch.res_class && strstr(ch.res_class, r->class)))
-                       && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) {
+                       && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance))))
+                       {
                                c->isfloating = r->isfloating;
                                c->tags |= r->tags;
                        }
@@ -305,7 +307,6 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact) {
        /* set minimum possible */
        *w = MAX(1, *w);
        *h = MAX(1, *h);
-
        if(interact) {
                if(*x > sw)
                        *x = sw - WIDTH(c);
@@ -330,16 +331,13 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact) {
                *h = bh;
        if(*w < bh)
                *w = bh;
-
        if(resizehints || c->isfloating) {
                /* see last two sentences in ICCCM 4.1.2.3 */
                baseismin = c->basew == c->minw && c->baseh == c->minh;
-
                if(!baseismin) { /* temporarily remove base dimensions */
                        *w -= c->basew;
                        *h -= c->baseh;
                }
-
                /* adjust for aspect limits */
                if(c->mina > 0 && c->maxa > 0) {
                        if(c->maxa < (float)*w / *h)
@@ -347,28 +345,22 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact) {
                        else if(c->mina < (float)*h / *w)
                                *h = *w * c->mina;
                }
-
                if(baseismin) { /* increment calculation requires this */
                        *w -= c->basew;
                        *h -= c->baseh;
                }
-
                /* 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;
-
                *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);
        }
@@ -438,7 +430,6 @@ buttonpress(XEvent *e) {
                focus(c);
                click = ClkClientWin;
        }
-
        for(i = 0; i < LENGTH(buttons); i++)
                if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
                   && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
@@ -449,7 +440,6 @@ void
 checkotherwm(void) {
        otherwm = False;
        xerrorxlib = XSetErrorHandler(xerrorstart);
-
        /* this causes an error if some other window manager is running */
        XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
        XSync(dpy, False);
@@ -632,6 +622,23 @@ die(const char *errstr, ...) {
        exit(EXIT_FAILURE);
 }
 
+Monitor *
+dirtomon(int dir) {
+       Monitor *m = NULL;
+
+       if(dir > 0) {
+               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);
+       }
+       return m;
+}
+
 void
 drawbar(Monitor *m) {
        int x;
@@ -644,7 +651,6 @@ drawbar(Monitor *m) {
                if(c->isurgent)
                        urg |= c->tags;
        }
-
        dc.x = 0;
        if(mons->next) { /* more than a single monitor */
                dc.w = TEXTW(monsyms[m->screen_number]);
@@ -676,9 +682,8 @@ drawbar(Monitor *m) {
                }
                drawtext(stext, dc.norm, False);
        }
-       else {
+       else
                dc.x = m->ww;
-       }
        if((dc.w = dc.x - x) > bh) {
                dc.x = x;
                if(m->sel) {
@@ -810,10 +815,11 @@ focusin(XEvent *e) { /* there are some broken focus acquiring clients */
 
 void
 focusmon(const Arg *arg) {
-       Monitor *m;
+       Monitor *m = NULL;
 
-       if(!(m = idxtomon(arg->ui)) || m == selmon)
+       if(!mons->next)
                return;
+       m = dirtomon(arg->i);
        unfocus(selmon->sel);
        selmon = m;
        focus(NULL);
@@ -860,6 +866,7 @@ getrootpointer(int *x, int *y) {
        int di;
        unsigned int dui;
        Window dummy;
+
        return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
 }
 
@@ -897,7 +904,8 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size) {
                strncpy(text, (char *)name.value, size - 1);
        else {
                if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
-               && n > 0 && *list) {
+               && n > 0 && *list)
+               {
                        strncpy(text, *list, size - 1);
                        XFreeStringList(list);
                }
@@ -922,7 +930,8 @@ grabbuttons(Client *c, Bool focused) {
                                                            buttons[i].mask | modifiers[j],
                                                            c->win, False, BUTTONMASK,
                                                            GrabModeAsync, GrabModeSync, None, None);
-               } else
+               }
+               else
                        XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
                                    BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
        }
@@ -931,7 +940,7 @@ grabbuttons(Client *c, Bool focused) {
 void
 grabkeys(void) {
        updatenumlockmask();
-       { /* grab keys */
+       {
                unsigned int i, j;
                unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
                KeyCode code;
@@ -946,15 +955,6 @@ grabkeys(void) {
        }
 }
 
-Monitor *
-idxtomon(unsigned int n) {
-       unsigned int i;
-       Monitor *m;
-
-       for(m = mons, i = 0; m && i != n; m = m->next, i++);
-       return m;
-}
-
 void
 initfont(const char *fontstr) {
        char *def, **missing;
@@ -1050,7 +1050,6 @@ manage(Window w, XWindowAttributes *wa) {
                die("fatal: could not malloc() %u bytes\n", sizeof(Client));
        *c = cz;
        c->win = w;
-
        if(XGetTransientForHint(dpy, w, &trans))
                t = wintoclient(trans);
        if(t) {
@@ -1061,7 +1060,6 @@ manage(Window w, XWindowAttributes *wa) {
                c->mon = selmon;
                applyrules(c);
        }
-
        /* geometry */
        c->x = wa->x + c->mon->wx;
        c->y = wa->y + c->mon->wy;
@@ -1084,7 +1082,6 @@ manage(Window w, XWindowAttributes *wa) {
                           && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
                c->bw = borderpx;
        }
-
        wc.border_width = c->bw;
        XConfigureWindow(dpy, w, CWBorderWidth, &wc);
        XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
@@ -1290,7 +1287,6 @@ resizemouse(const Arg *arg) {
                case MotionNotify:
                        nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
                        nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
-
                        if(snap && nw >= selmon->wx && nw <= selmon->wx + selmon->ww
                                && nh >= selmon->wy && nh <= selmon->wy + selmon->wh) {
                                if(!c->isfloating && lt[selmon->sellt]->arrange
@@ -1392,7 +1388,7 @@ sendmon(Client *c, Monitor *m) {
 
 void
 setclientstate(Client *c, long state) {
-       long data[] = {state, None};
+       long data[] = { state, None };
 
        XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
                        PropModeReplace, (unsigned char *)data, 2);
@@ -1440,19 +1436,16 @@ setup(void) {
        lt[0] = &layouts[0];
        lt[1] = &layouts[1 % LENGTH(layouts)];
        updategeom();
-
        /* init atoms */
        wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
        wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
        wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
        netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
        netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
-
        /* init cursors */
        cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
        cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
        cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
-
        /* init appearance */
        dc.norm[ColBorder] = getcolor(normbordercolor);
        dc.norm[ColBG] = getcolor(normbgcolor);
@@ -1465,7 +1458,6 @@ setup(void) {
        XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
        if(!dc.font.set)
                XSetFont(dpy, dc.gc, dc.font.xfont->fid);
-
        /* init bars */
        for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
                w = TEXTW(layouts[i].symbol);
@@ -1473,11 +1465,9 @@ setup(void) {
        }
        updatebars();
        updatestatus();
-
        /* EWMH support per view */
        XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
                        PropModeReplace, (unsigned char *) netatom, NetLast);
-
        /* select for events */
        wa.cursor = cursor[CurNormal];
        wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask
@@ -1485,7 +1475,6 @@ setup(void) {
                        |PropertyChangeMask;
        XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
        XSelectInput(dpy, root, wa.event_mask);
-
        grabkeys();
 }
 
@@ -1535,11 +1524,9 @@ tag(const Arg *arg) {
 
 void
 tagmon(const Arg *arg) {
-       Monitor *m;
-
-       if(!selmon->sel || !(m = idxtomon(arg->ui)))
+       if(!selmon->sel || !mons->next)
                return;
-       sendmon(selmon->sel, m);
+       sendmon(selmon->sel, dirtomon(arg->i));
 }
 
 int
@@ -1562,15 +1549,12 @@ tile(Monitor *m) {
        for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
        if(n == 0)
                return;
-
        /* master */
        c = nexttiled(m->clients);
        mw = m->mfact * m->ww;
        resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw, False);
-
        if(--n == 0)
                return;
-
        /* tile stack */
        x = (m->wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : m->wx + mw;
        y = m->wy;
@@ -1578,7 +1562,6 @@ tile(Monitor *m) {
        h = m->wh / n;
        if(h < bh)
                h = m->wh;
-
        for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
                resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n)
                       ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False);
@@ -1612,7 +1595,6 @@ toggletag(const Arg *arg) {
 
        if(!selmon->sel)
                return;
-       
        mask = selmon->sel->tags ^ (arg->ui & TAGMASK);
        if(mask) {
                selmon->sel->tags = mask;
@@ -1677,10 +1659,8 @@ updatebars(void) {
        wa.override_redirect = True;
        wa.background_pixmap = ParentRelative;
        wa.event_mask = ButtonPressMask|ExposureMask;
-
        for(m = mons; m; m = m->next) {
                m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
-
                                          CopyFromParent, DefaultVisual(dpy, screen),
                                          CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
                XDefineCursor(dpy, m->barwin, cursor[CurNormal]);
@@ -1719,7 +1699,6 @@ updategeom(void) {
                m->next = newmons;
                newmons = m;
        }
-
        /* initialise monitor(s) */
 #ifdef XINERAMA
        if(XineramaIsActive(dpy)) {
@@ -1742,7 +1721,6 @@ updategeom(void) {
                m->mw = m->ww = sw;
                m->mh = m->wh = sh;
        }
-
        /* bar geometry setup */
        for(m = newmons; m; m = m->next) {
                m->sel = m->stack = m->clients = NULL;
@@ -1754,7 +1732,6 @@ updategeom(void) {
                m->topbar = TOPBAR;
                updatebarpos(m);
        }
-
        /* reassign left over clients of disappeared monitors */
        for(tm = mons; tm; tm = tm->next)
                while(tm->clients) {
@@ -1765,7 +1742,6 @@ updategeom(void) {
                        attach(c);
                        attachstack(c);
                }
-
        /* select focused monitor */
        cleanupmons();
        selmon = mons = newmons;
@@ -1861,7 +1837,6 @@ updatewmhints(Client *c) {
                }
                else
                        c->isurgent = (wmh->flags & XUrgencyHint) ? True : False;
-
                XFree(wmh);
        }
 }
@@ -1941,7 +1916,9 @@ void
 zoom(const Arg *arg) {
        Client *c = selmon->sel;
 
-       if(!lt[selmon->sellt]->arrange || lt[selmon->sellt]->arrange == monocle || (selmon->sel && selmon->sel->isfloating))
+       if(!lt[selmon->sellt]->arrange
+       || lt[selmon->sellt]->arrange == monocle
+       || (selmon->sel && selmon->sel->isfloating))
                return;
        if(c == nexttiled(selmon->clients))
                if(!c || !(c = nexttiled(c->next)))
@@ -1958,19 +1935,15 @@ main(int argc, char *argv[]) {
                die("dwm-"VERSION", © 2006-2009 dwm engineers, see LICENSE for details\n");
        else if(argc != 1)
                die("usage: dwm [-v]\n");
-
        if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
                fputs("warning: no locale support\n", stderr);
-
        if(!(dpy = XOpenDisplay(NULL)))
                die("dwm: cannot open display\n");
-
        checkotherwm();
        setup();
        scan();
        run();
        cleanup();
-
        XCloseDisplay(dpy);
        return 0;
 }