Have updated the patch for mercurial tip.
I also add a patch which implements one layout per tag. Haven't looked
at the old one, so I can't say if it's an update or not.

On Thu, Mar 27, 2008 at 05:31:22PM +0100, Martin Oppegaard wrote:
> Hi,
> 
> I've made a function for cycling through the windows with the urgent flag
> set. The idea is that when first called, you start a cycle which on
> completion will give focus back to the window which had it initially. This
> window's prevtags are saved. Each call to focus() breaks the cycle, so
> you don't have to complete it to continue using dwm as normal.
> 
> To be fair, I've only tested the patch with one urgent window. If you
> have any ideas as to how to trigger the urgent flag manually,
> please let me know.
> 
> Best regards,
> 
> Martin Oppegaard

> --- dwm-4.8/dwm.c     2008-03-13 17:55:43.000000000 +0100
> +++ mydwm-4.8/dwm.c   2008-03-27 16:34:22.000000000 +0100
> @@ -186,6 +186,7 @@ void updatetitle(Client *c);
>  void updatewmhints(Client *c);
>  void view(const char *arg);
>  void viewprevtag(const char *arg);   /* views previous selected tags */
> +void cycleurgent(const char *arg);
>  int xerror(Display *dpy, XErrorEvent *ee);
>  int xerrordummy(Display *dpy, XErrorEvent *ee);
>  int xerrorstart(Display *dpy, XErrorEvent *ee);
> @@ -219,6 +220,9 @@ Bool *seltags;
>  Client *clients = NULL;
>  Client *sel = NULL;
>  Client *stack = NULL;
> +Client *initucycl; /* initialized urgent cycle */
> +Bool *iucprevtags; /* the urgent-cycle initiator's previous tags */
> +Bool inucycl = False; /* in urgent cycle */
>  Cursor cursor[CurLast];
>  Display *dpy;
>  DC dc = {0};
> @@ -661,6 +665,7 @@ focus(Client *c) {
>               grabbuttons(c, True);
>       }
>       sel = c;
> +    inucycl = False;
>       if(c) {
>               XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
>               XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
> @@ -1497,6 +1502,7 @@ setup(void) {
>       /* init tags */
>       seltags = emallocz(TAGSZ);
>       prevtags = emallocz(TAGSZ);
> +    iucprevtags = emallocz(TAGSZ);
>       seltags[0] = prevtags[0] = True;
>  
>       /* init layouts */
> @@ -1842,6 +1848,36 @@ viewprevtag(const char *arg) {
>       arrange();
>  }
>  
> +void
> +cycleurgent(const char *arg) {
> +    Client *c;
> +
> +    if(!sel)
> +        return;
> +
> +    if(!inucycl) {
> +        initucycl = sel;
> +        memcpy(iucprevtags, prevtags, TAGSZ);
> +    }
> +        
> +     for(c = clients; c; c = c->next) {
> +        if(c->isurgent) {
> +            memcpy(prevtags, seltags, TAGSZ);
> +            memcpy(seltags, c->tags, TAGSZ);
> +            focus(c);
> +            arrange();
> +            inucycl = True;
> +
> +            return;
> +        }
> +    }
> +
> +    memcpy(prevtags, iucprevtags, TAGSZ);
> +    memcpy(seltags, initucycl->tags, TAGSZ);
> +    focus(initucycl);
> +    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.  */

diff -r f330c3a2dc76 config.def.h
--- a/config.def.h      Tue Mar 25 09:41:14 2008
+++ b/config.def.h      Sat Mar 29 10:27:32 2008
@@ -54,6 +54,7 @@
        { MODKEY,                       XK_r,           reapply,        NULL },
        { MODKEY,                       XK_h,           setmfact,       "-0.05" 
},
        { MODKEY,                       XK_l,           setmfact,       "+0.05" 
},
+    { MODKEY,           XK_u,       cycleurgent,    NULL },
        { MODKEY,                       XK_Return,      zoom,           NULL },
        { MODKEY,                       XK_Tab,         viewprevtag,    NULL },
        { MODKEY|ShiftMask,             XK_c,           killclient,     NULL },
diff -r f330c3a2dc76 dwm.c
--- a/dwm.c     Tue Mar 25 09:41:14 2008
+++ b/dwm.c     Sat Mar 29 10:27:32 2008
@@ -202,6 +202,7 @@
 void updatewmhints(Client *c);
 void view(const char *arg);
 void viewprevtag(const char *arg);     /* views previous selected tags */
+void cycleurgent(const char *arg);
 int xerror(Display *dpy, XErrorEvent *ee);
 int xerrordummy(Display *dpy, XErrorEvent *ee);
 int xerrorstart(Display *dpy, XErrorEvent *ee);
@@ -235,6 +236,9 @@
 Client *clients = NULL;
 Client *sel = NULL;
 Client *stack = NULL;
+Client *initucycle = NULL; /* initiated urgent-cycle */
+Bool *iucprevtags; /* the urgent-cycle initiator's previous tags */
+Bool inucycle = False; /* in urgent-cycle */
 Cursor cursor[CurLast];
 Display *dpy;
 DC dc = {0};
@@ -692,6 +696,7 @@
                grabbuttons(c, True);
        }
        sel = c;
+    inucycle = False;
        if(c) {
                XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
                XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
@@ -1533,6 +1538,7 @@
        /* init tags */
        seltags = emallocz(TAGSZ);
        prevtags = emallocz(TAGSZ);
+    iucprevtags = emallocz(TAGSZ);
        seltags[0] = prevtags[0] = True;
 
        /* init layouts */
@@ -1883,6 +1889,32 @@
        arrange();
 }
 
+void cycleurgent(const char *arg) {
+    Client *c;
+
+    if(!sel)
+        return;
+    if(!inucycle) {
+        initucycle = sel;
+        memcpy(iucprevtags, prevtags, TAGSZ);
+    }
+
+    for(c = clients; c && !c->isurgent; c = c->next);
+    if(c) {
+        memcpy(prevtags, seltags, TAGSZ);
+        memcpy(seltags, c->tags, TAGSZ);
+        focus(c);
+        arrange();
+        inucycle = True;
+        return;
+    }
+
+    memcpy(prevtags, iucprevtags, TAGSZ);
+    memcpy(seltags, initucycle->tags, TAGSZ);
+    focus(initucycle);
+    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.  */
diff -r f330c3a2dc76 dwm.c
--- a/dwm.c     Tue Mar 25 09:41:14 2008
+++ b/dwm.c     Sat Mar 29 10:13:15 2008
@@ -239,7 +239,10 @@
 Display *dpy;
 DC dc = {0};
 Geom *geom = NULL;
-Layout *lt = NULL;
+Layout **lt;
+int prevlt = 0;
+int sellt = 0;
+int tmplt = 0;
 Window root, barwin;
 
 /* configuration, allows nested code to access above variables */
@@ -290,7 +293,7 @@
                        ban(c);
 
        focus(NULL);
-       lt->arrange();
+       lt[sellt]->arrange();
        restack();
 }
 
@@ -358,7 +361,7 @@
                        movemouse(c);
                }
                else if(ev->button == Button2) {
-                       if((floating != lt->arrange) && c->isfloating)
+                       if((floating != lt[sellt]->arrange) && c->isfloating)
                                togglefloating(NULL);
                        else
                                zoom(NULL);
@@ -446,7 +449,7 @@
        if((c = getclient(ev->window))) {
                if(ev->value_mask & CWBorderWidth)
                        c->bw = ev->border_width;
-               if(c->isfixed || c->isfloating || lt->isfloating) {
+               if(c->isfixed || c->isfloating || lt[sellt]->isfloating) {
                        if(ev->value_mask & CWX)
                                c->x = sx + ev->x;
                        if(ev->value_mask & CWY)
@@ -544,7 +547,7 @@
        }
        if(blw > 0) {
                dc.w = blw;
-               drawtext(lt->symbol, dc.norm, False);
+               drawtext(lt[sellt]->symbol, dc.norm, False);
                x = dc.x + dc.w;
        }
        else
@@ -1126,9 +1129,9 @@
                                ny = wy;
                        else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
                                ny = wy + wh - c->h - 2 * c->bw;
-                       if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) 
> SNAP || abs(ny - c->y) > SNAP))
+                       if(!c->isfloating && !lt[sellt]->isfloating && (abs(nx 
- c->x) > SNAP || abs(ny - c->y) > SNAP))
                                togglefloating(NULL);
-                       if((lt->isfloating) || c->isfloating)
+                       if((lt[sellt]->isfloating) || c->isfloating)
                                resize(c, nx, ny, c->w, c->h, False);
                        break;
                }
@@ -1287,9 +1290,9 @@
                                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))
+                       if(!c->isfloating && !lt[sellt]->isfloating && (abs(nw 
- c->w) > SNAP || abs(nh - c->h) > SNAP))
                                togglefloating(NULL);
-                       if((lt->isfloating) || c->isfloating)
+                       if((lt[sellt]->isfloating) || c->isfloating)
                                resize(c, c->x, c->y, nw, nh, True);
                        break;
                }
@@ -1305,9 +1308,9 @@
        drawbar();
        if(!sel)
                return;
-       if(sel->isfloating || lt->isfloating)
+       if(sel->isfloating || lt[sellt]->isfloating)
                XRaiseWindow(dpy, sel->win);
-       if(!lt->isfloating) {
+       if(!lt[sellt]->isfloating) {
                wc.stack_mode = Below;
                wc.sibling = barwin;
                if(!sel->isfloating) {
@@ -1446,8 +1449,8 @@
        unsigned int i;
 
        if(!arg) {
-               if(++lt == &layouts[LENGTH(layouts)])
-                       lt = &layouts[0];
+               if(++lt[sellt] == &layouts[LENGTH(layouts)])
+                       lt[sellt] = &layouts[0];
        }
        else {
                for(i = 0; i < LENGTH(layouts); i++)
@@ -1455,7 +1458,7 @@
                                break;
                if(i == LENGTH(layouts))
                        return;
-               lt = &layouts[i];
+               lt[sellt] = &layouts[i];
        }
        if(sel)
                arrange();
@@ -1467,7 +1470,7 @@
 setmfact(const char *arg) {
        double delta;
 
-       if(!arg || lt->isfloating)
+       if(!arg || lt[sellt]->isfloating)
                return;
        delta = strtod(arg, NULL);
        if(arg[0] == '-' || arg[0] == '+') {
@@ -1536,7 +1539,9 @@
        seltags[0] = prevtags[0] = True;
 
        /* init layouts */
-       lt = &layouts[0];
+    lt = malloc(LENGTH(tags)*sizeof(Layout));
+    for(i = 0; i < LENGTH(tags); i++)
+           lt[i] = &layouts[0];
 
        /* init bar */
        for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
@@ -1861,11 +1866,20 @@
 
 void
 view(const char *arg) {
-       unsigned int i;
+       unsigned int i, id;
+    id = idxoftag(arg);
 
        for(i = 0; i < LENGTH(tags); i++)
                tmp[i] = (NULL == arg);
-       tmp[idxoftag(arg)] = True;
+       tmp[id] = True;
+
+    if(NULL != arg)
+        tmplt = id;
+
+    if(tmplt != sellt) {
+        prevlt = sellt;
+        sellt = tmplt;
+    }
 
        if(memcmp(seltags, tmp, TAGSZ) != 0) {
                memcpy(prevtags, seltags, TAGSZ);
@@ -1880,6 +1894,10 @@
        memcpy(tmp, seltags, TAGSZ);
        memcpy(seltags, prevtags, TAGSZ);
        memcpy(prevtags, tmp, TAGSZ);
+
+    tmplt = sellt;
+    sellt = prevlt;
+    prevlt = tmplt;
        arrange();
 }
 
@@ -1919,7 +1937,7 @@
 zoom(const char *arg) {
        Client *c = sel;
 
-       if(!sel || lt->isfloating || sel->isfloating)
+       if(!sel || lt[sellt]->isfloating || sel->isfloating)
                return;
        if(c == nexttiled(clients))
                if(!(c = nexttiled(c->next)))

Reply via email to