sites

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit d40ed5e8196b653dd114acc8d59bc4d1a708eac2
parent 57af7b274127b09175d12daab1a12d6bfb73f3bb
Author: Jan Christoph Ebersbach <jceb@e-jc.de>
Date:   Sun, 18 Mar 2012 21:50:30 +0100

add single tagset patch
Diffstat:
Adwm.suckless.org/patches/dwm-6.0-single_tagset.diff | 496+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-6.0-single_tagset_all.diff | 606+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/single_tagset.md | 44++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 1146 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/dwm-6.0-single_tagset.diff b/dwm.suckless.org/patches/dwm-6.0-single_tagset.diff @@ -0,0 +1,496 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: no URL yet +This patch addresses the multi-monitor setup. Instead of having separate tags +for every monitor there is just one list of tags for all monitors. Instead of +moving windows from one monitor to the other, the desired tag from the +other monitor can just be selected and all windows will be drawn on the +current monitor. + +Several deep changes needed to be made: +1. Macro ISVISIBLE expects a second parameter, the monitor +2. Monitor->clients and Monitor->stack were moved to the global variable + Clientlist cl. All monitors refer to this one list. +3. A new method attachclients was added. When changing between tags this + function ensures that all clients are pointing to the right monitor. + +Please be aware that this patch probably breaks any other patch! + +diff -r 627ba72d3465 dwm.c +--- a/dwm.c Sun Mar 18 17:23:36 2012 +0100 ++++ b/dwm.c Sun Mar 18 20:44:53 2012 +0100 +@@ -45,7 +45,7 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLE(C, M) ((C->tags & M->tagset[M->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MAX(A, B) ((A) > (B) ? (A) : (B)) + #define MIN(A, B) ((A) < (B) ? (A) : (B)) +@@ -124,6 +124,7 @@ + void (*arrange)(Monitor *); + } Layout; + ++typedef struct Clientlist Clientlist; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -137,9 +138,8 @@ + unsigned int tagset[2]; + Bool showbar; + Bool topbar; +- Client *clients; ++ Clientlist *cl; + Client *sel; +- Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +@@ -154,12 +154,18 @@ + int monitor; + } Rule; + ++struct Clientlist { ++ Client *clients; ++ Client *stack; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachclients(Monitor *m); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -202,7 +208,7 @@ + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); +-static Client *nexttiled(Client *c); ++static Client *nexttiled(Client *c, Monitor *m); + static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); +@@ -283,6 +289,7 @@ + static DC dc; + static Monitor *mons = NULL, *selmon = NULL; + static Window root; ++static Clientlist *cl; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -394,9 +401,9 @@ + void + arrange(Monitor *m) { + if(m) +- showhide(m->stack); ++ showhide(m->cl->stack); + else for(m = mons; m; m = m->next) +- showhide(m->stack); ++ showhide(m->cl->stack); + if(m) { + arrangemon(m); + restack(m); +@@ -413,14 +420,47 @@ + + void + attach(Client *c) { +- c->next = c->mon->clients; +- c->mon->clients = c; ++ c->next = c->mon->cl->clients; ++ c->mon->cl->clients = c; ++} ++ ++void ++attachclients(Monitor *m) { ++ /* attach clients to the specified monitor */ ++ Monitor *tm; ++ Client *c; ++ unsigned int utags = 0; ++ Bool rmons = False; ++ if(!m) ++ return; ++ ++ /* collect information about the tags in use */ ++ for(tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ utags |= m->tagset[m->seltags]; ++ ++ for(c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) { ++ /* if client is also visible on other tags that are displayed on ++ * other monitors, remove these tags */ ++ if(c->tags & utags) { ++ c->tags = c->tags & m->tagset[m->seltags]; ++ rmons = True; ++ } ++ unfocus(c, True); ++ c->mon = m; ++ } ++ ++ if(rmons) ++ for(tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ arrange(tm); + } + + void + attachstack(Client *c) { +- c->snext = c->mon->stack; +- c->mon->stack = c; ++ c->snext = c->mon->cl->stack; ++ c->mon->cl->stack = c; + } + + void +@@ -483,8 +523,8 @@ + view(&a); + selmon->lt[selmon->sellt] = &foo; + for(m = mons; m; m = m->next) +- while(m->stack) +- unmanage(m->stack, False); ++ while(m->cl->stack) ++ unmanage(m->cl->stack, False); + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else +@@ -541,7 +581,7 @@ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } + else if(cme->message_type == netatom[NetActiveWindow]) { +- if(!ISVISIBLE(c)) { ++ if(!ISVISIBLE(c, c->mon)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; + } +@@ -624,7 +664,7 @@ + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); +- if(ISVISIBLE(c)) ++ if(ISVISIBLE(c, m)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } + else +@@ -645,11 +685,18 @@ + + Monitor * + createmon(void) { +- Monitor *m; ++ Monitor *m, *tm; ++ unsigned int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +- m->tagset[0] = m->tagset[1] = 1; ++ m->cl = cl; ++ /* reassing tags when creating a new monitor */ ++ for(i=1, tm = mons; tm; tm = tm->next, i++) { ++ tm->seltags ^= 1; ++ tm->tagset[tm->seltags] = i; ++ } ++ m->tagset[0] = m->tagset[1] = i; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; +@@ -673,7 +720,7 @@ + detach(Client *c) { + Client **tc; + +- for(tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); ++ for(tc = &c->mon->cl->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; + } + +@@ -681,11 +728,11 @@ + detachstack(Client *c) { + Client **tc, *t; + +- for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); ++ for(tc = &c->mon->cl->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if(c == c->mon->sel) { +- for(t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); ++ for(t = c->mon->cl->stack; t && !ISVISIBLE(t, c->mon); t = t->snext); + c->mon->sel = t; + } + } +@@ -722,7 +769,7 @@ + unsigned long *col; + Client *c; + +- for(c = m->clients; c; c = c->next) { ++ for(c = m->cl->clients; c; c = c->next) { + occ |= c->tags; + if(c->isurgent) + urg |= c->tags; +@@ -842,8 +889,8 @@ + + void + focus(Client *c) { +- if(!c || !ISVISIBLE(c)) +- for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); ++ if(!c || !ISVISIBLE(c, selmon)) ++ for(c = selmon->cl->stack; c && !ISVISIBLE(c, selmon); c = c->snext); + /* was if(selmon->sel) */ + if(selmon->sel && selmon->sel != c) + unfocus(selmon->sel, False); +@@ -892,17 +939,17 @@ + if(!selmon->sel) + return; + if(arg->i > 0) { +- for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); ++ for(c = selmon->sel->next; c && !ISVISIBLE(c, selmon); c = c->next); + if(!c) +- for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next); ++ for(c = selmon->cl->clients; c && !ISVISIBLE(c, selmon); c = c->next); + } + else { +- for(i = selmon->clients; i != selmon->sel; i = i->next) +- if(ISVISIBLE(i)) ++ for(i = selmon->cl->clients; i != selmon->sel; i = i->next) ++ if(ISVISIBLE(i, selmon)) + c = i; + if(!c) + for(; i; i = i->next) +- if(ISVISIBLE(i)) ++ if(ISVISIBLE(i, selmon)) + c = i; + } + if(c) { +@@ -1194,12 +1241,12 @@ + unsigned int n = 0; + Client *c; + +- for(c = m->clients; c; c = c->next) +- if(ISVISIBLE(c)) ++ for(c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) + n++; + if(n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) ++ for(c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); + } + +@@ -1275,8 +1322,8 @@ + } + + Client * +-nexttiled(Client *c) { +- for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); ++nexttiled(Client *c, Monitor *m) { ++ for(; c && (c->isfloating || !ISVISIBLE(c, m)); c = c->next); + return c; + } + +@@ -1426,8 +1473,8 @@ + if(m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; +- for(c = m->stack; c; c = c->snext) +- if(!c->isfloating && ISVISIBLE(c)) { ++ for(c = m->cl->stack; c; c = c->snext) ++ if(!c->isfloating && ISVISIBLE(c, m)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } +@@ -1477,11 +1524,9 @@ + if(c->mon == m) + return; + unfocus(c, True); +- detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1595,6 +1640,8 @@ + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + bh = dc.h = dc.font.height + 2; ++ if(!(cl = (Clientlist *)calloc(1, sizeof(Clientlist)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Clientlist)); + updategeom(); + /* init atoms */ + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); +@@ -1643,7 +1690,7 @@ + showhide(Client *c) { + if(!c) + return; +- if(ISVISIBLE(c)) { /* show clients top down */ ++ if(ISVISIBLE(c, c->mon)) { /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, False); +@@ -1677,7 +1724,23 @@ + + void + tag(const Arg *arg) { ++ Monitor *m; ++ unsigned int newtags; + if(selmon->sel && arg->ui & TAGMASK) { ++ newtags = arg->ui & TAGMASK; ++ for(m = mons; m; m = m->next) ++ /* if tag is visible on another monitor, move client to the new monitor */ ++ if(m != selmon && m->tagset[m->seltags] & newtags) { ++ /* prevent moving client to all tags (MODKEY-Shift-0) when multiple monitors are connected */ ++ if(newtags & selmon->tagset[selmon->seltags]) ++ return; ++ /* TODO sendmon? */ ++ selmon->sel->tags = newtags; ++ selmon->sel->mon = m; ++ arrange(m); ++ break; ++ } ++ /* workaround in case just one monitor is connected */ + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +@@ -1707,7 +1770,7 @@ + unsigned int i, n, h, mw, my, ty; + Client *c; + +- for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ for(n = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), n++); + if(n == 0) + return; + +@@ -1715,7 +1778,7 @@ + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; +- for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ for(i = my = ty = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), i++) + if(i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); +@@ -1749,12 +1812,17 @@ + + void + toggletag(const Arg *arg) { ++ Monitor *m; + unsigned int newtags; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { ++ /* prevent adding tags that are in use on other monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtags & m->tagset[m->seltags]) ++ return; + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); +@@ -1763,10 +1831,16 @@ + + void + toggleview(const Arg *arg) { ++ Monitor *m; + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if(newtagset) { ++ /* prevent displaying the same tags on multiple monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) ++ return; + selmon->tagset[selmon->seltags] = newtagset; ++ attachclients(selmon); + focus(NULL); + arrange(selmon); + } +@@ -1875,8 +1949,10 @@ + if(n <= nn) { + for(i = 0; i < (nn - n); i++) { /* new monitors available */ + for(m = mons; m && m->next; m = m->next); +- if(m) ++ if(m) { + m->next = createmon(); ++ attachclients(m->next); ++ } + else + mons = createmon(); + } +@@ -1897,17 +1973,13 @@ + else { /* less monitors available nn < n */ + for(i = nn; i < n; i++) { + for(m = mons; m && m->next; m = m->next); +- while(m->clients) { +- dirty = True; +- c = m->clients; +- m->clients = c->next; +- detachstack(c); +- c->mon = mons; +- attach(c); +- attachstack(c); +- } + if(m == selmon) + selmon = mons; ++ for(c = m->cl->clients; c; c = c->next) { ++ dirty = True; ++ if(ISVISIBLE(c, m)) ++ c->mon = selmon; ++ } + cleanupmon(m); + } + } +@@ -2046,11 +2118,31 @@ + + void + view(const Arg *arg) { ++ Monitor *m; ++ unsigned int newtagset = selmon->tagset[selmon->seltags ^ 1]; + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; ++ ++ /* swap tags when trying to display a tag from another monitor */ ++ if(arg->ui & TAGMASK) ++ newtagset = arg->ui & TAGMASK; ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) { ++ /* prevent displaying all tags (MODKEY-0) when multiple monitors ++ * are connected */ ++ if(newtagset & selmon->tagset[selmon->seltags]) ++ return; ++ m->seltags ^= 1; ++ m->tagset[m->seltags] = selmon->tagset[selmon->seltags]; ++ attachclients(m); ++ arrange(m); ++ break; ++ } ++ + selmon->seltags ^= 1; /* toggle sel tagset */ + if(arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ attachclients(selmon); + focus(NULL); + arrange(selmon); + } +@@ -2061,7 +2153,7 @@ + Monitor *m; + + for(m = mons; m; m = m->next) +- for(c = m->clients; c; c = c->next) ++ for(c = m->cl->clients; c; c = c->next) + if(c->win == w) + return c; + return NULL; +@@ -2123,8 +2215,8 @@ + if(!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if(c == nexttiled(selmon->clients)) +- if(!c || !(c = nexttiled(c->next))) ++ if(c == nexttiled(selmon->cl->clients, selmon)) ++ if(!c || !(c = nexttiled(c->next, selmon))) + return; + pop(c); + } diff --git a/dwm.suckless.org/patches/dwm-6.0-single_tagset_all.diff b/dwm.suckless.org/patches/dwm-6.0-single_tagset_all.diff @@ -0,0 +1,606 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: no URL yet +This patch addresses the multi-monitor setup. Instead of having separate tags +for every monitor there is just one list of tags for all monitors. Instead of +moving windows from one monitor to the other, the desired tag from the +other monitor can just be selected and all windows will be drawn on the +current monitor. + +Several deep changes needed to be made: +1. Macro ISVISIBLE expects a second parameter, the monitor +2. Monitor->clients and Monitor->stack were moved to the global variable + Clientlist cl. All monitors refer to this one list. +3. A new method attachclients was added. When changing between tags this + function ensures that all clients are pointing to the right monitor. + +Please be aware that this patch probably breaks any other patch! + +diff -r 454a5dd61441 dwm.c +--- a/dwm.c Sun Mar 18 20:45:06 2012 +0100 ++++ b/dwm.c Sun Mar 18 21:10:25 2012 +0100 +@@ -45,7 +45,7 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLE(C, M) ((C->tags & M->tagset[M->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MAX(A, B) ((A) > (B) ? (A) : (B)) + #define MIN(A, B) ((A) < (B) ? (A) : (B)) +@@ -126,6 +126,7 @@ + } Layout; + + typedef struct Pertag Pertag; ++typedef struct Clientlist Clientlist; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -139,9 +140,8 @@ + unsigned int tagset[2]; + Bool showbar; + Bool topbar; +- Client *clients; ++ Clientlist *cl; + Client *sel; +- Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +@@ -157,6 +157,11 @@ + int monitor; + } Rule; + ++struct Clientlist { ++ Client *clients; ++ Client *stack; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); +@@ -164,6 +169,7 @@ + static void arrangemon(Monitor *m); + static void attach(Client *c); + static void attachabove(Client *c); ++static void attachclients(Monitor *m); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -206,7 +212,7 @@ + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); +-static Client *nexttiled(Client *c); ++static Client *nexttiled(Client *c, Monitor *m); + static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); +@@ -290,6 +296,7 @@ + static DC dc; + static Monitor *mons = NULL, *selmon = NULL; + static Window root; ++static Clientlist *cl; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -410,9 +417,9 @@ + void + arrange(Monitor *m) { + if(m) +- showhide(m->stack); ++ showhide(m->cl->stack); + else for(m = mons; m; m = m->next) +- showhide(m->stack); ++ showhide(m->cl->stack); + if(m) { + arrangemon(m); + restack(m); +@@ -429,27 +436,60 @@ + + void + attach(Client *c) { +- c->next = c->mon->clients; +- c->mon->clients = c; ++ c->next = c->mon->cl->clients; ++ c->mon->cl->clients = c; + } + + void + attachabove(Client *c) { +- if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { ++ if(c->mon->sel == NULL || c->mon->sel == c->mon->cl->clients || c->mon->sel->isfloating) { + attach(c); + return; + } + + Client *at; +- for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); ++ for(at = c->mon->cl->clients; at->next != c->mon->sel; at = at->next); + c->next = at->next; + at->next = c; + } + + void ++attachclients(Monitor *m) { ++ /* attach clients to the specified monitor */ ++ Monitor *tm; ++ Client *c; ++ unsigned int utags = 0; ++ Bool rmons = False; ++ if(!m) ++ return; ++ ++ /* collect information about the tags in use */ ++ for(tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ utags |= m->tagset[m->seltags]; ++ ++ for(c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) { ++ /* if client is also visible on other tags that are displayed on ++ * other monitors, remove these tags */ ++ if(c->tags & utags) { ++ c->tags = c->tags & m->tagset[m->seltags]; ++ rmons = True; ++ } ++ unfocus(c, True); ++ c->mon = m; ++ } ++ ++ if(rmons) ++ for(tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ arrange(tm); ++} ++ ++void + attachstack(Client *c) { +- c->snext = c->mon->stack; +- c->mon->stack = c; ++ c->snext = c->mon->cl->stack; ++ c->mon->cl->stack = c; + } + + void +@@ -512,8 +552,8 @@ + view(&a); + selmon->lt[selmon->sellt] = &foo; + for(m = mons; m; m = m->next) +- while(m->stack) +- unmanage(m->stack, False); ++ while(m->cl->stack) ++ unmanage(m->cl->stack, False); + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else +@@ -570,7 +610,7 @@ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } + else if(cme->message_type == netatom[NetActiveWindow]) { +- if(!ISVISIBLE(c)) { ++ if(!ISVISIBLE(c, c->mon)) { + c->mon->seltags ^= 1; + c->mon->tagset[c->mon->seltags] = c->tags; + } +@@ -653,7 +693,7 @@ + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); +- if(ISVISIBLE(c)) ++ if(ISVISIBLE(c, m)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } + else +@@ -674,12 +714,18 @@ + + Monitor * + createmon(void) { +- Monitor *m; ++ Monitor *m, *tm; + int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +- m->tagset[0] = m->tagset[1] = 1; ++ m->cl = cl; ++ /* reassing tags when creating a new monitor */ ++ for(i=1, tm = mons; tm; tm = tm->next, i++) { ++ tm->seltags ^= 1; ++ tm->tagset[tm->seltags] = i; ++ } ++ m->tagset[0] = m->tagset[1] = i; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; +@@ -721,7 +767,7 @@ + detach(Client *c) { + Client **tc; + +- for(tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); ++ for(tc = &c->mon->cl->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; + } + +@@ -729,11 +775,11 @@ + detachstack(Client *c) { + Client **tc, *t; + +- for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); ++ for(tc = &c->mon->cl->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if(c == c->mon->sel) { +- for(t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); ++ for(t = c->mon->cl->stack; t && !ISVISIBLE(t, c->mon); t = t->snext); + c->mon->sel = t; + } + } +@@ -770,7 +816,7 @@ + unsigned long *col; + Client *c; + +- for(c = m->clients; c; c = c->next) { ++ for(c = m->cl->clients; c; c = c->next) { + occ |= c->tags; + if(c->isurgent) + urg |= c->tags; +@@ -886,8 +932,8 @@ + + void + focus(Client *c) { +- if(!c || !ISVISIBLE(c)) +- for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); ++ if(!c || !ISVISIBLE(c, selmon)) ++ for(c = selmon->cl->stack; c && !ISVISIBLE(c, selmon); c = c->snext); + /* was if(selmon->sel) */ + if(selmon->sel && selmon->sel != c) + unfocus(selmon->sel, False); +@@ -939,17 +985,17 @@ + if(!selmon->sel) + return; + if(arg->i > 0) { +- for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); ++ for(c = selmon->sel->next; c && !ISVISIBLE(c, selmon); c = c->next); + if(!c) +- for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next); ++ for(c = selmon->cl->clients; c && !ISVISIBLE(c, selmon); c = c->next); + } + else { +- for(i = selmon->clients; i != selmon->sel; i = i->next) +- if(ISVISIBLE(i)) ++ for(i = selmon->cl->clients; i != selmon->sel; i = i->next) ++ if(ISVISIBLE(i, selmon)) + c = i; + if(!c) + for(; i; i = i->next) +- if(ISVISIBLE(i)) ++ if(ISVISIBLE(i, selmon)) + c = i; + } + if(c) { +@@ -1254,12 +1300,12 @@ + unsigned int n = 0, r = 0; + Client *c; + +- for(c = m->clients; c; c = c->next) +- if(ISVISIBLE(c)) ++ for(c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) + n++; + if(n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { ++ for(c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m)) { + /* remove border when in monocle layout */ + if(c->bw) { + c->oldbw = c->bw; +@@ -1344,8 +1390,8 @@ + } + + Client * +-nexttiled(Client *c) { +- for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); ++nexttiled(Client *c, Monitor *m) { ++ for(; c && (c->isfloating || !ISVISIBLE(c, m)); c = c->next); + return c; + } + +@@ -1495,8 +1541,8 @@ + if(m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; +- for(c = m->stack; c; c = c->snext) +- if(!c->isfloating && ISVISIBLE(c)) { ++ for(c = m->cl->stack; c; c = c->snext) ++ if(!c->isfloating && ISVISIBLE(c, m)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } +@@ -1546,11 +1592,9 @@ + if(c->mon == m) + return; + unfocus(c, True); +- detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attachabove(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1667,6 +1711,8 @@ + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + bh = dc.h = dc.font.height + 2; ++ if(!(cl = (Clientlist *)calloc(1, sizeof(Clientlist)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Clientlist)); + updategeom(); + /* init atoms */ + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); +@@ -1717,7 +1763,7 @@ + showhide(Client *c) { + if(!c) + return; +- if(ISVISIBLE(c)) { /* show clients top down */ ++ if(ISVISIBLE(c, c->mon)) { /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, False); +@@ -1751,7 +1797,23 @@ + + void + tag(const Arg *arg) { ++ Monitor *m; ++ unsigned int newtags; + if(selmon->sel && arg->ui & TAGMASK) { ++ newtags = arg->ui & TAGMASK; ++ for(m = mons; m; m = m->next) ++ /* if tag is visible on another monitor, move client to the new monitor */ ++ if(m != selmon && m->tagset[m->seltags] & newtags) { ++ /* prevent moving client to all tags (MODKEY-Shift-0) when multiple monitors are connected */ ++ if(newtags & selmon->tagset[selmon->seltags]) ++ return; ++ /* TODO sendmon? */ ++ selmon->sel->tags = newtags; ++ selmon->sel->mon = m; ++ arrange(m); ++ break; ++ } ++ /* workaround in case just one monitor is connected */ + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +@@ -1781,7 +1843,7 @@ + unsigned int i, n, h, mw, my, ty, r; + Client *c; + +- for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ for(n = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), n++); + if(n == 0) + return; + +@@ -1789,7 +1851,7 @@ + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; +- for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++, r = 0) { ++ for(i = my = ty = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), i++, r = 0) { + if(n == 1) { + if (c->bw) { + /* remove border when only one window is on the current tag */ +@@ -1860,12 +1922,17 @@ + + void + toggletag(const Arg *arg) { ++ Monitor *m; + unsigned int newtags; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { ++ /* prevent adding tags that are in use on other monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtags & m->tagset[m->seltags]) ++ return; + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); +@@ -1874,10 +1941,15 @@ + + void + toggleview(const Arg *arg) { ++ Monitor *m; + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + int i; + + if(newtagset) { ++ /* prevent displaying the same tags on multiple monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) ++ return; + if(newtagset == ~0) { + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = 0; +@@ -1896,6 +1968,7 @@ + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ attachclients(selmon); + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) + togglebar(NULL); + focus(NULL); +@@ -2010,8 +2083,10 @@ + if(n <= nn) { + for(i = 0; i < (nn - n); i++) { /* new monitors available */ + for(m = mons; m && m->next; m = m->next); +- if(m) ++ if(m) { + m->next = createmon(); ++ attachclients(m->next); ++ } + else + mons = createmon(); + } +@@ -2032,17 +2107,13 @@ + else { /* less monitors available nn < n */ + for(i = nn; i < n; i++) { + for(m = mons; m && m->next; m = m->next); +- while(m->clients) { +- dirty = True; +- c = m->clients; +- m->clients = c->next; +- detachstack(c); +- c->mon = mons; +- attachabove(c); +- attachstack(c); +- } + if(m == selmon) + selmon = mons; ++ for(c = m->cl->clients; c; c = c->next) { ++ dirty = True; ++ if(ISVISIBLE(c, m)) ++ c->mon = selmon; ++ } + cleanupmon(m); + } + } +@@ -2183,11 +2254,30 @@ + + void + view(const Arg *arg) { ++ Monitor *m; ++ unsigned int newtagset = selmon->tagset[selmon->seltags ^ 1]; + int i; + unsigned int tmptag; + + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; ++ ++ /* swap tags when trying to display a tag from another monitor */ ++ if(arg->ui & TAGMASK) ++ newtagset = arg->ui & TAGMASK; ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) { ++ /* prevent displaying all tags (MODKEY-0) when multiple monitors ++ * are connected */ ++ if(newtagset & selmon->tagset[selmon->seltags]) ++ return; ++ m->seltags ^= 1; ++ m->tagset[m->seltags] = selmon->tagset[selmon->seltags]; ++ attachclients(m); ++ arrange(m); ++ break; ++ } ++ + selmon->seltags ^= 1; /* toggle sel tagset */ + if(arg->ui & TAGMASK) { + selmon->pertag->prevtag = selmon->pertag->curtag; +@@ -2208,6 +2298,7 @@ + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ attachclients(selmon); + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) + togglebar(NULL); + focus(NULL); +@@ -2220,7 +2311,7 @@ + Monitor *m; + + for(m = mons; m; m = m->next) +- for(c = m->clients; c; c = c->next) ++ for(c = m->cl->clients; c; c = c->next) + if(c->win == w) + return c; + return NULL; +@@ -2278,19 +2369,19 @@ + void + zoom(const Arg *arg) { + Client *c = selmon->sel; +- prevclient = selmon->clients; ++ prevclient = selmon->cl->clients; + Client *at, *tmp; + + if(!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if(c == nexttiled(selmon->clients)) +- if(!c || !(c = nexttiled(prevzoom))) { ++ if(c == nexttiled(selmon->cl->clients, selmon)) ++ if(!c || !(c = nexttiled(prevzoom, selmon))) { + c = selmon->sel; +- if(!c || !(c = nexttiled(c->next))) ++ if(!c || !(c = nexttiled(c->next, selmon))) + return; + } +- for(at = selmon->clients; at && at->next && at != c && at->next != c; at = nexttiled(at->next)) ; ++ for(at = selmon->cl->clients; at && at->next && at != c && at->next != c; at = nexttiled(at->next, selmon)) ; + pop(c); + /* swap windows instead of pushing the previous one down */ + if(at && at != c) { +diff -r 454a5dd61441 focusmaster.c +--- a/focusmaster.c Sun Mar 18 20:45:06 2012 +0100 ++++ b/focusmaster.c Sun Mar 18 21:10:25 2012 +0100 +@@ -1,4 +1,4 @@ + static void + focusmaster(const Arg *arg) { +- focus(selmon->clients); ++ focus(selmon->cl->clients); + } +diff -r 454a5dd61441 push.c +--- a/push.c Sun Mar 18 20:45:06 2012 +0100 ++++ b/push.c Sun Mar 18 21:10:25 2012 +0100 +@@ -2,8 +2,8 @@ + prevtiled(Client *c) { + Client *p, *r; + +- for(p = selmon->clients, r = NULL; p && p != c; p = p->next) +- if(!p->isfloating && ISVISIBLE(p)) ++ for(p = selmon->cl->clients, r = NULL; p && p != c; p = p->next) ++ if(!p->isfloating && ISVISIBLE(p, selmon)) + r = p; + return r; + } +@@ -19,10 +19,10 @@ + /* attach before c */ + detach(sel); + sel->next = c; +- if(selmon->clients == c) +- selmon->clients = sel; ++ if(selmon->cl->clients == c) ++ selmon->cl->clients = sel; + else { +- for(c = selmon->clients; c->next != sel->next; c = c->next); ++ for(c = selmon->cl->clients; c->next != sel->next; c = c->next); + c->next = sel; + } + } else { +@@ -43,7 +43,7 @@ + + if(!sel || sel->isfloating) + return; +- if((c = nexttiled(sel->next))) { ++ if((c = nexttiled(sel->next, selmon))) { + /* attach after c */ + detach(sel); + sel->next = c->next; +diff -r 454a5dd61441 tagall.c +--- a/tagall.c Sun Mar 18 20:45:06 2012 +0100 ++++ b/tagall.c Sun Mar 18 21:10:25 2012 +0100 +@@ -1,6 +1,6 @@ + void + tagall(const Arg *arg) { +- if (!selmon->clients) ++ if (!selmon->cl->clients) + return; + /* if parameter starts with F, just move floating windows */ + int floating_only = (char *)arg->v && ((char *)arg->v)[0] == 'F' ? 1 : 0; +@@ -8,7 +8,7 @@ + int j; + Client* c; + if(tag >= 0 && tag < LENGTH(tags)) +- for(c = selmon->clients; c; c = c->next) ++ for(c = selmon->cl->clients; c; c = c->next) + { + if(!floating_only || c->isfloating) + for(j = 0; j < LENGTH(tags); j++) diff --git a/dwm.suckless.org/patches/single_tagset.md b/dwm.suckless.org/patches/single_tagset.md @@ -0,0 +1,44 @@ +single tagset +============= + +Description +----------- + +This patch addresses the multi-monitor setup. Instead of having separate tags +for every monitor there is just one list of tags for all monitors. Instead of +moving windows from one monitor to the other, the desired tag from the +other monitor can just be selected and all windows will be drawn on the +current monitor. + +Several deep changes needed to be made: +1. Macro ISVISIBLE expects a second parameter, the monitor +2. Monitor->clients and Monitor->stack were moved to the global variable + Clientlist cl. All monitors refer to this one list. +3. A new method attachclients was added. When changing between tags this + function ensures that all clients are pointing to the right monitor. + +Please be aware that this patch probably breaks any other patch! + +* [dwm-6.0-single_tagset.diff](dwm-6.0-single_tagset.diff) (14K) (20120318) + +Special Version +--------------- +This is a special version of the patch that was created with following patches being applied: +* [attachabove](attachabove) +* [float_border_color](float_border_color) +* [focusmaster](https://bitbucket.org/jceb81/dwm-patches/src/90fb0feedff9/focusmaster.patch) +* [moveresize](moveresize) +* [noborder](noborder) +* [pertag](pertag) +* [push](push) +* [save_floats](save_floats) +* [statusallmons](statusallmons) +* [swapfocus](swapfocus) +* [tagall](tagall) +* [zoomswap](zoomswap) + +[dwm-6.0-single_tagset_all.diff](dwm-6.0-single_tagset_all.diff) (18K) (20120318) + +Authors +------- + * Jan Christoph Ebersbach - <jceb@e-jc.de>