Hi there,
First of all, I got to say thank you to Anselm and the contributors to
dwm, which truly is a wonder.
I just switched to release 5.6, and ported a couple of patches that I
happen to use : bstack and pertag.
I don't have a dual head setup to test everything, but in a few hours
of usage I haven't noticed any problem with these so far, so I guess I
can share them.
Many thanks to the original authors of these patches.
PS: my C kungfu is a bit rusty and there is a compiler warning I haven't
taken time to fix with the pertag patch. Boo-boo me at will.
--
Francois Gombault
--- a/config.def.h 2009-07-15 16:03:15.000000000 +0200
+++ b/config.def.h 2009-07-15 15:57:17.000000000 +0200
@@ -31,6 +30,7 @@
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "TTT", bstack },
};
/* key definitions */
--- a/dwm.c 2009-07-14 20:07:55.000000000 +0200
+++ b/dwm.c 2009-07-15 16:11:51.000000000 +0200
@@ -213,6 +213,7 @@
static void tagmon(const Arg *arg);
static int textnw(const char *text, unsigned int len);
static void tile(Monitor *);
+static void bstack(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -1571,6 +1572,38 @@
}
void
+bstack(Monitor *m) {
+ int x, y, h, w, mh;
+ unsigned int i, n;
+ Client *c;
+
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ c = nexttiled(m->clients);
+ mh = m->mfact * m->wh;
+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False);
+
+ if(--n == 0)
+ return;
+
+ x = m->wx;
+ y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh;
+ w = m->ww / n;
+ h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh;
+ if(h < bh)
+ h = m->wh;
+
+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
+ resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw,
+ h - 2 * c->bw, False);
+ if(w != m->ww)
+ x = c->x + WIDTH(c);
+ }
+}
+
+void
togglebar(const Arg *arg) {
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
--- a/dwm.c 2009-07-14 20:07:55.000000000 +0200
+++ b/dwm.c 2009-07-15 15:32:33.000000000 +0200
@@ -120,25 +120,6 @@
void (*arrange)(Monitor *);
} Layout;
-struct Monitor {
- float mfact;
- int num;
- int by; /* bar geometry */
- int mx, my, mw, mh; /* screen size */
- int wx, wy, ww, wh; /* window area */
- unsigned int seltags;
- unsigned int sellt;
- unsigned int tagset[2];
- Bool showbar;
- Bool topbar;
- Client *clients;
- Client *sel;
- Client *stack;
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
-};
-
typedef struct {
const char *class;
const char *instance;
@@ -270,6 +251,30 @@
/* configuration, allows nested code to access above variables */
#include "config.h"
+struct Monitor {
+ float mfact;
+ int num;
+ int by; /* bar geometry */
+ int mx, my, mw, mh; /* screen size */
+ int wx, wy, ww, wh; /* window area */
+ unsigned int seltags;
+ unsigned int sellt;
+ unsigned int tagset[2];
+ Bool showbar;
+ Bool topbar;
+ Client *clients;
+ Client *sel;
+ Client *stack;
+ Monitor *next;
+ Window barwin;
+ const Layout *lt[2];
+ int curtag;
+ int prevtag;
+ Layout *lts[LENGTH(tags) + 1];
+ double mfacts[LENGTH(tags) + 1];
+ Bool showbars[LENGTH(tags) + 1];
+};
+
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
@@ -1401,7 +1406,7 @@
if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
selmon->sellt ^= 1;
if(arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v;
if(selmon->sel)
arrange();
else
@@ -1418,7 +1423,7 @@
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
if(f < 0.1 || f > 0.9)
return;
- selmon->mfact = f;
+ selmon->mfact = selmon->mfacts[selmon->curtag] = f;
arrange();
}
@@ -1427,6 +1432,7 @@
unsigned int i;
int w;
XSetWindowAttributes wa;
+ Monitor *m;
/* init screen */
screen = DefaultScreen(dpy);
@@ -1458,11 +1464,31 @@
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
if(!dc.font.set)
XSetFont(dpy, dc.gc, dc.font.xfont->fid);
+ /* init tags */
+ for(m = mons; m; m = m->next)
+ m->curtag = m->prevtag = 1;
+ /* init mfacts */
+ for(m = mons; m; m = m->next) {
+ for(i=0; i < LENGTH(tags) + 1 ; i++) {
+ m->mfacts[i] = m->mfact;
+ }
+ }
+ /* init layouts */
+ for(m = mons; m; m = m->next) {
+ for(i=0; i < LENGTH(tags) + 1; i++) {
+ m->lts[i] = &layouts[0];
+ }
+ }
/* init bars */
for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
w = TEXTW(layouts[i].symbol);
blw = MAX(blw, w);
}
+ for(m = mons; m; m = m->next) {
+ for(i=0; i < LENGTH(tags) + 1; i++) {
+ m->showbars[i] = m->showbar;
+ }
+ }
updatebars();
updatestatus();
/* EWMH support per view */
@@ -1572,7 +1598,7 @@
void
togglebar(const Arg *arg) {
- selmon->showbar = !selmon->showbar;
+ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange();
@@ -1592,12 +1618,26 @@
void
toggletag(const Arg *arg) {
unsigned int mask;
+ unsigned int i;
if(!selmon->sel)
return;
mask = selmon->sel->tags ^ (arg->ui & TAGMASK);
if(mask) {
- selmon->sel->tags = mask;
+ if(mask == ~0) {
+ selmon->prevtag = selmon->curtag;
+ selmon->curtag = 0;
+ }
+ if(!(mask & 1 << (selmon->curtag - 1))) {
+ selmon->prevtag = selmon->curtag;
+ for (i=0; !(mask & 1 << i); i++);
+ selmon->curtag = i + 1;
+ }
+ selmon->sel->tags = mask;
+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
+ selmon->mfact = selmon->mfacts[selmon->curtag];
+ if (selmon->showbar != selmon->showbars[selmon->curtag])
+ togglebar(NULL);
arrange();
}
}
@@ -1848,11 +1888,28 @@
void
view(const Arg *arg) {
+ unsigned int i;
if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
selmon->seltags ^= 1; /* toggle sel tagset */
- if(arg->ui & TAGMASK)
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+ if(arg->ui & TAGMASK) {
+ selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+ selmon->prevtag = selmon->curtag;
+ if(arg->ui == ~0)
+ selmon->curtag = 0;
+ else {
+ for (i=0; !(arg->ui & 1 << i); i++);
+ selmon->curtag = i + 1;
+ }
+ } else {
+ selmon->prevtag= selmon->curtag ^ selmon->prevtag;
+ selmon->curtag^= selmon->prevtag;
+ selmon->prevtag= selmon->curtag ^ selmon->prevtag;
+ }
+ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag];
+ selmon->mfact = selmon->mfacts[selmon->curtag];
+ if(selmon->showbar != selmon->showbars[selmon->curtag])
+ togglebar(NULL);
arrange();
}