JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
some more changes towards a better dwm
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index 01d40f1..87bc1d2 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -67,10 +67,11 @@ struct Client {
        int x, y, w, h;
        int basew, baseh, incw, inch, maxw, maxh, minw, minh;
        int minax, maxax, minay, maxay;
-       int *tags;
        long flags;
        unsigned int border, oldborder;
        Bool isbanned, isfixed, isfloating, isurgent;
+       Bool *tags;
+       View *view;
        Client *next;
        Client *prev;
        Client *snext;
@@ -106,17 +107,12 @@ typedef struct {
 
 typedef struct {
        const char *prop;
-       const char *tags;
+       const char *tag;
        Bool isfloating;
 } Rule;
 
-typedef struct {
-       regex_t *propregex;
-       regex_t *tagregex;
-} Regs;
-
 struct View {
-       int id;
+       unsigned int id;
        int x, y, w, h, wax, way, wah, waw;
        double mwfact;
        Layout *layout;
@@ -124,6 +120,7 @@ struct View {
 };
 
 /* function declarations */
+void addtag(Client *c, const char *t);
 void applyrules(Client *c);
 void arrange(void);
 void attach(Client *c);
@@ -132,7 +129,6 @@ void ban(Client *c);
 void buttonpress(XEvent *e);
 void checkotherwm(void);
 void cleanup(void);
-void compileregs(void);
 void configure(Client *c);
 void configurenotify(XEvent *e);
 void configurerequest(XEvent *e);
@@ -140,8 +136,8 @@ void destroynotify(XEvent *e);
 void detach(Client *c);
 void detachstack(Client *c);
 void drawbar(View *v);
-void drawsquare(View *v, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
-void drawtext(View *v, const char *text, unsigned long col[ColLast], Bool invert);
+void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
+void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
 void *emallocz(unsigned int size);
 void enternotify(XEvent *e);
 void eprint(const char *errstr, ...);
@@ -154,12 +150,11 @@ void focusprev(const char *arg);
 Client *getclient(Window w);
 unsigned long getcolor(const char *colstr);
 View *getviewbar(Window barwin);
-View *getview(Client *c);
 long getstate(Window w);
 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 void grabbuttons(Client *c, Bool focused);
 void grabkeys(void);
-unsigned int idxoftag(const char *tag);
+unsigned int idxoftag(const char *t);
 void initfont(const char *fontstr);
 Bool isoccupied(unsigned int t);
 Bool isprotodel(Client *c);
@@ -210,12 +205,9 @@ void zoom(const char *arg);
 void selectview(const char *arg);
 
 /* variables */
-char stext[256];
+char stext[256], buf[256];
 int nviews = 1;
-View *selview;
 int screen;
-int *seltags;
-int *prevtags;
 int (*xerrorxlib)(Display *, XErrorEvent *);
 unsigned int bh, bpos;
 unsigned int blw = 0;
@@ -240,14 +232,16 @@ Bool domwfact = True;
 Bool dozoom = True;
 Bool otherwm, readin;
 Bool running = True;
+Bool *prevtags;
+Bool *seltags;
 Client *clients = NULL;
 Client *sel = NULL;
 Client *stack = NULL;
 Cursor cursor[CurLast];
 Display *dpy;
 DC dc = {0};
-Regs *regs = NULL;
 View *views;
+View *selview;
 Window root;
 
 /* configuration, allows nested code to access above variables */
@@ -255,34 +249,46 @@ Window root;
 
 /* function implementations */
 void
+addtag(Client *c, const char *t) {
+       unsigned int i, tidx = idxoftag(t);
+
+       for(i = 0; i < LENGTH(tags); i++)
+               if(c->tags[i] && vtags[i] != vtags[tidx])
+                       return; /* conflict */
+       c->tags[tidx] = True;
+       c->view = &views[vtags[tidx]];
+}
+
+void
 applyrules(Client *c) {
-       static char buf[512];
-       unsigned int i, j;
-       regmatch_t tmp;
-       Bool matched_tag = False;
+       unsigned int i;
+       Bool matched = False;
+       Rule *r;
        XClassHint ch = { 0 };
 
        /* rule matching */
        XGetClassHint(dpy, c->win, &ch);
-       snprintf(buf, sizeof buf, "%s:%s:%s",
-                       ch.res_class ? ch.res_class : "",
-                       ch.res_name ? ch.res_name : "", c->name);
-       for(i = 0; i < LENGTH(rules); 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 < LENGTH(tags); j++) {
-                               if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
-                                       matched_tag = True;
-                                       c->tags[j] = selview->id;
-                               }
+       for(i = 0; i < LENGTH(rules); i++) {
+               r = &rules[i];
+               if(strstr(c->name, r->prop)
+               || (ch.res_class && strstr(ch.res_class, r->prop))
+               || (ch.res_name && strstr(ch.res_name, r->prop)))
+               {
+                       c->isfloating = r->isfloating;
+                       if(r->tag) {
+                               addtag(c, r->tag);
+                               matched = True;
                        }
                }
+       }
        if(ch.res_class)
                XFree(ch.res_class);
        if(ch.res_name)
                XFree(ch.res_name);
-       if(!matched_tag)
+       if(!matched) {
                memcpy(c->tags, seltags, sizeof initags);
+               c->view = selview;
+       }
 }
 
 
@@ -323,7 +329,7 @@ void
 ban(Client *c) {
        if(c->isbanned)
                return;
-       XMoveWindow(dpy, c->win, c->x + 3 * getview(c)->w, c->y);
+       XMoveWindow(dpy, c->win, c->x + 3 * c->view->w, c->y);
        c->isbanned = True;
 }
 
@@ -333,9 +339,7 @@ buttonpress(XEvent *e) {
        Client *c;
        XButtonPressedEvent *ev = &e->xbutton;
 
-       View *v = selview;
-
-       if(ev->window == v->barwin) {
+       if(ev->window == selview->barwin) {
                x = 0;
                for(i = 0; i < LENGTH(tags); i++) {
                        x += textw(tags[i]);
@@ -363,17 +367,17 @@ buttonpress(XEvent *e) {
                if(CLEANMASK(ev->state) != MODKEY)
                        return;
                if(ev->button == Button1) {
-                       restack(getview(c));
+                       restack(c->view);
                        movemouse(c);
                }
                else if(ev->button == Button2) {
-                       if((floating != v->layout->arrange) && c->isfloating)
+                       if((floating != c->view->layout->arrange) && c->isfloating)
                                togglefloating(NULL);
                        else
                                zoom(NULL);
                }
                else if(ev->button == Button3 && !c->isfixed) {
-                       restack(getview(c));
+                       restack(c->view);
                        resizemouse(c);
                }
        }
@@ -421,32 +425,6 @@ cleanup(void) {
 }
 
 void
-compileregs(void) {
-       unsigned int i;
-       regex_t *reg;
-
-       if(regs)
-               return;
-       regs = emallocz(LENGTH(rules) * sizeof(Regs));
-       for(i = 0; i < LENGTH(rules); i++) {
-               if(rules[i].prop) {
-                       reg = emallocz(sizeof(regex_t));
-                       if(regcomp(reg, rules[i].prop, REG_EXTENDED))
-                               free(reg);
-                       else
-                               regs[i].propregex = reg;
-               }
-               if(rules[i].tags) {
-                       reg = emallocz(sizeof(regex_t));
-                       if(regcomp(reg, rules[i].tags, REG_EXTENDED))
-                               free(reg);
-                       else
-                               regs[i].tagregex = reg;
-               }
-       }
-}
-
-void
 configure(Client *c) {
        XConfigureEvent ce;
 
@@ -476,7 +454,7 @@ configurenotify(XEvent *e) {
                XFreePixmap(dpy, dc.drawable);
                dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(root, screen), bh, DefaultDepth(dpy, screen));
                XResizeWindow(dpy, v->barwin, v->w, bh);
-               updatebarpos(v);
+               updatebarpos(selview);
                arrange();
        }
 }
@@ -488,7 +466,7 @@ configurerequest(XEvent *e) {
        XWindowChanges wc;
 
        if((c = getclient(ev->window))) {
-               View *v = getview(c);
+               View *v = c->view;
                if(ev->value_mask & CWBorderWidth)
                        c->border = ev->border_width;
                if(c->isfixed || c->isfloating || (floating == v->layout->arrange)) {
@@ -560,21 +538,23 @@ drawbar(View *v) {
        Client *c;
 
        dc.x = 0;
-       for(c = stack; c && !isvisible(c); c = c->snext);
+       for(c = stack; c && (!isvisible(c) || c->view != v); c = c->snext);
        for(i = 0; i < LENGTH(tags); i++) {
+               if(&views[vtags[i]] != v)
+                       continue;
                dc.w = textw(tags[i]);
                if(seltags[i]) {
-                       drawtext(v, tags[i], dc.sel, isurgent(i));
-                       drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.sel);
+                       drawtext(tags[i], dc.sel, isurgent(i));
+                       drawsquare(c && c->tags[i], isoccupied(i), isurgent(i), dc.sel);
                }
                else {
-                       drawtext(v, tags[i], dc.norm, isurgent(i));
-                       drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.norm);
+                       drawtext(tags[i], dc.norm, isurgent(i));
+                       drawsquare(c && c->tags[i], isoccupied(i), isurgent(i), dc.norm);
                }
                dc.x += dc.w;
        }
        dc.w = blw;
-       drawtext(v, v->layout->symbol, dc.norm, False);
+       drawtext(v->layout->symbol, dc.norm, False);
        x = dc.x + dc.w;
        if(v == selview) {
                dc.w = textw(stext);
@@ -583,25 +563,25 @@ drawbar(View *v) {
                        dc.x = x;
                        dc.w = v->w - x;
                }
-               drawtext(v, stext, dc.norm, False);
+               drawtext(stext, dc.norm, False);
        }
        else
                dc.x = v->w;
        if((dc.w = dc.x - x) > bh) {
                dc.x = x;
                if(c) {
-                       drawtext(v, c->name, dc.sel, False);
-                       drawsquare(v, False, c->isfloating, False, dc.sel);
+                       drawtext(c->name, dc.sel, False);
+                       drawsquare(False, c->isfloating, False, dc.sel);
                }
                else
-                       drawtext(v, NULL, dc.norm, False);
+                       drawtext(NULL, dc.norm, False);
        }
        XCopyArea(dpy, dc.drawable, v->barwin, dc.gc, 0, 0, v->w, bh, 0, 0);
        XSync(dpy, False);
 }
 
 void
-drawsquare(View *v, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
+drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
        int x;
        XGCValues gcv;
        XRectangle r = { dc.x, dc.y, dc.w, dc.h };
@@ -622,9 +602,8 @@ drawsquare(View *v, Bool filled, Bool empty, Bool invert, unsigned long col[ColL
 }
 
 void
-drawtext(View *v, const char *text, unsigned long col[ColLast], Bool invert) {
+drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
        int x, y, w, h;
-       static char buf[256];
        unsigned int len, olen;
        XRectangle r = { dc.x, dc.y, dc.w, dc.h };
 
@@ -700,7 +679,7 @@ expose(XEvent *e) {
        View *v;
        XExposeEvent *ev = &e->xexpose;
 
-       if(ev->count == 0 && (v = getviewbar(ev->window)))
+       if(ev->count == 0 && ((v = getviewbar(ev->window))))
                drawbar(v);
 }
 
@@ -718,13 +697,13 @@ void
 focus(Client *c) {
        View *v = selview;
        if(c)
-               selview = getview(c);
+               selview = c->view;
        else
                selview = viewat();
        if(selview != v)
                drawbar(v);
        if(!c || (c && !isvisible(c)))
-               for(c = stack; c && !isvisible(c); c = c->snext);
+               for(c = stack; c && (!isvisible(c) || c->view != selview); c = c->snext);
        if(sel && sel != c) {
                grabbuttons(sel, False);
                XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
@@ -738,7 +717,7 @@ focus(Client *c) {
        if(c) {
                XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
                XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
-               selview = getview(c);
+               selview = c->view;
        }
        else
                XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -764,7 +743,7 @@ focusnext(const char *arg) {
                for(c = clients; c && !isvisible(c); c = c->next);
        if(c) {
                focus(c);
-               restack(getview(c));
+               restack(c->view);
        }
 }
 
@@ -781,7 +760,7 @@ focusprev(const char *arg) {
        }
        if(c) {
                focus(c);
-               restack(getview(c));
+               restack(c->view);
        }
 }
 
@@ -813,16 +792,6 @@ getviewbar(Window barwin) {
        return NULL;
 }
 
-View *
-getview(Client *c) {
-       unsigned int i;
-
-       for(i = 0; i < LENGTH(tags); i++)
-               if(c->tags[i])
-                       return &views[c->tags[i] - 1];
-       return &views[0]; /* fallback */
-}
-
 long
 getstate(Window w) {
        int format, status;
@@ -934,10 +903,10 @@ grabkeys(void)  {
 }
 
 unsigned int
-idxoftag(const char *tag) {
+idxoftag(const char *t) {
        unsigned int i;
 
-       for(i = 0; (i < LENGTH(tags)) && (tags[i] != tag); i++);
+       for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++);
        return (i < LENGTH(tags)) ? i : 0;
 }
 
@@ -1078,7 +1047,7 @@ manage(Window w, XWindowAttributes *wa) {
 
        applyrules(c);
 
-       v = getview(c);
+       v = c->view;
 
        c->x = wa->x + v->x;
        c->y = wa->y + v->y;
@@ -1147,22 +1116,6 @@ maprequest(XEvent *e) {
                manage(ev->window, &wa);
 }
 
-View *
-viewat() {
-       int i, x, y;
-       Window win;
-       unsigned int mask;
-
-       XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask);
-       for(i = 0; i < nviews; i++) {
-               if((x >= views[i].x && x < views[i].x + views[i].w)
-               && (y >= views[i].y && y < views[i].y + views[i].h)) {
-                       return &views[i];
-               }
-       }
-       return NULL;
-}
-
 void
 movemouse(Client *c) {
        int x1, y1, ocx, ocy, di, nx, ny;
@@ -1173,7 +1126,7 @@ movemouse(Client *c) {
 
        ocx = nx = c->x;
        ocy = ny = c->y;
-       v = getview(c);
+       v = c->view;
        if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
                        None, cursor[CurMove], CurrentTime) != GrabSuccess)
                return;
@@ -1212,7 +1165,7 @@ movemouse(Client *c) {
 
 Client *
 nexttiled(Client *c, View *v) {
-       for(; c && (c->isfloating || getview(c) != v || !isvisible(c)); c = c->next);
+       for(; c && (c->isfloating || c->view != v || !isvisible(c)); c = c->next);
        return c;
 }
 
@@ -1237,7 +1190,7 @@ propertynotify(XEvent *e) {
                        break;
                case XA_WM_HINTS:
                        updatewmhints(c);
-                       drawbar(getview(c));
+                       drawbar(c->view);
                        break;
                }
                if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
@@ -1270,7 +1223,7 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
        View *v;
        XWindowChanges wc;
 
-       v = getview(c);
+       v = c->view;
        if(sizehints) {
                /* set minimum possible */
                if (w < 1)
@@ -1341,7 +1294,7 @@ resizemouse(Client *c) {
 
        ocx = c->x;
        ocy = c->y;
-       v = getview(c);
+       v = c->view;
        if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
                        None, cursor[CurResize], CurrentTime) != GrabSuccess)
                return;
@@ -1407,7 +1360,7 @@ restack(View *v) {
 void
 run(void) {
        char *p;
-       char buf[sizeof stext];
+       char sbuf[sizeof stext];
        fd_set rd;
        int r, xfd;
        unsigned int len, offset;
@@ -1419,7 +1372,7 @@ run(void) {
        readin = True;
        offset = 0;
        len = sizeof stext - 1;
-       buf[len] = stext[len] = '\0'; /* 0-terminator is never touched */
+       sbuf[len] = stext[len] = '\0'; /* 0-terminator is never touched */
        while(running) {
                FD_ZERO(&rd);
                if(readin)
@@ -1431,7 +1384,7 @@ run(void) {
                        eprint("select failed\n");
                }
                if(FD_ISSET(STDIN_FILENO, &rd)) {
-                       switch((r = read(STDIN_FILENO, buf + offset, len - offset))) {
+                       switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) {
                        case -1:
                                strncpy(stext, strerror(errno), len);
                                readin = False;
@@ -1441,15 +1394,15 @@ run(void) {
                                readin = False;
                                break;
                        default:
-                               for(p = buf + offset; r > 0; p++, r--, offset++)
+                               for(p = sbuf + offset; r > 0; p++, r--, offset++)
                                        if(*p == '\n' || *p == '\0') {
                                                *p = '\0';
-                                               strncpy(stext, buf, len);
-                                               p += r - 1; /* p is buf + offset + r - 1 */
+                                               strncpy(stext, sbuf, len);
+                                               p += r - 1; /* p is sbuf + offset + r - 1 */
                                                for(r = 0; *(p - r) && *(p - r) != '\n'; r++);
                                                offset = r;
                                                if(r)
-                                                       memmove(buf, p - r + 1, r);
+                                                       memmove(sbuf, p - r + 1, r);
                                                break;
                                        }
                                break;
@@ -1520,13 +1473,12 @@ setlayout(const char *arg) {
        if(sel)
                arrange();
        else
-               drawbar(v);
+               drawbar(selview);
 }
 
 void
 setmwfact(const char *arg) {
        double delta;
-
        View *v = selview;
 
        if(!domwfact)
@@ -1573,7 +1525,7 @@ setup(void) {
 isxinerama = True;
 nviews = 2; /* aim Xinerama */
 #endif
-       selview = views = emallocz(nviews * sizeof(View));
+       views = emallocz(nviews * sizeof(View));
 
        screen = DefaultScreen(dpy);
        root = RootWindow(dpy, screen);
@@ -1607,7 +1559,6 @@ nviews = 2; /* aim Xinerama */
        for(i = 0; i < nviews; i++) {
                /* init geometry */
                v = &views[i];
-               v->id = i + 1;
 
                if(nviews != 1 && isxinerama) {
 
@@ -1664,13 +1615,10 @@ v->h = DisplayHeight(dpy, screen);
        if(info)
                XFree(info);
 
+       selview = viewat();
+
        /* grab keys */
        grabkeys();
-
-       /* init tags */
-       compileregs();
-
-       selview = &views[0];
 }
 
 void
@@ -1704,8 +1652,8 @@ tag(const char *arg) {
        if(!sel)
                return;
        for(i = 0; i < LENGTH(tags); i++)
-               sel->tags[i] = (NULL == arg) ? selview->id : 0;
-       sel->tags[idxoftag(arg)] = selview->id;
+               sel->tags[i] = (NULL == arg);
+       sel->tags[idxoftag(arg)] = True;
        arrange();
 }
 
@@ -1761,7 +1709,6 @@ tile(View *v) {
                        else
                                nh = th - 2 * c->border;
                }
-               fprintf(stderr, "tile %d %d %d %d\n", nx, ny, nw, nh);
                resize(c, nx, ny, nw, nh, RESIZEHINTS);
                if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw)))
                        /* client doesn't accept size constraints */
@@ -1802,7 +1749,7 @@ toggletag(const char *arg) {
        sel->tags[i] = !sel->tags[i];
        for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++);
        if(j == LENGTH(tags))
-               sel->tags[i] = selview->id; /* at least one tag must be enabled */
+               sel->tags[i] = True; /* at least one tag must be enabled */
        arrange();
 }
 
@@ -1814,7 +1761,7 @@ toggleview(const char *arg) {
        seltags[i] = !seltags[i];
        for(j = 0; j < LENGTH(tags) && !seltags[j]; j++);
        if(j == LENGTH(tags))
-               seltags[i] = selview->id; /* at least one tag must be viewed */
+               seltags[i] = True; /* at least one tag must be viewed */
        arrange();
 }
 
@@ -1952,6 +1899,47 @@ updatewmhints(Client *c) {
        }
 }
 
+void
+view(const char *arg) {
+       unsigned int i;
+       Bool tmp[LENGTH(tags)];
+
+       for(i = 0; i < LENGTH(tags); i++)
+               tmp[i] = (NULL == arg);
+       tmp[idxoftag(arg)] = True;
+
+       if(memcmp(seltags, tmp, sizeof initags) != 0) {
+               memcpy(prevtags, seltags, sizeof initags);
+               memcpy(seltags, tmp, sizeof initags);
+               arrange();
+       }
+}
+
+View *
+viewat() {
+       int i, x, y;
+       Window win;
+       unsigned int mask;
+
+       XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask);
+       for(i = 0; i < nviews; i++) {
+               if((x >= views[i].x && x < views[i].x + views[i].w)
+               && (y >= views[i].y && y < views[i].y + views[i].h))
+                       return &views[i];
+       }
+       return NULL;
+}
+
+void
+viewprevtag(const char *arg) {
+       static Bool tmp[LENGTH(tags)];
+
+       memcpy(tmp, seltags, sizeof initags);
+       memcpy(seltags, prevtags, sizeof initags);
+       memcpy(prevtags, tmp, sizeof initags);
+       arrange();
+}
+
 /* There's no way to check accesses to destroyed windows, thus those cases are
  * ignored (especially on UnmapNotify's).  Other types of errors call Xlibs
  * default error handler, which may call exit.  */
@@ -1985,38 +1973,13 @@ xerrorstart(Display *dpy, XErrorEvent *ee) {
 }
 
 void
-view(const char *arg) {
-       unsigned int i;
-       int tmp[LENGTH(tags)];
-
-       for(i = 0; i < LENGTH(tags); i++)
-               tmp[i] = (NULL == arg) ? selview->id : 0;
-       tmp[idxoftag(arg)] = selview->id;
-       if(memcmp(seltags, tmp, sizeof initags) != 0) {
-               memcpy(prevtags, seltags, sizeof initags);
-               memcpy(seltags, tmp, sizeof initags);
-               arrange();
-       }
-}
-
-void
-viewprevtag(const char *arg) {
-       static Bool tmp[LENGTH(tags)];
-
-       memcpy(tmp, seltags, sizeof initags);
-       memcpy(seltags, prevtags, sizeof initags);
-       memcpy(prevtags, tmp, sizeof initags);
-       arrange();
-}
-
-void
 zoom(const char *arg) {
        Client *c = sel;
 
        if(!sel || !dozoom || sel->isfloating)
                return;
-       if(c == nexttiled(clients, getview(c)))
-               if(!(c = nexttiled(c->next, getview(c))))
+       if(c == nexttiled(clients, c->view))
+               if(!(c = nexttiled(c->next, c->view)))
                        return;
        detach(c);
        attach(c);
@@ -2024,21 +1987,6 @@ zoom(const char *arg) {
        arrange();
 }
 
-void
-selectview(const char *arg) {
-       int i;
-       View *v;
-
-       if(!arg)
-               return;
-       if(arg)
-               i = atoi(arg);
-       v = &views[i % nviews];
-       XWarpPointer(dpy, None, root, 0, 0, 0, 0, v->wax+v->waw/2, v->way+v->wah/2);
-       focus(NULL);
-}
-
-
 int
 main(int argc, char *argv[]) {
        if(argc == 2 && !strcmp("-v", argv[1]))