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)))