sites

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

commit 3fbac93b047f5926381c03aa667a269db0ac305e
parent 0e75a72a7c2ed1836c26daa88de6f9e0bc8076ae
Author: Jan Christoph Ebersbach <jceb@e-jc.de>
Date:   Fri,  6 Apr 2012 09:21:40 +0200

provide patches for dwm tag 6.0 and tip
Diffstat:
Mdwm.suckless.org/patches/attachabove.md | 8+++++---
Adwm.suckless.org/patches/dwm-10e232f9ace7-attachabove.diff | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-maximize_vert_horz.diff | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-pertag.diff | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-push.diff | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff | 48++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff | 513+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-single_window_no_border.diff | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff | 43+++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-systray.diff | 625+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff | 32++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/dwm-10e232f9ace7-zoomswap.diff | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/dwm-6.0-attachabove.diff | 10+++++-----
Mdwm.suckless.org/patches/dwm-6.0-float_border_color2.diff | 22+++++++++++-----------
Mdwm.suckless.org/patches/dwm-6.0-maximize_vert_horz.diff | 10+++++-----
Mdwm.suckless.org/patches/dwm-6.0-moveresize.diff | 4++--
Mdwm.suckless.org/patches/dwm-6.0-pertag.diff | 16++++++++--------
Mdwm.suckless.org/patches/dwm-6.0-push.diff | 4++--
Mdwm.suckless.org/patches/dwm-6.0-save_floats.diff | 8++++----
Mdwm.suckless.org/patches/dwm-6.0-single_tagset.diff | 41++++++++++++++++++++---------------------
Mdwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff | 20++++++++------------
Mdwm.suckless.org/patches/dwm-6.0-statusallmons.diff | 8++++----
Mdwm.suckless.org/patches/dwm-6.0-swapfocus.diff | 27+++++++++++++++------------
Mdwm.suckless.org/patches/dwm-6.0-systray.diff | 127++++++++++++++++++++++++++++++++++---------------------------------------------
Mdwm.suckless.org/patches/dwm-6.0-tagall.diff | 4++--
Mdwm.suckless.org/patches/dwm-6.0-zoomswap.diff | 15++++++++++-----
Mdwm.suckless.org/patches/float_border_color.md | 6++----
Mdwm.suckless.org/patches/moveresize.md | 15++++++++-------
Mdwm.suckless.org/patches/noborder.md | 8++++++--
Mdwm.suckless.org/patches/pertag.md | 32++++++++++++++++----------------
Mdwm.suckless.org/patches/push.md | 13+++++++++----
Mdwm.suckless.org/patches/save_floats.md | 6++----
Mdwm.suckless.org/patches/single_tagset.md | 6+++---
Mdwm.suckless.org/patches/statusallmons.md | 8+++++---
Mdwm.suckless.org/patches/swapfocus.md | 7+++----
Mdwm.suckless.org/patches/systray.md | 5+++--
Mdwm.suckless.org/patches/tagall.md | 5++---
Mdwm.suckless.org/patches/zoomswap.md | 5+++--
41 files changed, 2226 insertions(+), 223 deletions(-)

diff --git a/dwm.suckless.org/patches/attachabove.md b/dwm.suckless.org/patches/attachabove.md @@ -11,9 +11,11 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-attachabove.diff](dwm-6.0-attachabove.diff) (1.6K) (20120214) -* [dwm-5.6.1-attachabove.diff](dwm-5.6.1-attachabove.diff) (1.1K) (20090817) + * [dwm-10e232f9ace7-attachabove.diff](dwm-10e232f9ace7-attachabove.diff) (1709b) (20120406) + * [dwm-6.0-attachabove.diff](dwm-6.0-attachabove.diff) (1707b) (20120406) + * [dwm-5.6.1-attachabove.diff](dwm-5.6.1-attachabove.diff) (1.1K) (20090817) Author ------ -* Mate Nagy - <mnagy@port70.net> + * Mate Nagy - <mnagy@port70.net> + * Rewritten by Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-attachabove.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-attachabove.diff @@ -0,0 +1,63 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/attachabove +attachabove makes new clients attach above the selected client (instead of +always becoming the new master) – basically how Xmonad does it. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:37 2012 +0200 +@@ -160,6 +160,7 @@ + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachabove(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -419,6 +420,19 @@ + } + + void ++attachabove(Client *c) { ++ if(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating) { ++ attach(c); ++ return; ++ } ++ ++ Client *at; ++ for(at = c->mon->clients; at->next != c->mon->sel; at = at->next); ++ c->next = at->next; ++ at->next = c; ++} ++ ++void + attachstack(Client *c) { + c->snext = c->mon->stack; + c->mon->stack = c; +@@ -1159,7 +1173,7 @@ + c->isfloating = c->oldstate = trans != None || c->isfixed; + if(c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ attachabove(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1493,7 +1507,7 @@ + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ attachabove(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1939,7 +1953,7 @@ + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ attachabove(c); + attachstack(c); + } + if(m == selmon) diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-float_border_color2.diff @@ -0,0 +1,84 @@ +URL: http://dwm.suckless.org/patches/historical/float_border_color +float_border_color2 allows you to specify a different border color for floating +windows. + +diff -r 10e232f9ace7 config.def.h +--- a/config.def.h Sun Mar 25 17:49:35 2012 +0200 ++++ b/config.def.h Fri Apr 06 08:16:29 2012 +0200 +@@ -8,6 +8,8 @@ + static const char selbordercolor[] = "#005577"; + static const char selbgcolor[] = "#005577"; + static const char selfgcolor[] = "#eeeeee"; ++static const char floatnormbordercolor[] = "#005577"; ++static const char floatselbordercolor[] = "#005577"; + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ + static const Bool showbar = True; /* False means no bar */ +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:29 2012 +0200 +@@ -57,7 +57,7 @@ + + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +-enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ ++enum { ColBorder, ColFG, ColBG, ColBorderFloat, ColLast }; /* color */ + enum { NetSupported, NetWMName, NetWMState, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +@@ -857,7 +857,10 @@ + detachstack(c); + attachstack(c); + grabbuttons(c, True); +- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, c->win, dc.sel[ColBorderFloat]); ++ else ++ XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); + setfocus(c); + } + else { +@@ -1159,6 +1162,8 @@ + c->isfloating = c->oldstate = trans != None || c->isfixed; + if(c->isfloating) + XRaiseWindow(dpy, c->win); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, w, dc.norm[ColBorderFloat]); + attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, +@@ -1633,9 +1638,11 @@ + dc.norm[ColBorder] = getcolor(normbordercolor); + dc.norm[ColBG] = getcolor(normbgcolor); + dc.norm[ColFG] = getcolor(normfgcolor); ++ dc.norm[ColBorderFloat] = getcolor(floatnormbordercolor); + dc.sel[ColBorder] = getcolor(selbordercolor); + dc.sel[ColBG] = getcolor(selbgcolor); + dc.sel[ColFG] = getcolor(selfgcolor); ++ dc.sel[ColBorderFloat] = getcolor(floatselbordercolor); + dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); +@@ -1760,6 +1767,10 @@ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if(selmon->sel->isfloating) ++ XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorderFloat]); ++ else ++ XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorder]); ++ if(selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, + selmon->sel->w, selmon->sel->h, False); + else if(selmon->sel->isfullscreen) +@@ -1797,7 +1808,10 @@ + if(!c) + return; + grabbuttons(c, False); +- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); ++ if(c->isfloating) ++ XSetWindowBorder(dpy, c->win, dc.norm[ColBorderFloat]); ++ else ++ XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); + if(setfocus) { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-maximize_vert_horz.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-maximize_vert_horz.diff @@ -0,0 +1,75 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/historical/moveresize +These patches provide helper functions for moving and resizing floating windows +using keybindings. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:26 2012 +0200 +@@ -90,7 +90,7 @@ + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; +- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ Bool ismax, wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; +@@ -1155,6 +1155,8 @@ + updatewmhints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); + grabbuttons(c, False); ++ c->wasfloating = False; ++ c->ismax = False; + if(!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if(c->isfloating) +diff -r 10e232f9ace7 maximize.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/maximize.c Fri Apr 06 08:16:26 2012 +0200 +@@ -0,0 +1,45 @@ ++void ++maximize(int x, int y, int w, int h) { ++ XEvent ev; ++ ++ if(!selmon->sel || selmon->sel->isfixed) ++ return; ++ XRaiseWindow(dpy, selmon->sel->win); ++ if(!selmon->sel->ismax) { ++ if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating) ++ selmon->sel->wasfloating = True; ++ else { ++ togglefloating(NULL); ++ selmon->sel->wasfloating = False; ++ } ++ selmon->sel->oldx = selmon->sel->x; ++ selmon->sel->oldy = selmon->sel->y; ++ selmon->sel->oldw = selmon->sel->w; ++ selmon->sel->oldh = selmon->sel->h; ++ resize(selmon->sel, x, y, w, h, True); ++ selmon->sel->ismax = True; ++ } ++ else { ++ resize(selmon->sel, selmon->sel->oldx, selmon->sel->oldy, selmon->sel->oldw, selmon->sel->oldh, True); ++ if(!selmon->sel->wasfloating) ++ togglefloating(NULL); ++ selmon->sel->ismax = False; ++ } ++ drawbar(selmon); ++ while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); ++} ++ ++void ++togglemaximize(const Arg *arg) { ++ maximize(selmon->wx, selmon->wy, selmon->ww - 2 * borderpx, selmon->wh - 2 * borderpx); ++} ++ ++void ++toggleverticalmax(const Arg *arg) { ++ maximize(selmon->sel->x, selmon->wy, selmon->sel->w, selmon->wh - 2 * borderpx); ++} ++ ++void ++togglehorizontalmax(const Arg *arg) { ++ maximize(selmon->wx, selmon->sel->y, selmon->ww - 2 * borderpx, selmon->sel->h); ++} diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff @@ -0,0 +1,73 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/historical/moveresize +These patches provide helper functions for moving and resizing floating windows +using keybindings. + +diff -r 10e232f9ace7 moveresize.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/moveresize.c Fri Apr 06 08:16:18 2012 +0200 +@@ -0,0 +1,64 @@ ++void ++moveresize(const Arg *arg) { ++ /* only floating windows can be moved */ ++ Client *c; ++ c = selmon->sel; ++ int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh; ++ char xAbs, yAbs, wAbs, hAbs; ++ int msx, msy, dx, dy, nmx, nmy; ++ unsigned int dui; ++ Window dummy; ++ ++ if (!c || !arg) ++ return; ++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) ++ return; ++ if(sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8) ++ return; ++ /* compute new window position; prevent window from be positioned outside the current monitor */ ++ nw = c->w + w; ++ if(wAbs == 'W') ++ nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw; ++ ++ nh = c->h + h; ++ if(hAbs == 'H') ++ nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw; ++ ++ nx = c->x + x; ++ if(xAbs == 'X') { ++ if(x < selmon->mx) ++ nx = selmon->mx; ++ else if(x > selmon->mx + selmon->mw) ++ nx = selmon->mx + selmon->mw - nw - 2 * c->bw; ++ else ++ nx = x; ++ } ++ ++ ny = c->y + y; ++ if(yAbs == 'Y') { ++ if(y < selmon->my) ++ ny = selmon->my; ++ else if(y > selmon->my + selmon->mh) ++ ny = selmon->my + selmon->mh - nh - 2 * c->bw; ++ else ++ ny = y; ++ } ++ ++ ox = c->x; ++ oy = c->y; ++ ow = c->w; ++ oh = c->h; ++ ++ XRaiseWindow(dpy, c->win); ++ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui); ++ resize(c, nx, ny, nw, nh, True); ++ ++ /* move cursor along with the window to avoid problems caused by the sloppy focus */ ++ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) ++ { ++ nmx = c->x - ox + c->w - ow; ++ nmy = c->y - oy + c->h - oh; ++ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy); ++ } ++} ++ diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-pertag.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-pertag.diff @@ -0,0 +1,181 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/pertag +This patch keeps layout, mwfact, barpos and nmaster per tag. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:31 2012 +0200 +@@ -124,6 +124,7 @@ + void (*arrange)(Monitor *); + } Layout; + ++typedef struct Pertag Pertag; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -143,6 +144,7 @@ + Monitor *next; + Window barwin; + const Layout *lt[2]; ++ Pertag *pertag; + }; + + typedef struct { +@@ -288,6 +290,15 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Pertag { ++ unsigned int curtag, prevtag; /* current and previous tag */ ++ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ ++ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ ++ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ ++ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ ++ Bool showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -648,6 +659,7 @@ + Monitor * + createmon(void) { + Monitor *m; ++ int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +@@ -659,6 +671,24 @@ + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); ++ m->pertag->curtag = m->pertag->prevtag = 1; ++ for(i=0; i <= LENGTH(tags); i++) { ++ /* init nmaster */ ++ m->pertag->nmasters[i] = m->nmaster; ++ ++ /* init mfacts */ ++ m->pertag->mfacts[i] = m->mfact; ++ ++ /* init layouts */ ++ m->pertag->ltidxs[i][0] = m->lt[0]; ++ m->pertag->ltidxs[i][1] = m->lt[1]; ++ m->pertag->sellts[i] = m->sellt; ++ ++ /* init showbar */ ++ m->pertag->showbars[i] = m->showbar; ++ } + return m; + } + +@@ -1032,7 +1062,7 @@ + + void + incnmaster(const Arg *arg) { +- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); + } + +@@ -1572,10 +1602,13 @@ + + void + setlayout(const Arg *arg) { +- if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) +- selmon->sellt ^= 1; ++ if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) { ++ selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++ } + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1593,7 +1626,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->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon); + } + +@@ -1748,7 +1781,7 @@ + + void + togglebar(const Arg *arg) { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1784,9 +1817,29 @@ + void + toggleview(const Arg *arg) { + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); ++ int i; + + if(newtagset) { ++ if(newtagset == ~0) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = 0; ++ } ++ /* test if the user did not select the same tag */ ++ if(!(newtagset & 1 << (selmon->pertag->curtag - 1))) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ for (i=0; !(newtagset & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } + selmon->tagset[selmon->seltags] = newtagset; ++ ++ /* apply settings for this view */ ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ 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]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } +@@ -2081,11 +2134,33 @@ + + void + view(const Arg *arg) { ++ int i; ++ unsigned int tmptag; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { ++ selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ if(arg->ui == ~0) ++ selmon->pertag->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++) ; ++ selmon->pertag->curtag = i + 1; ++ } ++ } else { ++ tmptag = selmon->pertag->prevtag; ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ selmon->pertag->curtag = tmptag; ++ } ++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++ 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]; ++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-push.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-push.diff @@ -0,0 +1,65 @@ +URL: http://dwm.suckless.org/patches/push +pushup and pushdown provide a way to move clients inside the clients list. + +diff -r 10e232f9ace7 push.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/push.c Fri Apr 06 08:16:39 2012 +0200 +@@ -0,0 +1,58 @@ ++static Client * ++prevtiled(Client *c) { ++ Client *p, *r; ++ ++ for(p = selmon->clients, r = NULL; p && p != c; p = p->next) ++ if(!p->isfloating && ISVISIBLE(p)) ++ r = p; ++ return r; ++} ++ ++static void ++pushup(const Arg *arg) { ++ Client *sel = selmon->sel; ++ Client *c; ++ ++ if(!sel || sel->isfloating) ++ return; ++ if((c = prevtiled(sel))) { ++ /* attach before c */ ++ detach(sel); ++ sel->next = c; ++ if(selmon->clients == c) ++ selmon->clients = sel; ++ else { ++ for(c = selmon->clients; c->next != sel->next; c = c->next); ++ c->next = sel; ++ } ++ } else { ++ /* move to the end */ ++ for(c = sel; c->next; c = c->next); ++ detach(sel); ++ sel->next = NULL; ++ c->next = sel; ++ } ++ focus(sel); ++ arrange(selmon); ++} ++ ++static void ++pushdown(const Arg *arg) { ++ Client *sel = selmon->sel; ++ Client *c; ++ ++ if(!sel || sel->isfloating) ++ return; ++ if((c = nexttiled(sel->next))) { ++ /* attach after c */ ++ detach(sel); ++ sel->next = c->next; ++ c->next = sel; ++ } else { ++ /* move to the front */ ++ detach(sel); ++ attach(sel); ++ } ++ focus(sel); ++ arrange(selmon); ++} diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff @@ -0,0 +1,48 @@ +URL: http://dwm.suckless.org/patches/historical/save_floats +This patch saves size and position of every floating window before it is forced +into tiled mode. If the window is made floating again, the old dimensions will +be restored. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:21 2012 +0200 +@@ -86,6 +86,7 @@ + char name[256]; + float mina, maxa; + int x, y, w, h; ++ int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */ + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; +@@ -1153,6 +1154,10 @@ + updatewindowtype(c); + updatesizehints(c); + updatewmhints(c); ++ c->sfx = c->x; ++ c->sfy = c->y; ++ c->sfw = c->w; ++ c->sfh = c->h; + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); + grabbuttons(c, False); + if(!c->isfloating) +@@ -1760,10 +1765,18 @@ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if(selmon->sel->isfloating) +- resize(selmon->sel, selmon->sel->x, selmon->sel->y, +- selmon->sel->w, selmon->sel->h, False); ++ /*restore last known float dimensions*/ ++ resize(selmon->sel, selmon->sel->sfx, selmon->sel->sfy, ++ selmon->sel->sfw, selmon->sel->sfh, False); + else if(selmon->sel->isfullscreen) + setfullscreen(selmon->sel, False); ++ else { ++ /*save last known float dimensions*/ ++ selmon->sel->sfx = selmon->sel->x; ++ selmon->sel->sfy = selmon->sel->y; ++ selmon->sel->sfw = selmon->sel->w; ++ selmon->sel->sfh = selmon->sel->h; ++ } + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff @@ -0,0 +1,513 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/single_tagset +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 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:16 2012 +0200 +@@ -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); +@@ -284,6 +290,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" +@@ -314,7 +321,7 @@ + { + c->isfloating = r->isfloating; + c->tags |= r->tags; +- for(m = mons; m && m->num != r->monitor; m = m->next); ++ for(m = mons; m && (m->tagset[m->seltags] & c->tags) == 0; m = m->next) ; + if(m) + c->mon = m; + } +@@ -395,9 +402,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); +@@ -414,14 +421,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 +@@ -484,8 +524,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 +@@ -543,7 +583,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; + } +@@ -626,7 +666,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 +@@ -647,11 +687,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; +@@ -675,7 +722,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; + } + +@@ -683,11 +730,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; + } + } +@@ -724,7 +771,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; +@@ -844,8 +891,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); +@@ -896,17 +943,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) { +@@ -1200,12 +1247,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); + } + +@@ -1284,8 +1331,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; + } + +@@ -1438,8 +1485,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; + } +@@ -1489,11 +1536,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); +@@ -1611,6 +1656,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); +@@ -1661,7 +1708,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); +@@ -1695,7 +1742,22 @@ + + 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; ++ 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); +@@ -1725,7 +1787,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; + +@@ -1733,7 +1795,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); +@@ -1769,12 +1831,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); +@@ -1783,10 +1850,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); + } +@@ -1881,7 +1954,7 @@ + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for(m = mons; m; m = m->next) +- for(c = m->clients; c; c = c->next) ++ for(c = m->cl->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], + XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1911,8 +1984,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(); + } +@@ -1933,17 +2008,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(c->mon == m) ++ c->mon = selmon; ++ } + cleanupmon(m); + } + } +@@ -2081,11 +2152,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); + } +@@ -2096,7 +2187,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; +@@ -2158,8 +2249,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-10e232f9ace7-single_window_no_border.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-single_window_no_border.diff @@ -0,0 +1,97 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/noborder +This patch removes the border when there is just one window visible in tiled or +monocle layout. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:34 2012 +0200 +@@ -1197,7 +1197,7 @@ + + void + monocle(Monitor *m) { +- unsigned int n = 0; ++ unsigned int n = 0, r = 0; + Client *c; + + for(c = m->clients; c; c = c->next) +@@ -1205,8 +1205,17 @@ + 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)) +- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); ++ for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) { ++ /* remove border when in monocle layout */ ++ if(c->bw) { ++ c->oldbw = c->bw; ++ c->bw = 0; ++ r = 1; ++ } ++ resize(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw), False); ++ if(r) ++ resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw)); ++ } + } + + void +@@ -1722,7 +1731,7 @@ + + void + tile(Monitor *m) { +- unsigned int i, n, h, mw, my, ty; ++ unsigned int i, n, h, mw, my, ty, r; + Client *c; + + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); +@@ -1733,17 +1742,36 @@ + 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->clients); c; c = nexttiled(c->next), i++, r = 0) { ++ if(n == 1) { ++ if (c->bw) { ++ /* remove border when only one window is on the current tag */ ++ c->oldbw = c->bw; ++ c->bw = 0; ++ r = 1; ++ } ++ } ++ else if(!c->bw && c->oldbw) { ++ /* restore border when more than one window is displayed */ ++ c->bw = c->oldbw; ++ c->oldbw = 0; ++ r = 1; ++ } + 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); ++ if(r) ++ resizeclient(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw)); + my += HEIGHT(c); + } + else { + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False); ++ if(r) ++ resizeclient(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw)); + ty += HEIGHT(c); + } ++ } + } + + void +@@ -1760,6 +1788,12 @@ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if(selmon->sel->isfloating) ++ /* restore border when moving window into floating mode */ ++ if(!selmon->sel->bw && selmon->sel->oldbw) { ++ selmon->sel->bw = selmon->sel->oldbw; ++ selmon->sel->oldbw = 0; ++ } ++ if(selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, + selmon->sel->w, selmon->sel->h, False); + else if(selmon->sel->isfullscreen) diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff @@ -0,0 +1,43 @@ +URL: http://dwm.suckless.org/patches/statusallmons +This patch draws and updates the statusbar on all monitors. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:42 2012 +0200 +@@ -742,17 +742,13 @@ + drawtext(m->ltsymbol, dc.norm, False); + dc.x += dc.w; + x = dc.x; +- if(m == selmon) { /* status is only drawn on selected monitor */ +- dc.w = TEXTW(stext); +- dc.x = m->ww - dc.w; +- if(dc.x < x) { +- dc.x = x; +- dc.w = m->ww - x; +- } +- drawtext(stext, dc.norm, False); ++ dc.w = TEXTW(stext); ++ dc.x = m->ww - dc.w; ++ if(dc.x < x) { ++ dc.x = x; ++ dc.w = m->ww - x; + } +- else +- dc.x = m->ww; ++ drawtext(stext, dc.norm, False); + if((dc.w = dc.x - x) > bh) { + dc.x = x; + if(m->sel) { +@@ -2044,9 +2040,11 @@ + + void + updatestatus(void) { ++ Monitor* m; + if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); +- drawbar(selmon); ++ for(m = mons; m; m = m->next) ++ drawbar(m); + } + + void diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff @@ -0,0 +1,55 @@ +URL: http://dwm.suckless.org/patches/swapfocus +This patch makes it possible to switch focus with one single shortcut (alt-s) +instead of having to think if you should use alt-j or alt-k for reaching the +last used window. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:45 2012 +0200 +@@ -224,6 +224,7 @@ + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void swapfocus(); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static int textnw(const char *text, unsigned int len); +@@ -254,6 +255,7 @@ + static void zoom(const Arg *arg); + + /* variables */ ++static Client *prevclient = NULL; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -1694,6 +1696,14 @@ + } + + void ++swapfocus(){ ++ Client *c; ++ for(c = selmon->clients; c && c != prevclient; c = c->next) ; ++ if(c == prevclient) ++ focus(prevclient); ++} ++ ++void + tag(const Arg *arg) { + if(selmon->sel && arg->ui & TAGMASK) { + selmon->sel->tags = arg->ui & TAGMASK; +@@ -1796,6 +1806,7 @@ + unfocus(Client *c, Bool setfocus) { + if(!c) + return; ++ prevclient = c; + grabbuttons(c, False); + XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); + if(setfocus) { +@@ -2154,6 +2165,7 @@ + void + zoom(const Arg *arg) { + Client *c = selmon->sel; ++ prevclient = selmon->clients; + + if(!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-systray.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-systray.diff @@ -0,0 +1,625 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de>, inspired by http://code.google.com/p/dwm-plus +URL: http://dwm.suckless.org/patches/systray +Implements a system tray for dwm. + +diff -r 10e232f9ace7 config.def.h +--- a/config.def.h Sun Mar 25 17:49:35 2012 +0200 ++++ b/config.def.h Wed Apr 04 22:18:50 2012 +0200 +@@ -10,6 +10,8 @@ + static const char selfgcolor[] = "#eeeeee"; + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const Bool showsystray = True; /* False means no systray */ + static const Bool showbar = True; /* False means no bar */ + static const Bool topbar = True; /* False means bottom bar */ + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Wed Apr 04 22:18:50 2012 +0200 +@@ -55,12 +55,30 @@ + #define TAGMASK ((1 << LENGTH(tags)) - 1) + #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) + ++#define SYSTEM_TRAY_REQUEST_DOCK 0 ++#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 ++ ++/* XEMBED messages */ ++#define XEMBED_EMBEDDED_NOTIFY 0 ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_FOCUS_IN 4 ++#define XEMBED_MODALITY_ON 10 ++ ++#define XEMBED_MAPPED (1 << 0) ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_WINDOW_DEACTIVATE 2 ++ ++#define VERSION_MAJOR 0 ++#define VERSION_MINOR 0 ++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR ++ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ +-enum { NetSupported, NetWMName, NetWMState, +- NetWMFullscreen, NetActiveWindow, NetWMWindowType, +- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, ++ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, ++ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ +@@ -154,6 +172,12 @@ + int monitor; + } Rule; + ++typedef struct Systray Systray; ++struct Systray { ++ Window win; ++ Client *icons; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); +@@ -186,9 +210,11 @@ + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static Atom getatomprop(Client *c, Atom prop); + static unsigned long getcolor(const char *colstr); + static Bool getrootptr(int *x, int *y); + static long getstate(Window w); ++static unsigned int getsystraywidth(); + static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, Bool focused); + static void grabkeys(void); +@@ -207,13 +233,16 @@ + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); + static Monitor *recttomon(int x, int y, int w, int h); ++static void removesystrayicon(Client *i); + static void resize(Client *c, int x, int y, int w, int h, Bool interact); ++static void resizebarwin(Monitor *m); + static void resizeclient(Client *c, int x, int y, int w, int h); + static void resizemouse(const Arg *arg); ++static void resizerequest(XEvent *e); + static void restack(Monitor *m); + static void run(void); + static void scan(void); +-static Bool sendevent(Client *c, Atom proto); ++static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); + static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); +@@ -242,18 +271,24 @@ + static void updatenumlockmask(void); + static void updatesizehints(Client *c); + static void updatestatus(void); ++static void updatesystray(void); ++static void updatesystrayicongeom(Client *i, int w, int h); ++static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); + static void updatewindowtype(Client *c); + static void updatetitle(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); ++static Client *wintosystrayicon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); + + /* variables */ ++static Systray *systray = NULL; ++static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -275,9 +310,10 @@ + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, ++ [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify + }; +-static Atom wmatom[WMLast], netatom[NetLast]; ++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; + static Bool running = True; + static Cursor cursor[CurLast]; + static Display *dpy; +@@ -498,6 +534,11 @@ + XFreeCursor(dpy, cursor[CurMove]); + while(mons) + cleanupmon(mons); ++ if(showsystray) { ++ XUnmapWindow(dpy, systray->win); ++ XDestroyWindow(dpy, systray->win); ++ free(systray); ++ } + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); +@@ -532,9 +573,48 @@ + + void + clientmessage(XEvent *e) { ++ XWindowAttributes wa; ++ XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + ++ if(showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { ++ /* add systray icons */ ++ if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { ++ if(!(c = (Client *)calloc(1, sizeof(Client)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); ++ c->win = cme->data.l[2]; ++ c->mon = selmon; ++ c->next = systray->icons; ++ systray->icons = c; ++ XGetWindowAttributes(dpy, c->win, &wa); ++ c->x = c->oldx = c->y = c->oldy = 0; ++ c->w = c->oldw = wa.width; ++ c->h = c->oldh = wa.height; ++ c->oldbw = wa.border_width; ++ c->bw = 0; ++ c->isfloating = True; ++ /* reuse tags field as mapped status */ ++ c->tags = 1; ++ updatesizehints(c); ++ updatesystrayicongeom(c, wa.width, wa.height); ++ XAddToSaveSet(dpy, c->win); ++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); ++ XReparentWindow(dpy, c->win, systray->win, 0, 0); ++ /* use parents background pixmap */ ++ swa.background_pixmap = ParentRelative; ++ XChangeWindowAttributes(dpy, c->win, CWBackPixmap, &swa); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ /* FIXME not sure if I have to send these events, too */ ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); ++ updatesystray(); ++ setclientstate(c, NormalState); ++ } ++ return; ++ } + if(!c) + return; + if(cme->message_type == netatom[NetWMState]) { +@@ -585,7 +665,7 @@ + dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); + updatebars(); + for(m = mons; m; m = m->next) +- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); ++ resizebarwin(m); + focus(NULL); + arrange(NULL); + } +@@ -669,6 +749,11 @@ + + if((c = wintoclient(ev->window))) + unmanage(c, True); ++ else if((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + } + + void +@@ -724,6 +809,7 @@ + unsigned long *col; + Client *c; + ++ resizebarwin(m); + for(c = m->clients; c; c = c->next) { + occ |= c->tags; + if(c->isurgent) +@@ -745,6 +831,9 @@ + if(m == selmon) { /* status is only drawn on selected monitor */ + dc.w = TEXTW(stext); + dc.x = m->ww - dc.w; ++ if(showsystray && m == selmon) { ++ dc.x -= getsystraywidth(); ++ } + if(dc.x < x) { + dc.x = x; + dc.w = m->ww - x; +@@ -773,6 +862,7 @@ + + for(m = mons; m; m = m->next) + drawbar(m); ++ updatesystray(); + } + + void +@@ -921,10 +1011,17 @@ + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; ++ /* FIXME getatomprop should return the number of items and a pointer to ++ * the stored data instead of this workaround */ ++ Atom req = XA_ATOM; ++ if(prop == xatom[XembedInfo]) ++ req = xatom[XembedInfo]; + +- if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, ++ if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; ++ if(da == xatom[XembedInfo] && dl == 2) ++ atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; +@@ -966,6 +1063,15 @@ + return result; + } + ++unsigned int ++getsystraywidth() { ++ unsigned int w = 0; ++ Client *i; ++ if(showsystray) ++ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; ++ return w ? w + systrayspacing : 1; ++} ++ + Bool + gettextprop(Window w, Atom atom, char *text, unsigned int size) { + char **list = NULL; +@@ -1100,7 +1206,7 @@ + killclient(const Arg *arg) { + if(!selmon->sel) + return; +- if(!sendevent(selmon->sel, wmatom[WMDelete])) { ++ if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); +@@ -1186,6 +1292,12 @@ + maprequest(XEvent *e) { + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; ++ Client *i; ++ if((i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + + if(!XGetWindowAttributes(dpy, ev->window, &wa)) + return; +@@ -1303,6 +1415,16 @@ + Window trans; + XPropertyEvent *ev = &e->xproperty; + ++ if((c = wintosystrayicon(ev->window))) { ++ if(ev->atom == XA_WM_NORMAL_HINTS) { ++ updatesizehints(c); ++ updatesystrayicongeom(c, c->w, c->h); ++ } ++ else ++ updatesystrayiconstate(c, ev); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + if((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if(ev->state == PropertyDelete) +@@ -1352,12 +1474,33 @@ + } + + void ++removesystrayicon(Client *i) { ++ Client **ii; ++ ++ if(!showsystray || !i) ++ return; ++ for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); ++ if(ii) ++ *ii = i->next; ++ free(i); ++} ++ ++ ++void + resize(Client *c, int x, int y, int w, int h, Bool interact) { + if(applysizehints(c, &x, &y, &w, &h, interact)) + resizeclient(c, x, y, w, h); + } + + void ++resizebarwin(Monitor *m) { ++ unsigned int w = m->ww; ++ if(showsystray && m == selmon) ++ w -= getsystraywidth(); ++ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); ++} ++ ++void + resizeclient(Client *c, int x, int y, int w, int h) { + XWindowChanges wc; + +@@ -1425,6 +1568,18 @@ + } + + void ++resizerequest(XEvent *e) { ++ XResizeRequestEvent *ev = &e->xresizerequest; ++ Client *i; ++ ++ if((i = wintosystrayicon(ev->window))) { ++ updatesystrayicongeom(i, ev->width, ev->height); ++ resizebarwin(selmon); ++ updatesystray(); ++ } ++} ++ ++void + restack(Monitor *m) { + Client *c; + XEvent ev; +@@ -1508,25 +1663,35 @@ + } + + Bool +-sendevent(Client *c, Atom proto) { ++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) { + int n; +- Atom *protocols; ++ Atom *protocols, mt; + Bool exists = False; + XEvent ev; + +- if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { +- while(!exists && n--) +- exists = protocols[n] == proto; +- XFree(protocols); ++ if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { ++ mt = wmatom[WMProtocols]; ++ if(XGetWMProtocols(dpy, w, &protocols, &n)) { ++ while(!exists && n--) ++ exists = protocols[n] == proto; ++ XFree(protocols); ++ } ++ } ++ else { ++ exists = True; ++ mt = proto; + } + if(exists) { + ev.type = ClientMessage; +- ev.xclient.window = c->win; +- ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; + ev.xclient.format = 32; +- ev.xclient.data.l[0] = proto; +- ev.xclient.data.l[1] = CurrentTime; +- XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ ev.xclient.data.l[0] = d0; ++ ev.xclient.data.l[1] = d1; ++ ev.xclient.data.l[2] = d2; ++ ev.xclient.data.l[3] = d3; ++ ev.xclient.data.l[4] = d4; ++ XSendEvent(dpy, w, False, mask, &ev); + } + return exists; + } +@@ -1539,7 +1704,7 @@ + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } +- sendevent(c, wmatom[WMTakeFocus]); ++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + } + + void +@@ -1619,12 +1784,18 @@ + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); ++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); ++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); ++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); ++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); ++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); ++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + /* init cursors */ + cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); + cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); +@@ -1641,6 +1812,8 @@ + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); ++ /* init system tray */ ++ updatesystray(); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1750,7 +1923,18 @@ + togglebar(const Arg *arg) { + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); +- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ resizebarwin(selmon); ++ if(showsystray) { ++ XWindowChanges wc; ++ if(!selmon->showbar) ++ wc.y = -bh; ++ else if(selmon->showbar) { ++ wc.y = 0; ++ if(!selmon->topbar) ++ wc.y = selmon->mh - bh; ++ } ++ XConfigureWindow(dpy, systray->win, CWY, &wc); ++ } + arrange(selmon); + } + +@@ -1840,11 +2024,18 @@ + else + unmanage(c, False); + } ++ else if((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } + } + + void + updatebars(void) { ++ unsigned int w; + Monitor *m; ++ + XSetWindowAttributes wa = { + .override_redirect = True, + .background_pixmap = ParentRelative, +@@ -1853,7 +2044,10 @@ + for(m = mons; m; m = m->next) { + if (m->barwin) + continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), ++ w = m->ww; ++ if(showsystray && m == selmon) ++ w -= getsystraywidth(); ++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]); +@@ -2050,6 +2244,104 @@ + } + + void ++updatesystrayicongeom(Client *i, int w, int h) { ++ if(i) { ++ i->h = bh; ++ if(w == h) ++ i->w = bh; ++ else if(h == bh) ++ i->w = w; ++ else ++ i->w = (int) ((float)bh * ((float)w / (float)h)); ++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); ++ /* force icons into the systray dimenons if they don't want to */ ++ if(i->h > bh) { ++ if(i->w == i->h) ++ i->w = bh; ++ else ++ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); ++ i->h = bh; ++ } ++ } ++} ++ ++void ++updatesystrayiconstate(Client *i, XPropertyEvent *ev) { ++ long flags; ++ int code = 0; ++ ++ if(!showsystray || !i || ev->atom != xatom[XembedInfo] || ++ !(flags = getatomprop(i, xatom[XembedInfo]))) ++ return; ++ ++ if(flags & XEMBED_MAPPED && !i->tags) { ++ i->tags = 1; ++ code = XEMBED_WINDOW_ACTIVATE; ++ XMapRaised(dpy, i->win); ++ setclientstate(i, NormalState); ++ } ++ else if(!(flags & XEMBED_MAPPED) && i->tags) { ++ i->tags = 0; ++ code = XEMBED_WINDOW_DEACTIVATE; ++ XUnmapWindow(dpy, i->win); ++ setclientstate(i, WithdrawnState); ++ } ++ else ++ return; ++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, ++ systray->win, XEMBED_EMBEDDED_VERSION); ++} ++ ++void ++updatesystray(void) { ++ XSetWindowAttributes wa; ++ Client *i; ++ unsigned int x = selmon->mx + selmon->mw; ++ unsigned int w = 1; ++ ++ if(!showsystray) ++ return; ++ if(!systray) { ++ /* init systray */ ++ if(!(systray = (Systray *)calloc(1, sizeof(Systray)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); ++ systray->win = XCreateSimpleWindow(dpy, root, x, selmon->by, w, bh, 0, 0, dc.sel[ColBG]); ++ wa.event_mask = ButtonPressMask | ExposureMask; ++ wa.override_redirect = True; ++ wa.background_pixmap = ParentRelative; ++ wa.background_pixel = dc.norm[ColBG]; ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, ++ PropModeReplace, (unsigned char *)&systrayorientation, 1); ++ XChangeWindowAttributes(dpy, systray->win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wa); ++ XMapRaised(dpy, systray->win); ++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); ++ if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); ++ XSync(dpy, False); ++ } ++ else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return; ++ } ++ } ++ for(w = 0, i = systray->icons; i; i = i->next) { ++ XMapRaised(dpy, i->win); ++ w += systrayspacing; ++ XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->h); ++ w += i->w; ++ if(i->mon != selmon) ++ i->mon = selmon; ++ } ++ w = w ? w + systrayspacing : 1; ++ x -= w; ++ XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh); ++ XSync(dpy, False); ++} ++ ++void + updatewindowtype(Client *c) { + Atom state = getatomprop(c, netatom[NetWMState]); + Atom wtype = getatomprop(c, netatom[NetWMWindowType]); +@@ -2118,6 +2410,16 @@ + return selmon; + } + ++Client * ++wintosystrayicon(Window w) { ++ Client *i = NULL; ++ ++ if(!showsystray || !w) ++ return i; ++ for(i = systray->icons; i && i->win != w; i = i->next) ; ++ return i; ++} ++ + /* 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 --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff @@ -0,0 +1,32 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/historical/tagall +Shortcut to move all (floating) windows from one tag to another. + +diff -r 10e232f9ace7 tagall.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/tagall.c Fri Apr 06 08:16:23 2012 +0200 +@@ -0,0 +1,24 @@ ++void ++tagall(const Arg *arg) { ++ if (!selmon->clients) ++ return; ++ /* if parameter starts with F, just move floating windows */ ++ int floating_only = (char *)arg->v && ((char *)arg->v)[0] == 'F' ? 1 : 0; ++ int tag = (char *)arg->v ? atoi(((char *)arg->v) + floating_only) : 0; ++ int j; ++ Client* c; ++ if(tag >= 0 && tag < LENGTH(tags)) ++ for(c = selmon->clients; c; c = c->next) ++ { ++ if(!floating_only || c->isfloating) ++ for(j = 0; j < LENGTH(tags); j++) ++ { ++ if(c->tags & 1 << j && selmon->tagset[selmon->seltags] & 1 << j) ++ { ++ c->tags = c->tags ^ (1 << j & TAGMASK); ++ c->tags = c->tags | 1 << (tag-1); ++ } ++ } ++ } ++ arrange(selmon); ++} diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-zoomswap.diff b/dwm.suckless.org/patches/dwm-10e232f9ace7-zoomswap.diff @@ -0,0 +1,55 @@ +Author: Jan Christoph Ebersbach <jceb@e-jc.de> +URL: http://dwm.suckless.org/patches/zoomswap +This patch swaps the current window with the previous master when zooming. + +diff -r 10e232f9ace7 dwm.c +--- a/dwm.c Sun Mar 25 17:49:35 2012 +0200 ++++ b/dwm.c Fri Apr 06 08:16:47 2012 +0200 +@@ -254,6 +254,7 @@ + static void zoom(const Arg *arg); + + /* variables */ ++static Client *prevzoom = NULL; + static const char broken[] = "broken"; + static char stext[256]; + static int screen; +@@ -2154,14 +2155,36 @@ + void + zoom(const Arg *arg) { + Client *c = selmon->sel; ++ Client *at, *tmp; + + if(!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if(c == nexttiled(selmon->clients)) +- if(!c || !(c = nexttiled(c->next))) +- return; ++ if(c == nexttiled(selmon->clients)) { ++ for(tmp = selmon->clients; tmp && tmp != prevzoom; tmp = tmp->next) ; ++ if(tmp != prevzoom) ++ prevzoom = NULL; ++ if(!c || !(c = nexttiled(prevzoom))) { ++ c = selmon->sel; ++ if(!c || !(c = nexttiled(c->next))) ++ return; ++ } ++ } ++ for(at = selmon->clients; at && at->next && at != c && at->next != c; at = nexttiled(at->next)) ; + pop(c); ++ /* swap windows instead of pushing the previous one down */ ++ if(at && at != c) { ++ /* store c's next neighbor - this window needs to be moved away */ ++ tmp = prevzoom = c->next; ++ if(c->next != at) { ++ /* detach c's neighbor from the list of windows */ ++ c->next = tmp->next; ++ /* attach tmp after c's previous neighbor */ ++ tmp->next = at->next; ++ at->next = tmp; ++ arrange(c->mon); ++ } ++ } + } + + int diff --git a/dwm.suckless.org/patches/dwm-6.0-attachabove.diff b/dwm.suckless.org/patches/dwm-6.0-attachabove.diff @@ -3,9 +3,9 @@ URL: http://dwm.suckless.org/patches/attachabove attachabove makes new clients attach above the selected client (instead of always becoming the new master) – basically how Xmonad does it. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:10 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:34 2012 +0200 @@ -160,6 +160,7 @@ static void arrange(Monitor *m); static void arrangemon(Monitor *m); @@ -43,7 +43,7 @@ diff -r ad90e7fab364 dwm.c attachstack(c); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ setclientstate(c, NormalState); -@@ -1481,7 +1495,7 @@ +@@ -1480,7 +1494,7 @@ detachstack(c); c->mon = m; c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ @@ -52,7 +52,7 @@ diff -r ad90e7fab364 dwm.c attachstack(c); focus(NULL); arrange(NULL); -@@ -1903,7 +1917,7 @@ +@@ -1900,7 +1914,7 @@ m->clients = c->next; detachstack(c); c->mon = mons; diff --git a/dwm.suckless.org/patches/dwm-6.0-float_border_color2.diff b/dwm.suckless.org/patches/dwm-6.0-float_border_color2.diff @@ -2,9 +2,9 @@ URL: http://dwm.suckless.org/patches/historical/float_border_color float_border_color2 allows you to specify a different border color for floating windows. -diff -r ad90e7fab364 config.def.h ---- a/config.def.h Fri Feb 10 00:36:08 2012 +0000 -+++ b/config.def.h Sat Mar 24 13:41:08 2012 +0100 +diff -r ec4baab78314 config.def.h +--- a/config.def.h Mon Dec 19 15:38:30 2011 +0100 ++++ b/config.def.h Fri Apr 06 08:23:26 2012 +0200 @@ -8,6 +8,8 @@ static const char selbordercolor[] = "#005577"; static const char selbgcolor[] = "#005577"; @@ -14,9 +14,9 @@ diff -r ad90e7fab364 config.def.h static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ static const Bool showbar = True; /* False means no bar */ -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:08 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:26 2012 +0200 @@ -57,7 +57,7 @@ /* enums */ @@ -47,7 +47,7 @@ diff -r ad90e7fab364 dwm.c attach(c); attachstack(c); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ -@@ -1616,9 +1621,11 @@ +@@ -1615,9 +1620,11 @@ dc.norm[ColBorder] = getcolor(normbordercolor); dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); @@ -60,17 +60,17 @@ diff -r ad90e7fab364 dwm.c dc.gc = XCreateGC(dpy, root, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); @@ -1741,6 +1748,10 @@ - if(!selmon->sel) return; selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; -+ if(selmon->sel->isfloating) + if(selmon->sel->isfloating) + XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorderFloat]); + else + XSetWindowBorder(dpy, selmon->sel->win, dc.sel[ColBorder]); - if(selmon->sel->isfloating) ++ if(selmon->sel->isfloating) resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h, False); -@@ -1777,7 +1788,10 @@ + arrange(selmon); +@@ -1776,7 +1787,10 @@ if(!c) return; grabbuttons(c, False); diff --git a/dwm.suckless.org/patches/dwm-6.0-maximize_vert_horz.diff b/dwm.suckless.org/patches/dwm-6.0-maximize_vert_horz.diff @@ -3,9 +3,9 @@ URL: http://dwm.suckless.org/patches/historical/moveresize These patches provide helper functions for moving and resizing floating windows using keybindings. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:07 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:23 2012 +0200 @@ -90,7 +90,7 @@ int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; @@ -24,9 +24,9 @@ diff -r ad90e7fab364 dwm.c if(!c->isfloating) c->isfloating = c->oldstate = trans != None || c->isfixed; if(c->isfloating) -diff -r ad90e7fab364 maximize.c +diff -r ec4baab78314 maximize.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/maximize.c Sat Mar 24 13:41:07 2012 +0100 ++++ b/maximize.c Fri Apr 06 08:23:23 2012 +0200 @@ -0,0 +1,45 @@ +void +maximize(int x, int y, int w, int h) { diff --git a/dwm.suckless.org/patches/dwm-6.0-moveresize.diff b/dwm.suckless.org/patches/dwm-6.0-moveresize.diff @@ -3,9 +3,9 @@ URL: http://dwm.suckless.org/patches/historical/moveresize These patches provide helper functions for moving and resizing floating windows using keybindings. -diff -r ad90e7fab364 moveresize.c +diff -r ec4baab78314 moveresize.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/moveresize.c Sat Mar 24 13:41:04 2012 +0100 ++++ b/moveresize.c Fri Apr 06 08:23:15 2012 +0200 @@ -0,0 +1,64 @@ +void +moveresize(const Arg *arg) { diff --git a/dwm.suckless.org/patches/dwm-6.0-pertag.diff b/dwm.suckless.org/patches/dwm-6.0-pertag.diff @@ -2,9 +2,9 @@ Author: Jan Christoph Ebersbach <jceb@e-jc.de> URL: http://dwm.suckless.org/patches/pertag This patch keeps layout, mwfact, barpos and nmaster per tag. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:09 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:29 2012 +0200 @@ -124,6 +124,7 @@ void (*arrange)(Monitor *); } Layout; @@ -79,7 +79,7 @@ diff -r ad90e7fab364 dwm.c arrange(selmon); } -@@ -1556,10 +1586,13 @@ +@@ -1555,10 +1585,13 @@ void setlayout(const Arg *arg) { @@ -96,7 +96,7 @@ diff -r ad90e7fab364 dwm.c strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); if(selmon->sel) arrange(selmon); -@@ -1577,7 +1610,7 @@ +@@ -1576,7 +1609,7 @@ f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; if(f < 0.1 || f > 0.9) return; @@ -105,7 +105,7 @@ diff -r ad90e7fab364 dwm.c arrange(selmon); } -@@ -1730,7 +1763,7 @@ +@@ -1729,7 +1762,7 @@ void togglebar(const Arg *arg) { @@ -114,7 +114,7 @@ diff -r ad90e7fab364 dwm.c updatebarpos(selmon); XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); arrange(selmon); -@@ -1764,9 +1797,29 @@ +@@ -1763,9 +1796,29 @@ void toggleview(const Arg *arg) { unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); @@ -144,7 +144,7 @@ diff -r ad90e7fab364 dwm.c focus(NULL); arrange(selmon); } -@@ -2046,11 +2099,33 @@ +@@ -2043,11 +2096,33 @@ void view(const Arg *arg) { diff --git a/dwm.suckless.org/patches/dwm-6.0-push.diff b/dwm.suckless.org/patches/dwm-6.0-push.diff @@ -1,9 +1,9 @@ URL: http://dwm.suckless.org/patches/push pushup and pushdown provide a way to move clients inside the clients list. -diff -r ad90e7fab364 push.c +diff -r ec4baab78314 push.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/push.c Sat Mar 24 13:41:11 2012 +0100 ++++ b/push.c Fri Apr 06 08:23:37 2012 +0200 @@ -0,0 +1,58 @@ +static Client * +prevtiled(Client *c) { diff --git a/dwm.suckless.org/patches/dwm-6.0-save_floats.diff b/dwm.suckless.org/patches/dwm-6.0-save_floats.diff @@ -3,9 +3,9 @@ This patch saves size and position of every floating window before it is forced into tiled mode. If the window is made floating again, the old dimensions will be restored. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:05 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:18 2012 +0200 @@ -86,6 +86,7 @@ char name[256]; float mina, maxa; @@ -25,7 +25,7 @@ diff -r ad90e7fab364 dwm.c XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); grabbuttons(c, False); if(!c->isfloating) -@@ -1742,8 +1747,16 @@ +@@ -1741,8 +1746,16 @@ return; selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; if(selmon->sel->isfloating) diff --git a/dwm.suckless.org/patches/dwm-6.0-single_tagset.diff b/dwm.suckless.org/patches/dwm-6.0-single_tagset.diff @@ -15,9 +15,9 @@ Several deep changes needed to be made: Please be aware that this patch probably breaks any other patch! -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sun Mar 25 11:43:05 2012 +0200 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:13 2012 +0200 @@ -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)) \ @@ -100,9 +100,9 @@ diff -r ad90e7fab364 dwm.c else for(m = mons; m; m = m->next) - showhide(m->stack); + showhide(m->cl->stack); - if(m) { + if(m) arrangemon(m); - restack(m); + else for(m = mons; m; m = m->next) @@ -413,14 +420,47 @@ void @@ -287,7 +287,7 @@ diff -r ad90e7fab364 dwm.c resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); } -@@ -1275,8 +1322,8 @@ +@@ -1274,8 +1321,8 @@ } Client * @@ -298,7 +298,7 @@ diff -r ad90e7fab364 dwm.c return c; } -@@ -1426,8 +1473,8 @@ +@@ -1425,8 +1472,8 @@ if(m->lt[m->sellt]->arrange) { wc.stack_mode = Below; wc.sibling = m->barwin; @@ -309,7 +309,7 @@ diff -r ad90e7fab364 dwm.c XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); wc.sibling = c->win; } -@@ -1477,11 +1524,9 @@ +@@ -1476,11 +1523,9 @@ if(c->mon == m) return; unfocus(c, True); @@ -321,7 +321,7 @@ diff -r ad90e7fab364 dwm.c attachstack(c); focus(NULL); arrange(NULL); -@@ -1595,6 +1640,8 @@ +@@ -1594,6 +1639,8 @@ sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); bh = dc.h = dc.font.height + 2; @@ -330,7 +330,7 @@ diff -r ad90e7fab364 dwm.c updategeom(); /* init atoms */ wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1643,7 +1690,7 @@ +@@ -1642,7 +1689,7 @@ showhide(Client *c) { if(!c) return; @@ -339,7 +339,7 @@ diff -r ad90e7fab364 dwm.c 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 @@ +@@ -1676,7 +1723,22 @@ void tag(const Arg *arg) { @@ -353,7 +353,6 @@ diff -r ad90e7fab364 dwm.c + /* 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); @@ -363,7 +362,7 @@ diff -r ad90e7fab364 dwm.c selmon->sel->tags = arg->ui & TAGMASK; focus(NULL); arrange(selmon); -@@ -1707,7 +1770,7 @@ +@@ -1706,7 +1768,7 @@ unsigned int i, n, h, mw, my, ty; Client *c; @@ -372,7 +371,7 @@ diff -r ad90e7fab364 dwm.c if(n == 0) return; -@@ -1715,7 +1778,7 @@ +@@ -1714,7 +1776,7 @@ mw = m->nmaster ? m->ww * m->mfact : 0; else mw = m->ww; @@ -381,7 +380,7 @@ diff -r ad90e7fab364 dwm.c 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 @@ +@@ -1748,12 +1810,17 @@ void toggletag(const Arg *arg) { @@ -399,7 +398,7 @@ diff -r ad90e7fab364 dwm.c selmon->sel->tags = newtags; focus(NULL); arrange(selmon); -@@ -1763,10 +1831,16 @@ +@@ -1762,10 +1829,16 @@ void toggleview(const Arg *arg) { @@ -416,7 +415,7 @@ diff -r ad90e7fab364 dwm.c focus(NULL); arrange(selmon); } -@@ -1875,8 +1949,10 @@ +@@ -1872,8 +1945,10 @@ if(n <= nn) { for(i = 0; i < (nn - n); i++) { /* new monitors available */ for(m = mons; m && m->next; m = m->next); @@ -428,7 +427,7 @@ diff -r ad90e7fab364 dwm.c else mons = createmon(); } -@@ -1897,17 +1973,13 @@ +@@ -1894,17 +1969,13 @@ else { /* less monitors available nn < n */ for(i = nn; i < n; i++) { for(m = mons; m && m->next; m = m->next); @@ -451,7 +450,7 @@ diff -r ad90e7fab364 dwm.c cleanupmon(m); } } -@@ -2046,11 +2118,31 @@ +@@ -2043,11 +2114,31 @@ void view(const Arg *arg) { @@ -483,7 +482,7 @@ diff -r ad90e7fab364 dwm.c focus(NULL); arrange(selmon); } -@@ -2061,7 +2153,7 @@ +@@ -2058,7 +2149,7 @@ Monitor *m; for(m = mons; m; m = m->next) @@ -492,7 +491,7 @@ diff -r ad90e7fab364 dwm.c if(c->win == w) return c; return NULL; -@@ -2123,8 +2215,8 @@ +@@ -2120,8 +2211,8 @@ if(!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)) return; diff --git a/dwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff b/dwm.suckless.org/patches/dwm-6.0-single_window_no_border.diff @@ -3,9 +3,9 @@ URL: http://dwm.suckless.org/patches/noborder This patch removes the border when there is just one window visible in tiled or monocle layout. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:09 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:31 2012 +0200 @@ -1191,7 +1191,7 @@ void @@ -35,7 +35,7 @@ diff -r ad90e7fab364 dwm.c } void -@@ -1704,7 +1713,7 @@ +@@ -1703,7 +1712,7 @@ void tile(Monitor *m) { @@ -44,7 +44,7 @@ diff -r ad90e7fab364 dwm.c Client *c; for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -@@ -1715,17 +1724,36 @@ +@@ -1714,17 +1723,36 @@ mw = m->nmaster ? m->ww * m->mfact : 0; else mw = m->ww; @@ -82,20 +82,16 @@ diff -r ad90e7fab364 dwm.c } void -@@ -1741,9 +1769,15 @@ - if(!selmon->sel) +@@ -1741,6 +1769,12 @@ return; selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; -- if(selmon->sel->isfloating) -+ if(selmon->sel->isfloating) { + if(selmon->sel->isfloating) + /* restore border when moving window into floating mode */ + if(!selmon->sel->bw && selmon->sel->oldbw) { + selmon->sel->bw = selmon->sel->oldbw; + selmon->sel->oldbw = 0; + } ++ if(selmon->sel->isfloating) resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h, False); -+ } arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/dwm-6.0-statusallmons.diff b/dwm.suckless.org/patches/dwm-6.0-statusallmons.diff @@ -1,9 +1,9 @@ URL: http://dwm.suckless.org/patches/statusallmons This patch draws and updates the statusbar on all monitors. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:12 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:39 2012 +0200 @@ -740,17 +740,13 @@ drawtext(m->ltsymbol, dc.norm, False); dc.x += dc.w; @@ -28,7 +28,7 @@ diff -r ad90e7fab364 dwm.c if((dc.w = dc.x - x) > bh) { dc.x = x; if(m->sel) { -@@ -2008,9 +2004,11 @@ +@@ -2005,9 +2001,11 @@ void updatestatus(void) { diff --git a/dwm.suckless.org/patches/dwm-6.0-swapfocus.diff b/dwm.suckless.org/patches/dwm-6.0-swapfocus.diff @@ -3,9 +3,9 @@ This patch makes it possible to switch focus with one single shortcut (alt-s) instead of having to think if you should use alt-j or alt-k for reaching the last used window. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:13 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:42 2012 +0200 @@ -224,6 +224,7 @@ static void showhide(Client *c); static void sigchld(int unused); @@ -22,19 +22,22 @@ diff -r ad90e7fab364 dwm.c static const char broken[] = "broken"; static char stext[256]; static int screen; -@@ -926,6 +928,11 @@ - return atom; +@@ -1675,6 +1677,14 @@ } -+void + void +swapfocus(){ -+ focus(prevclient); ++ Client *c; ++ for(c = selmon->clients; c && c != prevclient; c = c->next) ; ++ if(c == prevclient) ++ focus(prevclient); +} + - unsigned long - getcolor(const char *colstr) { - Colormap cmap = DefaultColormap(dpy, screen); -@@ -1776,6 +1783,7 @@ ++void + tag(const Arg *arg) { + if(selmon->sel && arg->ui & TAGMASK) { + selmon->sel->tags = arg->ui & TAGMASK; +@@ -1775,6 +1785,7 @@ unfocus(Client *c, Bool setfocus) { if(!c) return; @@ -42,7 +45,7 @@ diff -r ad90e7fab364 dwm.c grabbuttons(c, False); XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); if(setfocus) -@@ -2119,6 +2127,7 @@ +@@ -2116,6 +2127,7 @@ void zoom(const Arg *arg) { Client *c = selmon->sel; diff --git a/dwm.suckless.org/patches/dwm-6.0-systray.diff b/dwm.suckless.org/patches/dwm-6.0-systray.diff @@ -1,45 +1,27 @@ -diff -rupN dwm-6.0/config.def.h dwm/config.def.h ---- dwm-6.0/config.def.h 2011-12-19 09:02:46.000000000 -0600 -+++ dwm/config.def.h 2012-04-04 22:04:37.895074163 -0500 -@@ -1,17 +1,19 @@ - /* See LICENSE file for copyright and license details. */ +Author: Jan Christoph Ebersbach <jceb@e-jc.de>, inspired by http://code.google.com/p/dwm-plus +URL: http://dwm.suckless.org/patches/systray +Implements a system tray for dwm. + +diff -r ec4baab78314 config.def.h +--- a/config.def.h Mon Dec 19 15:38:30 2011 +0100 ++++ b/config.def.h Fri Apr 06 08:25:40 2012 +0200 +@@ -10,6 +10,8 @@ + static const char selfgcolor[] = "#eeeeee"; + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const Bool showsystray = True; /* False means no systray */ + static const Bool showbar = True; /* False means no bar */ + static const Bool topbar = True; /* False means bottom bar */ - /* appearance */ --static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; --static const char normbordercolor[] = "#444444"; --static const char normbgcolor[] = "#222222"; --static const char normfgcolor[] = "#bbbbbb"; --static const char selbordercolor[] = "#005577"; --static const char selbgcolor[] = "#005577"; --static const char selfgcolor[] = "#eeeeee"; --static const unsigned int borderpx = 1; /* border pixel of windows */ --static const unsigned int snap = 32; /* snap pixel */ --static const Bool showbar = True; /* False means no bar */ --static const Bool topbar = True; /* False means bottom bar */ -+static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -+static const char normbordercolor[] = "#444444"; -+static const char normbgcolor[] = "#222222"; -+static const char normfgcolor[] = "#bbbbbb"; -+static const char selbordercolor[] = "#005577"; -+static const char selbgcolor[] = "#005577"; -+static const char selfgcolor[] = "#eeeeee"; -+static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int systrayspacing = 2; /* systray spacing */ -+static const Bool showsystray = True; -+static const unsigned int snap = 32; /* snap pixel */ -+static const Bool showbar = True; /* False means no bar */ -+static const Bool topbar = True; /* False means bottom bar */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -diff -rupN dwm-6.0/dwm.c dwm/dwm.c ---- dwm-6.0/dwm.c 2011-12-19 09:02:46.000000000 -0600 -+++ dwm/dwm.c 2012-04-04 22:02:49.605076986 -0500 -@@ -54,13 +54,30 @@ - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:25:40 2012 +0200 +@@ -55,12 +55,30 @@ #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) -+#define SYSTEM_TRAY_REQUEST_DOCK 0 + ++#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 + +/* XEMBED messages */ @@ -55,7 +37,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR - ++ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ @@ -64,12 +46,12 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ +enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, + NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, -+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++ NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ +enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -@@ -154,6 +171,12 @@ typedef struct { +@@ -154,6 +172,12 @@ int monitor; } Rule; @@ -82,7 +64,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c /* function declarations */ static void applyrules(Client *c); static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); -@@ -186,9 +209,11 @@ static void focus(Client *c); +@@ -186,9 +210,11 @@ static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -94,7 +76,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, Bool focused); static void grabkeys(void); -@@ -207,13 +232,16 @@ static void pop(Client *); +@@ -207,13 +233,16 @@ static void propertynotify(XEvent *e); static void quit(const Arg *arg); static Monitor *recttomon(int x, int y, int w, int h); @@ -112,7 +94,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); -@@ -241,18 +269,24 @@ static void updatebars(void); +@@ -241,18 +270,24 @@ static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); @@ -137,7 +119,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c static const char broken[] = "broken"; static char stext[256]; static int screen; -@@ -274,9 +308,10 @@ static void (*handler[LASTEvent]) (XEven +@@ -274,9 +309,10 @@ [MapRequest] = maprequest, [MotionNotify] = motionnotify, [PropertyNotify] = propertynotify, @@ -149,7 +131,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c static Bool running = True; static Cursor cursor[CurLast]; static Display *dpy; -@@ -497,6 +532,11 @@ cleanup(void) { +@@ -497,6 +533,11 @@ XFreeCursor(dpy, cursor[CurMove]); while(mons) cleanupmon(mons); @@ -161,7 +143,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c XSync(dpy, False); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); } -@@ -530,9 +570,48 @@ clearurgent(Client *c) { +@@ -530,9 +571,48 @@ void clientmessage(XEvent *e) { @@ -210,7 +192,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c if(!c) return; if(cme->message_type == netatom[NetWMState]) { -@@ -583,7 +662,7 @@ configurenotify(XEvent *e) { +@@ -583,7 +663,7 @@ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); updatebars(); for(m = mons; m; m = m->next) @@ -219,7 +201,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c focus(NULL); arrange(NULL); } -@@ -667,6 +746,11 @@ destroynotify(XEvent *e) { +@@ -667,6 +747,11 @@ if((c = wintoclient(ev->window))) unmanage(c, True); @@ -231,7 +213,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c } void -@@ -722,6 +806,7 @@ drawbar(Monitor *m) { +@@ -722,6 +807,7 @@ unsigned long *col; Client *c; @@ -239,7 +221,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c for(c = m->clients; c; c = c->next) { occ |= c->tags; if(c->isurgent) -@@ -743,6 +828,9 @@ drawbar(Monitor *m) { +@@ -743,6 +829,9 @@ if(m == selmon) { /* status is only drawn on selected monitor */ dc.w = TEXTW(stext); dc.x = m->ww - dc.w; @@ -249,7 +231,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c if(dc.x < x) { dc.x = x; dc.w = m->ww - x; -@@ -771,6 +859,7 @@ drawbars(void) { +@@ -771,6 +860,7 @@ for(m = mons; m; m = m->next) drawbar(m); @@ -257,7 +239,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c } void -@@ -917,10 +1006,17 @@ getatomprop(Client *c, Atom prop) { +@@ -917,10 +1007,17 @@ unsigned long dl; unsigned char *p = NULL; Atom da, atom = None; @@ -276,7 +258,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c XFree(p); } return atom; -@@ -962,6 +1058,16 @@ getstate(Window w) { +@@ -962,6 +1059,15 @@ return result; } @@ -289,11 +271,10 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c + return w ? w + systrayspacing : 1; +} + -+ Bool gettextprop(Window w, Atom atom, char *text, unsigned int size) { char **list = NULL; -@@ -1096,7 +1202,7 @@ void +@@ -1096,7 +1202,7 @@ killclient(const Arg *arg) { if(!selmon->sel) return; @@ -302,7 +283,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); -@@ -1180,6 +1286,12 @@ void +@@ -1180,6 +1286,12 @@ maprequest(XEvent *e) { static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; @@ -315,7 +296,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c if(!XGetWindowAttributes(dpy, ev->window, &wa)) return; -@@ -1293,6 +1405,16 @@ propertynotify(XEvent *e) { +@@ -1293,6 +1405,16 @@ Window trans; XPropertyEvent *ev = &e->xproperty; @@ -332,7 +313,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c if((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if(ev->state == PropertyDelete) -@@ -1342,12 +1464,34 @@ recttomon(int x, int y, int w, int h) { +@@ -1342,12 +1464,33 @@ } void @@ -348,7 +329,6 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c +} + + -+ +void resize(Client *c, int x, int y, int w, int h, Bool interact) { if(applysizehints(c, &x, &y, &w, &h, interact)) @@ -367,7 +347,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; -@@ -1412,6 +1556,18 @@ resizemouse(const Arg *arg) { +@@ -1412,6 +1555,18 @@ } void @@ -386,7 +366,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c restack(Monitor *m) { Client *c; XEvent ev; -@@ -1495,25 +1651,35 @@ setclientstate(Client *c, long state) { +@@ -1495,25 +1650,35 @@ } Bool @@ -418,12 +398,12 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c ev.type = ClientMessage; - ev.xclient.window = c->win; - ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; ev.xclient.format = 32; - ev.xclient.data.l[0] = proto; - ev.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, c->win, False, NoEventMask, &ev); -+ ev.xclient.window = w; -+ ev.xclient.message_type = mt; + ev.xclient.data.l[0] = d0; + ev.xclient.data.l[1] = d1; + ev.xclient.data.l[2] = d2; @@ -433,7 +413,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c } return exists; } -@@ -1522,7 +1688,7 @@ void +@@ -1522,7 +1687,7 @@ setfocus(Client *c) { if(!c->neverfocus) XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); @@ -442,7 +422,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c } void -@@ -1602,11 +1768,17 @@ setup(void) { +@@ -1602,11 +1767,17 @@ wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); @@ -460,7 +440,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c /* init cursors */ cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); -@@ -1623,6 +1795,8 @@ setup(void) { +@@ -1623,6 +1794,8 @@ XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); @@ -469,7 +449,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c /* init bars */ updatebars(); updatestatus(); -@@ -1731,7 +1905,18 @@ void +@@ -1731,7 +1904,18 @@ togglebar(const Arg *arg) { selmon->showbar = !selmon->showbar; updatebarpos(selmon); @@ -489,7 +469,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c arrange(selmon); } -@@ -1816,10 +2001,16 @@ unmapnotify(XEvent *e) { +@@ -1816,18 +2000,28 @@ else unmanage(c, False); } @@ -504,9 +484,10 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c updatebars(void) { + unsigned int w; Monitor *m; ++ XSetWindowAttributes wa = { .override_redirect = True, -@@ -1827,7 +2018,10 @@ updatebars(void) { + .background_pixmap = ParentRelative, .event_mask = ButtonPressMask|ExposureMask }; for(m = mons; m; m = m->next) { @@ -518,7 +499,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]); -@@ -2011,6 +2205,104 @@ updatestatus(void) { +@@ -2011,6 +2205,104 @@ } void @@ -623,7 +604,7 @@ diff -rupN dwm-6.0/dwm.c dwm/dwm.c updatewindowtype(Client *c) { Atom state = getatomprop(c, netatom[NetWMState]); Atom wtype = getatomprop(c, netatom[NetWMWindowType]); -@@ -2080,6 +2372,16 @@ wintomon(Window w) { +@@ -2080,6 +2372,16 @@ return selmon; } diff --git a/dwm.suckless.org/patches/dwm-6.0-tagall.diff b/dwm.suckless.org/patches/dwm-6.0-tagall.diff @@ -2,9 +2,9 @@ Author: Jan Christoph Ebersbach <jceb@e-jc.de> URL: http://dwm.suckless.org/patches/historical/tagall Shortcut to move all (floating) windows from one tag to another. -diff -r ad90e7fab364 tagall.c +diff -r ec4baab78314 tagall.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/tagall.c Sat Mar 24 13:41:06 2012 +0100 ++++ b/tagall.c Fri Apr 06 08:23:21 2012 +0200 @@ -0,0 +1,24 @@ +void +tagall(const Arg *arg) { diff --git a/dwm.suckless.org/patches/dwm-6.0-zoomswap.diff b/dwm.suckless.org/patches/dwm-6.0-zoomswap.diff @@ -2,9 +2,9 @@ Author: Jan Christoph Ebersbach <jceb@e-jc.de> URL: http://dwm.suckless.org/patches/zoomswap This patch swaps the current window with the previous master when zooming. -diff -r ad90e7fab364 dwm.c ---- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sat Mar 24 13:41:14 2012 +0100 +diff -r ec4baab78314 dwm.c +--- a/dwm.c Mon Dec 19 15:38:30 2011 +0100 ++++ b/dwm.c Fri Apr 06 08:23:45 2012 +0200 @@ -253,6 +253,7 @@ static void zoom(const Arg *arg); @@ -13,7 +13,7 @@ diff -r ad90e7fab364 dwm.c static const char broken[] = "broken"; static char stext[256]; static int screen; -@@ -2119,14 +2120,32 @@ +@@ -2116,14 +2117,36 @@ void zoom(const Arg *arg) { Client *c = selmon->sel; @@ -22,14 +22,19 @@ diff -r ad90e7fab364 dwm.c if(!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)) return; - if(c == nexttiled(selmon->clients)) +- if(c == nexttiled(selmon->clients)) - if(!c || !(c = nexttiled(c->next))) - return; ++ if(c == nexttiled(selmon->clients)) { ++ for(tmp = selmon->clients; tmp && tmp != prevzoom; tmp = tmp->next) ; ++ if(tmp != prevzoom) ++ prevzoom = NULL; + if(!c || !(c = nexttiled(prevzoom))) { + c = selmon->sel; + if(!c || !(c = nexttiled(c->next))) + return; + } ++ } + for(at = selmon->clients; at && at->next && at != c && at->next != c; at = nexttiled(at->next)) ; pop(c); + /* swap windows instead of pushing the previous one down */ diff --git a/dwm.suckless.org/patches/float_border_color.md b/dwm.suckless.org/patches/float_border_color.md @@ -1,17 +1,15 @@ # float border color # ## Description ## - This patch allows you to specify a different border color for floating windows. ## Download ## Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). - * [dwm-6.0-float-border-color2.diff][1] + * [dwm-10e232f9ace7-float_border_color2.diff](dwm-10e232f9ace7-float_border_color2.diff) (3432b) (20120406) + * [dwm-6.0-float_border_color2.diff](dwm-6.0-float_border_color2.diff) (3356b) (20120406) ## Author ## * Message-ID: <20070626093131.GA5005@shota.mine.nu> * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> - -[1]: dwm-6.0-float_border_color2.diff diff --git a/dwm.suckless.org/patches/moveresize.md b/dwm.suckless.org/patches/moveresize.md @@ -3,13 +3,11 @@ moveresize Description ----------- - This changes allows you to move and resize dwm's clients using keyboard bindings. Usage ----- - 1. Put the following `moveresize()` function somewhere in your `dwm.c`, **after** the line which includes the config.h file: @@ -55,17 +53,20 @@ replace the `if()` statement above with this code: Multi-head ---------- -From dwm 6.0 onward there's the following patch which is aware of the screen sizes in a multi monitor setup. +From dwm 6.0 onward there's the following patch which is aware of the screen +sizes in a multi monitor setup. A second patch allows you to maximize windows. +Download +-------- Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-moveresize.diff][0] - -[0]: dwm-6.0-moveresize.diff + * [dwm-10e232f9ace7-moveresize.diff](dwm-10e232f9ace7-moveresize.diff) (2025b) (20120406) + * [dwm-10e232f9ace7-maximize_vert_horz.diff](dwm-10e232f9ace7-maximize_vert_horz.diff) (2385b) (20120406) + * [dwm-6.0-moveresize.diff](dwm-6.0-moveresize.diff) (2025b) (20120406) + * [dwm-6.0-maximize_vert_horz.diff](dwm-6.0-maximize_vert_horz.diff) (2385b) (20120406) Authors ------- - * Claudio M. Alessi - <smoppy@gmail.com> * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/noborder.md b/dwm.suckless.org/patches/noborder.md @@ -7,8 +7,12 @@ This patch removes the border when there is just one window visible in tiled or Download -------- -* [dwm-6.0-single_window_no_border.diff](dwm-6.0-single_window_no_border.diff) (2.8K) (20120214) +Patches against different versions of dwm are available at +[dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). + + * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) + * [dwm-6.0-single_window_no_border.diff](dwm-6.0-single_window_no_border.diff) (2865b) (20120406) Author ------ -* Jan Christoph Ebersbach - `<jceb at e-jc dot de>` + * Jan Christoph Ebersbach - `<jceb at e-jc dot de>` diff --git a/dwm.suckless.org/patches/pertag.md b/dwm.suckless.org/patches/pertag.md @@ -11,24 +11,25 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-pertag.diff][10] -* [dwm-r1578-pertag.diff][9] (nmaster included in mainline) -* [dwm-5.8.2-pertag\_without\_bar.diff][8] -* [dwm-5.8.2-pertag.diff][7] -* [dwm-5.7.2-pertag.diff][6] -* [dwm-pertag-5.6.1.diff][5] -* [dwm-5.4-pertag.diff][4] -* [dwm-5.2-pertag.diff][3] -* [dwm-5.1-pertag.diff][2] + * [dwm-10e232f9ace7-pertag.diff](dwm-10e232f9ace7-pertag.diff) (5955b) (20120406) + * [dwm-6.0-pertag.diff](dwm-6.0-pertag.diff) (5955b) (20120406) + * [dwm-r1578-pertag.diff][9] (nmaster included in mainline) + * [dwm-5.8.2-pertag\_without\_bar.diff][8] + * [dwm-5.8.2-pertag.diff][7] + * [dwm-5.7.2-pertag.diff][6] + * [dwm-pertag-5.6.1.diff][5] + * [dwm-5.4-pertag.diff][4] + * [dwm-5.2-pertag.diff][3] + * [dwm-5.1-pertag.diff][2] Authors ------- -* Jan Christoph Ebersbach - `<jceb at e-jc dot de>` -* Updated by V4hn - `v4hn.de` -* Updated by Jerome Andrieux - `<jerome at gcu dot info>` -* Updated by Sidney Amani - `<seed at uffs dot org>` -* Updated by William Light - `<wrl at illest dot net>` -* Updated by termac - `<terror.macbeth.I at gmail dot com>` + * Jan Christoph Ebersbach - <jceb@e-jc.de> + * Updated by V4hn - `v4hn.de` + * Updated by Jerome Andrieux - `<jerome at gcu dot info>` + * Updated by Sidney Amani - `<seed at uffs dot org>` + * Updated by William Light - `<wrl at illest dot net>` + * Updated by termac - `<terror.macbeth.I at gmail dot com>` [1]: historical/taglayouts [2]: http://v4hn.de/patches/dwm-5.1-pertag.diff @@ -39,4 +40,3 @@ Authors [7]: dwm-5.8.2-pertag.diff [8]: dwm-5.8.2-pertag_without_bar.diff [9]: dwm-r1578-pertag.diff -[10]: dwm-6.0-pertag.diff diff --git a/dwm.suckless.org/patches/push.md b/dwm.suckless.org/patches/push.md @@ -15,11 +15,16 @@ Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-push.diff](dwm-6.0-push.diff) (1.3K) (20120214) -* [push.c](push.c) (dwm 5.7.1) (20090927) -* [push-5.6.c](historical/push-5.6.c) (1K) (20090709) -* [push-5.3.c](historical/push-5.3.c) (1K) (20090124) + * [dwm-10e232f9ace7-push.diff](dwm-10e232f9ace7-push.diff) (1332b) (20120406) + * [dwm-6.0-push.diff](dwm-6.0-push.diff) (1332b) (20120406) + * [push.c](push.c) (dwm 5.7.1) (20090927) + * [push-5.6.c](historical/push-5.6.c) (1K) (20090709) + * [push-5.3.c](historical/push-5.3.c) (1K) (20090124) ## Note This patch seems to be equivalent to the [movestack](movestack) patch. + +## Author + * Unknown? + * Updated by Jan Christoph Ebersbach <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/save_floats.md b/dwm.suckless.org/patches/save_floats.md @@ -1,7 +1,6 @@ # save floats patch # ## Description ## - This patch saves size and position of every floating window before it is forced into tiled mode. If the window is made floating again, the old dimensions will be restored. @@ -10,10 +9,9 @@ be restored. Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). - * [dwm-6.0-save_floats.diff][1] + * [dwm-10e232f9ace7-save_floats.diff](dwm-10e232f9ace7-save_floats.diff) (1604b) (20120406) + * [dwm-6.0-save_floats.diff](dwm-6.0-save_floats.diff) (1528b) (20120406) ## Author ## * http://nymu.net/patches * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> - -[1]: dwm-6.0-save_floats.diff diff --git a/dwm.suckless.org/patches/single_tagset.md b/dwm.suckless.org/patches/single_tagset.md @@ -24,8 +24,8 @@ Please be aware that this patch probably breaks any other patch! Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). - * [dwm-6.0-single_tagset.diff](dwm-6.0-single_tagset.diff) (14K) (20120325) - + * [dwm-10e232f9ace7-single_tagset.diff](dwm-10e232f9ace7-single_tagset.diff) (14748b) (20120406) + * [dwm-6.0-single_tagset.diff](dwm-6.0-single_tagset.diff) (14417b) (20120406) Special Version --------------- @@ -43,7 +43,7 @@ This is a special version of the patch that was created with following patches b * [tagall](tagall) * [zoomswap](zoomswap) -[dwm-6.0-single_tagset_all.diff](dwm-6.0-single_tagset_all.diff) (18K) (20120325) +[dwm-6.0-single_tagset_all.diff](https://bitbucket.org/jceb81/dwm-patches/raw/cc88093b8acb/single_tagset_all.patch) Authors ------- diff --git a/dwm.suckless.org/patches/statusallmons.md b/dwm.suckless.org/patches/statusallmons.md @@ -10,9 +10,11 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-statusallmons.diff](dwm-6.0-statusallmons.diff) (1.0K) (20120214) -* [dwm-5.8.2-statusallmons.diff](dwm-5.8.2-statusallmons.diff) (4.0K) (20110318) + * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) + * [dwm-6.0-statusallmons.diff](dwm-6.0-statusallmons.diff) (982b) (20120406) + * [dwm-5.8.2-statusallmons.diff](dwm-5.8.2-statusallmons.diff) (4.0K) (20110318) Author ------ -* Pascal Wittmann - <mail@pascal-wittmann.de> + * Pascal Wittmann - <mail@pascal-wittmann.de> + * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/swapfocus.md b/dwm.suckless.org/patches/swapfocus.md @@ -1,17 +1,16 @@ # swap focus ## Description - This patch makes it possible to switch focus with one single shortcut (alt-s) instead of having to think if you should use alt-j or alt-k for reaching the last used window. ## Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). - * [dwm-6.0-swapfocus.diff](dwm-6.0-swapfocus.diff) (dwm 6.0) + * [dwm-10e232f9ace7-swapfocus.diff](dwm-10e232f9ace7-swapfocus.diff) (1484b) (20120406) + * [dwm-6.0-swapfocus.diff](dwm-6.0-swapfocus.diff) (1482b) (20120406) * [dwm-5.8.2-swap.diff](dwm-5.8.2-swap.diff) (dwm 5.8.2) ## Author - * Lasse Engblom - * Jan Christoph Ebersbach + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray.md @@ -11,8 +11,9 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (20K) (20120405) + * [dwm-10e232f9ace7-systray.diff](dwm-10e232f9ace7-systray.diff) (19946b) (20120406) + * [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (19788b) (20120406) Author ------ -* Jan Christoph Ebersbach - <jceb@e-jc.de> + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/tagall.md b/dwm.suckless.org/patches/tagall.md @@ -8,7 +8,8 @@ Shortcut to move all (floating) windows from one tag to another. Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). - * [dwm-6.0-tagall.diff][1] + * [dwm-10e232f9ace7-tagall.diff](dwm-10e232f9ace7-tagall.diff) (988b) (20120406) + * [dwm-6.0-tagall.diff](dwm-6.0-tagall.diff) (988b) (20120406) ## Configuration ## @@ -26,5 +27,3 @@ Patches against different versions of dwm are available at ## Author ## * Jan Christoph Ebersbach - <jceb@e-jc.de> - -[1]: dwm-6.0-tagall.diff diff --git a/dwm.suckless.org/patches/zoomswap.md b/dwm.suckless.org/patches/zoomswap.md @@ -43,8 +43,9 @@ Download Patches against different versions of dwm are available at [dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). -* [dwm-6.0-zoomswap.diff](dwm-6.0-zoomswap.diff) (1.4K) (20120214) + * [dwm-10e232f9ace7-attachabove.diff](dwm-10e232f9ace7-attachabove.diff) (1.7K) (20120406) + * [dwm-6.0-zoomswap.diff](dwm-6.0-zoomswap.diff) (1.6K) (20120406) Author ------ -* Jan Christoph Ebersbach - `<jceb at e-jc dot de>` + * Jan Christoph Ebersbach - `<jceb at e-jc dot de>`