commit 556f2aae56b5862dbd1194abd184b39d55b667ed parent 0ad093d1523cb7cd5d5761fd0602e48e3b4b5640 Author: Laslo Hunhold <dev@frign.de> Date: Sun, 5 Nov 2017 01:45:15 +0100 Tidy up dwm patch section into subdirectories Diffstat:
413 files changed, 6683 insertions(+), 13853 deletions(-)
diff --git a/dwm.suckless.org/patches/dwm-alpha-6.1.diff b/dwm.suckless.org/patches/alpha/dwm-alpha-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-alpha.png b/dwm.suckless.org/patches/alpha/dwm-alpha.png Binary files differ. diff --git a/dwm.suckless.org/patches/alpha.md b/dwm.suckless.org/patches/alpha/index.md diff --git a/dwm.suckless.org/patches/dwm-alwaysfullscreen-20160713-56a31dc.diff b/dwm.suckless.org/patches/alwaysfullscreen/dwm-alwaysfullscreen-20160713-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-alwaysfullscreen-6.1.diff b/dwm.suckless.org/patches/alwaysfullscreen/dwm-alwaysfullscreen-6.1.diff diff --git a/dwm.suckless.org/patches/alwaysfullscreen.md b/dwm.suckless.org/patches/alwaysfullscreen/index.md diff --git a/dwm.suckless.org/patches/dwm-attachabove-20160713-56a31dc.diff b/dwm.suckless.org/patches/attachabove/dwm-attachabove-20160713-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-attachabove-6.0.diff b/dwm.suckless.org/patches/attachabove/dwm-attachabove-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-attachabove-6.1.diff b/dwm.suckless.org/patches/attachabove/dwm-attachabove-6.1.diff diff --git a/dwm.suckless.org/patches/attachabove.md b/dwm.suckless.org/patches/attachabove/index.md diff --git a/dwm.suckless.org/patches/dwm-attachaside-20160718-56a31dc.diff b/dwm.suckless.org/patches/attachaside/dwm-attachaside-20160718-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-attachaside-6.1.diff b/dwm.suckless.org/patches/attachaside/dwm-attachaside-6.1.diff diff --git a/dwm.suckless.org/patches/attachaside.md b/dwm.suckless.org/patches/attachaside/index.md diff --git a/dwm.suckless.org/patches/dwm-autoresize-20160718-56a31dc.diff b/dwm.suckless.org/patches/autoresize/dwm-autoresize-20160718-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-autoresize-6.0.diff b/dwm.suckless.org/patches/autoresize/dwm-autoresize-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-autoresize-6.1.diff b/dwm.suckless.org/patches/autoresize/dwm-autoresize-6.1.diff diff --git a/dwm.suckless.org/patches/autoresize.md b/dwm.suckless.org/patches/autoresize/index.md diff --git a/dwm.suckless.org/patches/dwm-autostart-20161205-bb3bd6f.diff b/dwm.suckless.org/patches/autostart/dwm-autostart-20161205-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/autostart.md b/dwm.suckless.org/patches/autostart/index.md diff --git a/dwm.suckless.org/patches/dwm-bottomstack-20160719-56a31dc.diff b/dwm.suckless.org/patches/bottomstack/dwm-bottomstack-20160719-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-bottomstack-6.1.diff b/dwm.suckless.org/patches/bottomstack/dwm-bottomstack-6.1.diff diff --git a/dwm.suckless.org/patches/bottomstack.md b/dwm.suckless.org/patches/bottomstack/index.md diff --git a/dwm.suckless.org/patches/dwm-center-20160719-56a31dc.diff b/dwm.suckless.org/patches/center/dwm-center-20160719-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-center-6.1.diff b/dwm.suckless.org/patches/center/dwm-center-6.1.diff diff --git a/dwm.suckless.org/patches/center.md b/dwm.suckless.org/patches/center/index.md diff --git a/dwm.suckless.org/patches/dwm-centeredmaster-20160719-56a31dc.diff b/dwm.suckless.org/patches/centeredmaster/dwm-centeredmaster-20160719-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-centeredmaster-6.1.diff b/dwm.suckless.org/patches/centeredmaster/dwm-centeredmaster-6.1.diff diff --git a/dwm.suckless.org/patches/centeredmaster.md b/dwm.suckless.org/patches/centeredmaster/index.md diff --git a/dwm.suckless.org/patches/cfacts.md b/dwm.suckless.org/patches/cfacts.md @@ -1,56 +0,0 @@ -cfacts -====== - -Description ------------ - -This patch provides the ability to assign different weights to -clients in their respective stack in tiled layout. It implements -a new function setcfact which will modify the cfact-value for the -currently selected client. It accepts the following values: - -* A positive float to increase a clients weight, thus increasing - the space the client is allocated in its current stack. - -* A negative float to decrease a clients weight, thus decreasing - the space the client is allocated in its current stack. - -* A zero-value float to reset a clients weight to default. - -Default cfact-value for each client is 1.0. If a client is -assigned a cfact value of 0.5 it will be allocated half of the -space other clients would be allocated. If a client is assigned a -cfact value of 2.0 it will be allocated twice the space other -clients would be allocated. - -The following illustrates the behavior. The clients cfact-values -are represented by floats inside the clients rectangles. - - +---------------------+ - | | 0.5 | - | 1.0 +----------+ - +----------+ | - | | 1.0 | - | +----------+ - | 2.0 | | - | | 1.0 | - +----------+----------+ - -Default key bindings --------------------- - - Key | Argument | Description -:---------:|:----------:|:---------------- - `Mod-H` | `+0.25` | Increase cfact - `Mod-L` | `-0.25` | Decrease cfact - `Mod-O` | ` 0.00` | Reset cfact - -Download --------- - -* [dwm-6.1-cfacts.diff](dwm-6.1-cfacts.diff) - -Author ------- - -* Patrick Steinhardt (pks) <ps@pks.im> diff --git a/dwm.suckless.org/patches/dwm-6.1-cfacts.diff b/dwm.suckless.org/patches/cfacts/dwm-cfacts-6.1.diff diff --git a/dwm.suckless.org/patches/cfacts/index.md b/dwm.suckless.org/patches/cfacts/index.md @@ -0,0 +1,56 @@ +cfacts +====== + +Description +----------- + +This patch provides the ability to assign different weights to +clients in their respective stack in tiled layout. It implements +a new function setcfact which will modify the cfact-value for the +currently selected client. It accepts the following values: + +* A positive float to increase a clients weight, thus increasing + the space the client is allocated in its current stack. + +* A negative float to decrease a clients weight, thus decreasing + the space the client is allocated in its current stack. + +* A zero-value float to reset a clients weight to default. + +Default cfact-value for each client is 1.0. If a client is +assigned a cfact value of 0.5 it will be allocated half of the +space other clients would be allocated. If a client is assigned a +cfact value of 2.0 it will be allocated twice the space other +clients would be allocated. + +The following illustrates the behavior. The clients cfact-values +are represented by floats inside the clients rectangles. + + +---------------------+ + | | 0.5 | + | 1.0 +----------+ + +----------+ | + | | 1.0 | + | +----------+ + | 2.0 | | + | | 1.0 | + +----------+----------+ + +Default key bindings +-------------------- + + Key | Argument | Description +:---------:|:----------:|:---------------- + `Mod-H` | `+0.25` | Increase cfact + `Mod-L` | `-0.25` | Decrease cfact + `Mod-O` | ` 0.00` | Reset cfact + +Download +-------- + +* [dwm-cfacts-6.1.diff](dwm-cfacts-6.1.diff) + +Author +------ + +* Patrick Steinhardt (pks) <ps@pks.im> diff --git a/dwm.suckless.org/patches/dwm-clientspertag-5.6.1.diff b/dwm.suckless.org/patches/clientspertag/dwm-clientspertag-5.6.1.diff diff --git a/dwm.suckless.org/patches/clientspertag.md b/dwm.suckless.org/patches/clientspertag/index.md diff --git a/dwm.suckless.org/patches/dwm-columns-6.0.diff b/dwm.suckless.org/patches/columns/dwm-columns-6.0.diff diff --git a/dwm.suckless.org/patches/columns.md b/dwm.suckless.org/patches/columns/index.md diff --git a/dwm.suckless.org/patches/dwm-combo-5.9.diff b/dwm.suckless.org/patches/combo/dwm-combo-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-combo-6.0.diff b/dwm.suckless.org/patches/combo/dwm-combo-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-combo-6.1.diff b/dwm.suckless.org/patches/combo/dwm-combo-6.1.diff diff --git a/dwm.suckless.org/patches/combo.md b/dwm.suckless.org/patches/combo/index.md diff --git a/dwm.suckless.org/patches/dwm-cropwindows-20170709-ceac8c9.diff b/dwm.suckless.org/patches/cropwindows/dwm-cropwindows-20170709-ceac8c9.diff diff --git a/dwm.suckless.org/patches/cropwindows.md b/dwm.suckless.org/patches/cropwindows/index.md diff --git a/dwm.suckless.org/patches/dwm-current_desktop-5.8.2.diff b/dwm.suckless.org/patches/current_desktop/dwm-current_desktop-5.8.2.diff diff --git a/dwm.suckless.org/patches/current_desktop.md b/dwm.suckless.org/patches/current_desktop/index.md diff --git a/dwm.suckless.org/patches/deck.md b/dwm.suckless.org/patches/deck.md @@ -1,40 +0,0 @@ -deck layout -=========== - -Description ------------ -`deck` is a new layout for DWM (inspired by the TTWM window manager). It is like tile(), but with monocle in the stack. You have a master client (complete with nmaster et all), but the stack clients now overlap one another as in monocle(). (The stacked clients are like a deck of cards, hence the name). - - - Tile : - +-----------------+--------+ - | | | - | | S1 | - | | | - | M +--------+ - | | | - | | S2 | - | | | - +-----------------+--------+ - - - Deck : - +-----------------+--------+ - | | | - | | | - | | | - | M | S1 | - | | | - | | | - | | | - +-----------------+--------+ - -Download --------- -* [dwm-6.0-deck.diff](dwm-6.0-deck.diff) -* [dwm-deck-20170909-ceac8c9.diff](dwm-deck-20170909-ceac8c9.diff) - - -Author ------- -* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/dwm-deck-20170909-ceac8c9.diff b/dwm.suckless.org/patches/deck/dwm-deck-20170909-ceac8c9.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-deck.diff b/dwm.suckless.org/patches/deck/dwm-deck-6.0.diff diff --git a/dwm.suckless.org/patches/deck/index.md b/dwm.suckless.org/patches/deck/index.md @@ -0,0 +1,40 @@ +deck layout +=========== + +Description +----------- +`deck` is a new layout for DWM (inspired by the TTWM window manager). It is like tile(), but with monocle in the stack. You have a master client (complete with nmaster et all), but the stack clients now overlap one another as in monocle(). (The stacked clients are like a deck of cards, hence the name). + + + Tile : + +-----------------+--------+ + | | | + | | S1 | + | | | + | M +--------+ + | | | + | | S2 | + | | | + +-----------------+--------+ + + + Deck : + +-----------------+--------+ + | | | + | | | + | | | + | M | S1 | + | | | + | | | + | | | + +-----------------+--------+ + +Download +-------- +* [dwm-deck-6.0.diff](dwm-deck-6.0.diff) +* [dwm-deck-20170909-ceac8c9.diff](dwm-deck-20170909-ceac8c9.diff) + + +Author +------ +* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/defaulttransparency.md b/dwm.suckless.org/patches/defaulttransparency.md @@ -1,24 +0,0 @@ -# defaulttransparency - -## Description - -This patch adds a default transparency parameter to config.h, which specifies the -transparency, all windows are started with. - -Additionally it adds some shortcuts: - - * MOD + Shift + s -> decrease transparency of current focused window - * MOD + Shift + d -> increase transparency of current focused window - * MOD + Shift + f -> set window to default opacity (.75) - -It is based on the transparency patch of Stefan Mark. - -## Download - - * [dwm.defaultopacity.patch](//dwm.suckless.org/patches/dwm.defaultopacity.patch) - latest patch (against r1521) - -## Author - - * Christoph Lohmann - <20h@r-36.net> - diff --git a/dwm.suckless.org/patches/dwm.defaultopacity.patch b/dwm.suckless.org/patches/defaulttransparency/dwm-defaulttransparency-r1521.diff diff --git a/dwm.suckless.org/patches/defaulttransparency/index.md b/dwm.suckless.org/patches/defaulttransparency/index.md @@ -0,0 +1,24 @@ +# defaulttransparency + +## Description + +This patch adds a default transparency parameter to config.h, which specifies the +transparency, all windows are started with. + +Additionally it adds some shortcuts: + + * MOD + Shift + s -> decrease transparency of current focused window + * MOD + Shift + d -> increase transparency of current focused window + * MOD + Shift + f -> set window to default opacity (.75) + +It is based on the transparency patch of Stefan Mark. + +## Download + + * [dwm-defaulttransparency-r1521.diff](dwm-defaulttransparency-r1521.diff) + latest patch (against r1521) + +## Author + + * Christoph Lohmann - <20h@r-36.net> + diff --git a/dwm.suckless.org/patches/dwm-dualstatus-6.0.diff b/dwm.suckless.org/patches/dualstatus/dwm-dualstatus-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-dualstatus-6.1.diff b/dwm.suckless.org/patches/dualstatus/dwm-dualstatus-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-dualstatus.png b/dwm.suckless.org/patches/dualstatus/dwm-dualstatus.png Binary files differ. diff --git a/dwm.suckless.org/patches/dualstatus.md b/dwm.suckless.org/patches/dualstatus/index.md diff --git a/dwm.suckless.org/patches/dwm-dwmfifo-6.1.diff b/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-6.1.diff diff --git a/dwm.suckless.org/patches/dwmfifo.md b/dwm.suckless.org/patches/dwmfifo/index.md diff --git a/dwm.suckless.org/patches/dwm-emptyview-6.0.diff b/dwm.suckless.org/patches/emptyview/dwm-emptyview-6.0.diff diff --git a/dwm.suckless.org/patches/emptyview.md b/dwm.suckless.org/patches/emptyview/index.md diff --git a/dwm.suckless.org/patches/exresize.md b/dwm.suckless.org/patches/exresize.md @@ -1,26 +0,0 @@ -exresize -======== - -Description ------------ - -This allows the user to change size and placement of floating windows using only -the keyboard. It also allows for temporary vertical and horizontal extension of -windows similar to other WMs fill command. This patch is inspired by -[maximize](//dwm.suckless.org/patches/maximize) and -[moveresize](//dwm.suckless.org/patches/moveresize) but fixes a lot of -problems I had with those patches. It also includes the functionality of -[save floats](//dwm.suckless.org/patches/save_floats) judging by it's -description. - -Download --------- - -<!-- This patch used to say (20121117), but it doesn't build against commits - from that date. Author emailed. --> - * [dwm-r1606-exresize.diff](dwm-r1606-exresize.diff) (Old patch, unknown version) - -Authors -------- - - * Krister Svanlund - `<krister.svanlund@gmail.com>` diff --git a/dwm.suckless.org/patches/dwm-r1606-exresize.diff b/dwm.suckless.org/patches/exresize/dwm-exresize-r1606.diff diff --git a/dwm.suckless.org/patches/exresize/index.md b/dwm.suckless.org/patches/exresize/index.md @@ -0,0 +1,26 @@ +exresize +======== + +Description +----------- + +This allows the user to change size and placement of floating windows using only +the keyboard. It also allows for temporary vertical and horizontal extension of +windows similar to other WMs fill command. This patch is inspired by +[maximize](//dwm.suckless.org/patches/maximize) and +[moveresize](//dwm.suckless.org/patches/moveresize) but fixes a lot of +problems I had with those patches. It also includes the functionality of +[save floats](//dwm.suckless.org/patches/save_floats) judging by it's +description. + +Download +-------- + +<!-- This patch used to say (20121117), but it doesn't build against commits + from that date. Author emailed. --> + * [dwm-exresize-r1606.diff](dwm-exresize-r1606.diff) (Old patch, unknown version) + +Authors +------- + + * Krister Svanlund - `<krister.svanlund@gmail.com>` diff --git a/dwm.suckless.org/patches/dwm-fakefullscreen-20170508-ceac8c9.diff b/dwm.suckless.org/patches/fakefullscreen/dwm-fakefullscreen-20170508-ceac8c9.diff diff --git a/dwm.suckless.org/patches/fakefullscreen.md b/dwm.suckless.org/patches/fakefullscreen/index.md diff --git a/dwm.suckless.org/patches/fancybar.md b/dwm.suckless.org/patches/fancybar.md @@ -1,26 +0,0 @@ -# fancybar - -## Description - -This patch provides a status bar that shows the titles of all visible windows -(as opposed to showing just the selected one). When the titles don't completely -fit, they're cropped. The title of the selected window is inverted. - -[![Fancybar][1]][1] - -*Fancybar in action* - -## Download - - * [dwm-fancybar-5.6.1.diff](historical/dwm-fancybar-5.6.1.diff) - * [dwm-fancybar-6.1.diff](dwm-fancybar-6.1.diff) - * [dwm-fancybar-git-20160725-7af4d43.diff](dwm-fancybar-git-20160725-7af4d43.diff) - -## Author - - * Mate Nagy - <mnagy@port70.net> - * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (rewrite) - -This patch was inspired by the decorated tabbed layout of Xmonad. - -[1]: http://s27.postimg.org/nvlkivn03/2015_10_14_132203_727x15_scrot.png diff --git a/dwm.suckless.org/patches/fancybar/dwm-fancybar-5.6.1.diff b/dwm.suckless.org/patches/fancybar/dwm-fancybar-5.6.1.diff @@ -0,0 +1,121 @@ +diff -r e47a47bd3ed4 dwm.c +--- a/dwm.c Tue Jul 21 10:57:54 2009 +0100 ++++ b/dwm.c Mon Aug 24 18:28:57 2009 +0200 +@@ -169,6 +169,7 @@ + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); ++static void drawvline(unsigned long col[ColLast]); + static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); + static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); + static void enternotify(XEvent *e); +@@ -648,10 +649,11 @@ + + void + drawbar(Monitor *m) { +- int x; ++ int x, ow, mw = 0, extra, tw; + unsigned int i, n = 0, occ = 0, urg = 0; + unsigned long *col; +- Client *c; ++ Client *c, *firstvis, *lastvis = NULL; ++ DC seldc; + + for(c = m->clients; c; c = c->next) { + if(ISVISIBLE(c)) +@@ -689,16 +691,62 @@ + } + else + dc.x = m->ww; +- if((dc.w = dc.x - x) > bh) { +- dc.x = x; +- if(m->sel) { +- col = m == selmon ? dc.sel : dc.norm; +- drawtext(m->sel->name, col, False); +- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); ++ ++ for(c = m->clients; c && !ISVISIBLE(c); c = c->next); ++ firstvis = c; ++ ++ col = m == selmon ? dc.sel : dc.norm; ++ dc.w = dc.x - x; ++ dc.x = x; ++ ++ if(n > 0) { ++ mw = dc.w / n; ++ extra = 0; ++ seldc = dc; ++ i = 0; ++ ++ while(c) { ++ lastvis = c; ++ tw = TEXTW(c->name); ++ if(tw < mw) extra += (mw - tw); else i++; ++ for(c = c->next; c && !ISVISIBLE(c); c = c->next); + } +- else ++ ++ if(i > 0) mw += extra / i; ++ ++ c = firstvis; ++ x = dc.x; ++ } ++ ++ while(dc.w > bh) { ++ if(c) { ++ ow = dc.w; ++ tw = TEXTW(c->name); ++ dc.w = MIN(ow, tw); ++ ++ if(dc.w > mw) dc.w = mw; ++ if(m->sel == c) seldc = dc; ++ if(c == lastvis) dc.w = ow; ++ ++ drawtext(c->name, col, False); ++ if(c != firstvis) drawvline(col); ++ drawsquare(c->isfixed, c->isfloating, False, col); ++ ++ dc.x += dc.w; ++ dc.w = ow - dc.w; ++ for(c = c->next; c && !ISVISIBLE(c); c = c->next); ++ } else { + drawtext(NULL, dc.norm, False); ++ break; ++ } + } ++ ++ if(m == selmon && m->sel && ISVISIBLE(m->sel)) { ++ dc = seldc; ++ drawtext(m->sel->name, col, True); ++ drawsquare(m->sel->isfixed, m->sel->isfloating, True, col); ++ } ++ + XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); + XSync(dpy, False); + } +@@ -709,6 +757,15 @@ + + for(m = mons; m; m = m->next) + drawbar(m); ++} ++ ++void ++drawvline(unsigned long col[ColLast]) { ++ XGCValues gcv; ++ ++ gcv.foreground = col[ColFG]; ++ XChangeGC(dpy, dc.gc, GCForeground, &gcv); ++ XDrawLine(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.x, dc.y + (dc.font.ascent + dc.font.descent + 2)); + } + + void +@@ -1235,8 +1292,7 @@ + } + if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { + updatetitle(c); +- if(c == selmon->sel) +- drawbars(); ++ drawbars(); + } + } + } diff --git a/dwm.suckless.org/patches/dwm-fancybar-6.1.diff b/dwm.suckless.org/patches/fancybar/dwm-fancybar-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-fancybar-git-20160725-7af4d43.diff b/dwm.suckless.org/patches/fancybar/dwm-fancybar-git-20160725-7af4d43.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-winview.diff b/dwm.suckless.org/patches/fancybar/fancybar.png diff --git a/dwm.suckless.org/patches/fancybar/index.md b/dwm.suckless.org/patches/fancybar/index.md @@ -0,0 +1,24 @@ +# fancybar + +## Description + +This patch provides a status bar that shows the titles of all visible windows +(as opposed to showing just the selected one). When the titles don't completely +fit, they're cropped. The title of the selected window is inverted. + +[![Screenshot][fancybar.png]][fancybar.png] + +*Fancybar in action* + +## Download + + * [dwm-fancybar-5.6.1.diff](dwm-fancybar-5.6.1.diff) + * [dwm-fancybar-6.1.diff](dwm-fancybar-6.1.diff) + * [dwm-fancybar-git-20160725-7af4d43.diff](dwm-fancybar-git-20160725-7af4d43.diff) + +## Author + + * Mate Nagy - <mnagy@port70.net> + * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (rewrite) + +This patch was inspired by the decorated tabbed layout of Xmonad. diff --git a/dwm.suckless.org/patches/fancybarclickable.md b/dwm.suckless.org/patches/fancybarclickable.md @@ -1,24 +0,0 @@ -fancybarclickable -================= - -Description ------------ -`fancybarclickable` is basically [fancycoloredbarclickable](fancycoloredbarclickable) -minus the [statuscolors](statuscolors). It uses the dwm bar to show you the -titles of all the windows in the current tag and lets you select windows by -selecting their title in the dwm bar. - -[![Fancybarclickable][1]][1] - -Download --------- -* [dwm-6.1-fancybarclickable.diff](dwm-6.1-fancybarclickable.diff) (Unclean patch) - -Authors -------- -* Stefan Mark wrote [fancycoloredbarclickable](fancycoloredbarclickable.md). -* Mate Nagy wrote [fancybar](fancybar.md). -* An anonymous Canadian updated the fancybar patch and added the - `selectby-click-on-title` function from fancycoloredbarclickable to it. - -[1]: http://s4.postimg.org/ql2f934wd/fancybar.png diff --git a/dwm.suckless.org/patches/dwm-6.1-fancybarclickable.diff b/dwm.suckless.org/patches/fancybarclickable/dwm-fancybarclickable-6.1.diff diff --git a/dwm.suckless.org/patches/fancybarclickable/fancybarclickable.png b/dwm.suckless.org/patches/fancybarclickable/fancybarclickable.png Binary files differ. diff --git a/dwm.suckless.org/patches/fancybarclickable/index.md b/dwm.suckless.org/patches/fancybarclickable/index.md @@ -0,0 +1,21 @@ +fancybarclickable +================= + +Description +----------- +`fancybarclickable` is basically [fancycoloredbarclickable](fancycoloredbarclickable) +minus the [statuscolors](statuscolors). It uses the dwm bar to show you the +titles of all the windows in the current tag and lets you select windows by +selecting their title in the dwm bar. + +[![Screenshot][fancybarclickable.png]][fancybarclickable.png] + +Download +-------- +* [dwm-fancybarclickable-6.1.diff](dwm-fancybarclickable-6.1.diff) (Unclean patch) + +Authors +------- +* Mate Nagy wrote [fancybar](../fancybar/). +* An anonymous Canadian updated the fancybar patch and added the + `selectby-click-on-title` function from fancycoloredbarclickable to it. diff --git a/dwm.suckless.org/patches/fancycoloredbarclickable.md b/dwm.suckless.org/patches/fancycoloredbarclickable.md @@ -1,33 +0,0 @@ -fancycoloredbarclickable -======================== - -Description ------------ -`fancycoloredbarclickable` provides colors in the status area, shows the -titles of all visible clients, and provides a function to select a client by -clicking on its title. - -This patch combines [fancybar](fancybar) and [statuscolors](statuscolors) with -the additional `selectby-click-on-title` function. - -The fancybar patch used is rather new and unchanged, while the statuscolor -patch is older and modified. The original statuscolor patch made gaps after -changing the color and used its own color definition everywhere. This modified -version creates no gaps and the default color definition is used everywhere -but in the status area. - -[dwmd][2] is an extensible status script with color support. - -Download --------- -* [dwm-fancycoloredbarclickable.diff][1] - -Gluer ------ -...for this is a patch of patches; I'm not really the author, but the one who -glued things together. ;) - -* Stefan Mark - <0mark@unserver.de> - -[1]: https://svn.0mark.unserver.de/dwm/trunk/patches/dwm-fancycoloredbarclickable.diff -[2]: http://0mark.unserver.de/dwmd diff --git a/dwm.suckless.org/patches/dwm-fibonacci-5.8.2.diff b/dwm.suckless.org/patches/fibonacci/dwm-fibonacci-5.8.2.diff diff --git a/dwm.suckless.org/patches/fibonacci.md b/dwm.suckless.org/patches/fibonacci/index.md diff --git a/dwm.suckless.org/patches/flextile/dwm-flextile-5.8.1.diff b/dwm.suckless.org/patches/flextile/dwm-flextile-5.8.1.diff @@ -0,0 +1,418 @@ +diff -up ../dwm-5.8.1-0/config.def.h ./config.def.h +--- ../dwm-5.8.1-0/config.def.h 2010-05-29 13:49:12.000000000 +0200 ++++ ./config.def.h 2010-05-31 15:18:43.686311000 +0200 +@@ -25,6 +25,11 @@ static const Rule rules[] = { + /* layout(s) */ + static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ + static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ ++static const int layoutaxis[] = { ++ 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ ++ 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ ++ 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ ++}; + + static const Layout layouts[] = { + /* symbol arrange function */ +@@ -81,6 +86,12 @@ static Key keys[] = { + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0} }, /* 0 = layout axis */ ++ { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1} }, /* 1 = master axis */ ++ { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2} }, /* 2 = stack axis */ ++ { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, ++ { MODKEY|ControlMask, XK_j, shiftmastersplit, {.i = -1} }, /* reduce the number of tiled clients in the master area */ ++ { MODKEY|ControlMask, XK_k, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ + }; + + /* button definitions */ +diff -up ../dwm-5.8.1-0/dwm.c ./dwm.c +--- ../dwm-5.8.1-0/dwm.c 2010-05-29 13:49:12.000000000 +0200 ++++ ./dwm.c 2010-05-31 16:02:14.553316000 +0200 +@@ -120,26 +120,6 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + +-struct Monitor { +- char ltsymbol[16]; +- float mfact; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +-}; +- + typedef struct { + const char *class; + const char *instance; +@@ -193,6 +173,7 @@ static void killclient(const Arg *arg); + static void manage(Window w, XWindowAttributes *wa); + static void mappingnotify(XEvent *e); + static void maprequest(XEvent *e); ++static void mirrorlayout(const Arg *arg); + static void monocle(Monitor *m); + static void movemouse(const Arg *arg); + static Client *nexttiled(Client *c); +@@ -202,6 +183,7 @@ static void quit(const Arg *arg); + static void resize(Client *c, int x, int y, int w, int h, Bool interact); + static void resizemouse(const Arg *arg); + static void restack(Monitor *m); ++static void rotatelayoutaxis(const Arg *arg); + static void run(void); + static void scan(void); + static void sendmon(Client *c, Monitor *m); +@@ -209,6 +191,7 @@ static void setclientstate(Client *c, lo + static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); ++static void shiftmastersplit(const Arg *arg); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); +@@ -275,6 +258,34 @@ static Window root; + + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; ++struct Monitor { ++ char ltsymbol[16]; ++ float mfact; ++ double mfacts[LENGTH(tags) + 1]; ++ int ltaxis[3]; ++ int ltaxes[LENGTH(tags) + 1][3]; ++ int num; ++ int curtag; ++ int prevtag; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int msplit; ++ unsigned int msplits[LENGTH(tags) + 1]; ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool showbars[LENGTH(tags) + 1]; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++ const Layout *lts[LENGTH(tags) + 1]; ++}; + + /* function implementations */ + void +@@ -616,6 +627,10 @@ createmon(void) { + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ m->ltaxis[0] = layoutaxis[0]; ++ m->ltaxis[1] = layoutaxis[1]; ++ m->ltaxis[2] = layoutaxis[2]; ++ m->msplit = 1; + return m; + } + +@@ -1173,6 +1188,15 @@ maprequest(XEvent *e) { + } + + void ++mirrorlayout(const Arg *arg) { ++ if(!selmon->lt[selmon->sellt]->arrange) ++ return; ++ selmon->ltaxis[0] *= -1; ++ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0]; ++ arrange(selmon); ++} ++ ++void + monocle(Monitor *m) { + unsigned int n = 0; + Client *c; +@@ -1387,6 +1411,21 @@ restack(Monitor *m) { + } + + void ++rotatelayoutaxis(const Arg *arg) { ++ if(!selmon->lt[selmon->sellt]->arrange) ++ return; ++ if(arg->i == 0) { ++ if(selmon->ltaxis[0] > 0) ++ selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 2 ? 1 : selmon->ltaxis[0] + 1; ++ else ++ selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -2 ? -1 : selmon->ltaxis[0] - 1; ++ } else ++ selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 3 ? 1 : selmon->ltaxis[arg->i] + 1; ++ selmon->ltaxes[selmon->curtag][arg->i] = selmon->ltaxis[arg->i]; ++ arrange(selmon); ++} ++ ++void + run(void) { + XEvent ev; + /* main event loop */ +@@ -1451,7 +1490,7 @@ setlayout(const Arg *arg) { + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1469,14 +1508,16 @@ setmfact(const Arg *arg) { + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->mfacts[selmon->curtag] = f; + arrange(selmon); + } + + void + setup(void) { + XSetWindowAttributes wa; +- ++ Monitor *m; ++ unsigned int i; ++ + /* clean up any zombies immediately */ + sigchld(0); + +@@ -1511,7 +1552,19 @@ setup(void) { + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); +- /* init bars */ ++ /* init tags, bars, layouts, axes, msplits and mfacts */ ++ for(m = mons; m; m = m->next) { ++ m->curtag = m->prevtag = 1; ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ m->showbars[i] = m->showbar; ++ m->lts[i] = &layouts[0]; ++ m->mfacts[i] = m->mfact; ++ m->ltaxes[i][0] = m->ltaxis[0]; ++ m->ltaxes[i][1] = m->ltaxis[1]; ++ m->ltaxes[i][2] = m->ltaxis[2]; ++ m->msplits[i] = m->msplit; ++ } ++ } + updatebars(); + updatestatus(); + /* EWMH support per view */ +@@ -1528,6 +1581,19 @@ setup(void) { + } + + void ++shiftmastersplit(const Arg *arg) { ++ unsigned int n; ++ Client *c; ++ ++ for(n = 0, c = nexttiled(selmon->clients); c; c = nexttiled(c->next), n++); ++ if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->msplit + arg->i < 1 || selmon->msplit + arg->i > n) ++ return; ++ selmon->msplit += arg->i; ++ selmon->msplits[selmon->curtag] = selmon->msplit; ++ arrange(selmon); ++} ++ ++void + showhide(Client *c) { + if(!c) + return; +@@ -1592,37 +1658,95 @@ textnw(const char *text, unsigned int le + + void + tile(Monitor *m) { +- int x, y, h, w, mw; +- unsigned int i, n; ++ char sym1 = 61, sym2 = 93, sym3 = 61, sym; ++ int x1 = m->wx, y1 = m->wy, h1 = m->wh, w1 = m->ww, X1 = x1 + w1, Y1 = y1 + h1; ++ int x2 = m->wx, y2 = m->wy, h2 = m->wh, w2 = m->ww, X2 = x2 + w2, Y2 = y2 + h2; ++ unsigned int i, n, n1, n2; + Client *c; + + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ if(m->msplit > n) ++ m->msplit = (n == 0) ? 1 : n; ++ if(n == 0 && m->ltaxis[1] != 3) ++ return; ++ /* layout symbol */ ++ if(abs(m->ltaxis[0]) == m->ltaxis[1]) /* explicitly: ((abs(m->ltaxis[0]) == 1 && m->ltaxis[1] == 1) || (abs(m->ltaxis[0]) == 2 && m->ltaxis[1] == 2)) */ ++ sym1 = 124; ++ if(abs(m->ltaxis[0]) == m->ltaxis[2]) ++ sym3 = 124; ++ if(m->ltaxis[1] == 3) ++ sym1 = (n == 0) ? 0 : m->msplit; ++ if(m->ltaxis[2] == 3) ++ sym3 = (n == 0) ? 0 : n - m->msplit; ++ if(m->ltaxis[0] < 0) { ++ sym = sym1; ++ sym1 = sym3; ++ sym2 = 91; ++ sym3 = sym; ++ } ++ if(m->msplit == 1) { ++ if(m->ltaxis[0] > 0) ++ sym1 = 91; ++ else ++ sym3 = 93; ++ } ++ if(m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[2] == 3) ++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3); ++ else if((m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] > 0) || (m->ltaxis[2] == 3 && m->ltaxis[0] < 0)) ++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3); ++ else if((m->ltaxis[2] == 3 && m->ltaxis[0] > 0) || (m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] < 0)) ++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, sym3); ++ else ++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); + if(n == 0) + return; ++ /* master and stack area */ ++ if(abs(m->ltaxis[0]) == 1 && n > m->msplit) { ++ w1 *= m->mfact; ++ w2 -= w1; ++ x1 += (m->ltaxis[0] < 0) ? w2 : 0; ++ x2 += (m->ltaxis[0] < 0) ? 0 : w1; ++ X1 = x1 + w1; ++ X2 = x2 + w2; ++ } else if(abs(m->ltaxis[0]) == 2 && n > m->msplit) { ++ h1 *= m->mfact; ++ h2 -= h1; ++ y1 += (m->ltaxis[0] < 0) ? h2 : 0; ++ y2 += (m->ltaxis[0] < 0) ? 0 : h1; ++ Y1 = y1 + h1; ++ Y2 = y2 + h2; ++ } + /* master */ +- c = nexttiled(m->clients); +- mw = m->mfact * m->ww; +- resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw, False); +- if(--n == 0) +- return; +- /* tile stack */ +- x = (m->wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : m->wx + mw; +- y = m->wy; +- w = (m->wx + mw > c->x + c->w) ? m->wx + m->ww - x : m->ww - mw; +- h = m->wh / n; +- if(h < bh) +- h = m->wh; +- for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { +- resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) +- ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); +- if(h != m->wh) +- y = c->y + HEIGHT(c); ++ n1 = (m->ltaxis[1] != 1 || w1 / m->msplit < bh) ? 1 : m->msplit; ++ n2 = (m->ltaxis[1] != 2 || h1 / m->msplit < bh) ? 1 : m->msplit; ++ for(i = 0, c = nexttiled(m->clients); i < m->msplit; c = nexttiled(c->next), i++) { ++ resize(c, x1, y1, ++ (m->ltaxis[1] == 1 && i + 1 == m->msplit) ? X1 - x1 - 2 * c->bw : w1 / n1 - 2 * c->bw, ++ (m->ltaxis[1] == 2 && i + 1 == m->msplit) ? Y1 - y1 - 2 * c->bw : h1 / n2 - 2 * c->bw, False); ++ if(n1 > 1) ++ x1 = c->x + WIDTH(c); ++ if(n2 > 1) ++ y1 = c->y + HEIGHT(c); ++ } ++ /* stack */ ++ if(n > m->msplit) { ++ n1 = (m->ltaxis[2] != 1 || w2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; ++ n2 = (m->ltaxis[2] != 2 || h2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; ++ for(i = 0; c; c = nexttiled(c->next), i++) { ++ resize(c, x2, y2, ++ (m->ltaxis[2] == 1 && i + 1 == n - m->msplit) ? X2 - x2 - 2 * c->bw : w2 / n1 - 2 * c->bw, ++ (m->ltaxis[2] == 2 && i + 1 == n - m->msplit) ? Y2 - y2 - 2 * c->bw : h2 / n2 - 2 * c->bw, False); ++ if(n1 > 1) ++ x2 = c->x + WIDTH(c); ++ if(n2 > 1) ++ y2 = c->y + HEIGHT(c); ++ } + } + } + + void + togglebar(const Arg *arg) { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1642,12 +1766,31 @@ togglefloating(const Arg *arg) { + void + toggletag(const Arg *arg) { + unsigned int newtags; ++ unsigned int i; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { + selmon->sel->tags = newtags; ++ if(newtags == ~0) { ++ selmon->prevtag = selmon->curtag; ++ selmon->curtag = 0; ++ } ++ if(!(newtags & 1 << (selmon->curtag - 1))) { ++ selmon->prevtag = selmon->curtag; ++ for (i=0; !(newtags & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ selmon->sel->tags = newtags; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if (selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); ++ selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; ++ selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; ++ selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; ++ selmon->msplit = selmon->msplits[selmon->curtag]; + arrange(selmon); + } + } +@@ -1914,11 +2057,33 @@ updatewmhints(Client *c) { + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->prevtag = selmon->curtag; ++ if(arg->ui == ~0) ++ selmon->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ } else { ++ selmon->prevtag = selmon->curtag ^ selmon->prevtag; ++ selmon->curtag ^= selmon->prevtag; ++ selmon->prevtag = selmon->curtag ^ selmon->prevtag; ++ } ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if(selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); ++ selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; ++ selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; ++ selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; ++ selmon->msplit = selmon->msplits[selmon->curtag]; + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-flextile-5.8.2.diff b/dwm.suckless.org/patches/flextile/dwm-flextile-5.8.2.diff diff --git a/dwm.suckless.org/patches/flextile.md b/dwm.suckless.org/patches/flextile/index.md diff --git a/dwm.suckless.org/patches/dwm-float_border_color-6.0.diff b/dwm.suckless.org/patches/float_border_color/dwm-float_border_color-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-float_border_color-6.1.diff b/dwm.suckless.org/patches/float_border_color/dwm-float_border_color-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-float_border_color2-20160731-56a31dc.diff b/dwm.suckless.org/patches/float_border_color/dwm-float_border_color2-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/float_border_color.md b/dwm.suckless.org/patches/float_border_color/index.md diff --git a/dwm.suckless.org/patches/focusadjacenttag.md b/dwm.suckless.org/patches/focusadjacenttag.md @@ -1,29 +0,0 @@ -focus adjacent tag -================== - -Description ------------ - -This patch provides the ability to focus the tag on the immediate left or right -of the currently focused tag. It also allows to send the focused window either -on the left or the right tag. - -Default key bindings --------------------- - - Key | Description -:-------------------:|:-------------------------------------------------- - `Mod-Left` | Focus tag on the left, if any. - `Mod-Right` | Focus tag on the right, if any. - `Mod-Shift-Left` | Send focused window to tag on the left, if any. - `Mod-Shift-Right` | Send focused window to tag on the right, if any. - -Download --------- - -<!-- Author emailed about this issue already --> - * [dwm-6.0-focusadjacenttag.diff](dwm-6.0-focusadjacenttag.diff) (Unclean patch) - -Authors -------- - * Fabio Banfi - `<fbanfi90 at gmail dot com>` diff --git a/dwm.suckless.org/patches/dwm-6.0-focusadjacenttag.diff b/dwm.suckless.org/patches/focusadjacenttag/dwm-focusadjacenttag-6.0.diff diff --git a/dwm.suckless.org/patches/focusadjacenttag/index.md b/dwm.suckless.org/patches/focusadjacenttag/index.md @@ -0,0 +1,29 @@ +focus adjacent tag +================== + +Description +----------- + +This patch provides the ability to focus the tag on the immediate left or right +of the currently focused tag. It also allows to send the focused window either +on the left or the right tag. + +Default key bindings +-------------------- + + Key | Description +:-------------------:|:-------------------------------------------------- + `Mod-Left` | Focus tag on the left, if any. + `Mod-Right` | Focus tag on the right, if any. + `Mod-Shift-Left` | Send focused window to tag on the left, if any. + `Mod-Shift-Right` | Send focused window to tag on the right, if any. + +Download +-------- + +<!-- Author emailed about this issue already --> + * [dwm-focusadjacenttag-6.0.diff](dwm-focusadjacenttag-6.0.diff) (Unclean patch) + +Authors +------- + * Fabio Banfi - `<fbanfi90 at gmail dot com>` diff --git a/dwm.suckless.org/patches/focusonclick.md b/dwm.suckless.org/patches/focusonclick.md @@ -1,22 +0,0 @@ -# focusonclick - -## Description - - * Switch focus only by mouse click and not sloppy. - -## Download - - * [dwm-focusonclick-20171030-6aa8e37.diff](dwm-focusonclick-20171030-6aa8e37.diff) (2017-10-17) - * [dwm-focusonclick-bb3bd6f.diff](dwm-focusonclick-bb3bd6f.diff) (2017-01-04) - * [dwm-focusonclick-6.0.diff](dwm-focusonclick-6.0.diff) (2012-11-24) - * [dwm-git-20100321-focusonclick.diff](historical/dwm-git-20100321-focusonclick.diff) - -## Author - - * Wolfgang S. - ezzieyguywuf at gmail . com (added 6aa8e37 patch fix) - * Markus P. - peters_mops at arcor . de - * Eric Pruitt - added option to disable focus changing with the scroll wheel - * [Alessandro Di Martino][1] - Maintainer of the 6.0 version. - * Markus Teich - Update and fix - -[1]: http://www.alessandrodimartino.com diff --git a/dwm.suckless.org/patches/dwm-focusonclick-20171030-6aa8e37.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-20171030-6aa8e37.diff diff --git a/dwm.suckless.org/patches/dwm-focusonclick-6.0.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-focusonclick-bb3bd6f.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-git-20100321.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-git-20100321.diff @@ -0,0 +1,38 @@ +diff -r 72e52c5333ef config.def.h +--- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 ++++ b/config.def.h Sun Mar 21 00:38:45 2010 +0100 +@@ -12,6 +12,7 @@ + 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 Bool focusonclick = True; /* Change focus only on click */ + + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +diff -r 72e52c5333ef dwm.c +--- a/dwm.c Wed Nov 25 13:56:17 2009 +0000 ++++ b/dwm.c Sun Mar 21 00:38:45 2010 +0100 +@@ -791,14 +791,16 @@ + + if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + return; +- if((m = wintomon(ev->window)) && m != selmon) { +- unfocus(selmon->sel); +- selmon = m; ++ if (!focusonclick) { ++ if((m = wintomon(ev->window)) && m != selmon) { ++ unfocus(selmon->sel); ++ selmon = m; ++ } ++ if((c = wintoclient(ev->window))) ++ focus(c); ++ else ++ focus(NULL); + } +- if((c = wintoclient(ev->window))) +- focus(c); +- else +- focus(NULL); + } + + void diff --git a/dwm.suckless.org/patches/focusonclick/index.md b/dwm.suckless.org/patches/focusonclick/index.md @@ -0,0 +1,22 @@ +# focusonclick + +## Description + + * Switch focus only by mouse click and not sloppy. + +## Download + + * [dwm-focusonclick-20171030-6aa8e37.diff](dwm-focusonclick-20171030-6aa8e37.diff) (2017-10-17) + * [dwm-focusonclick-bb3bd6f.diff](dwm-focusonclick-bb3bd6f.diff) (2017-01-04) + * [dwm-focusonclick-6.0.diff](dwm-focusonclick-6.0.diff) (2012-11-24) + * [dwm-focusonclick-git-20100321.diff](dwm-focusonclick-git-20100321.diff) + +## Author + + * Wolfgang S. - ezzieyguywuf at gmail . com (added 6aa8e37 patch fix) + * Markus P. - peters_mops at arcor . de + * Eric Pruitt - added option to disable focus changing with the scroll wheel + * [Alessandro Di Martino][1] - Maintainer of the 6.0 version. + * Markus Teich - Update and fix + +[1]: http://www.alessandrodimartino.com diff --git a/dwm.suckless.org/patches/focusurgent.md b/dwm.suckless.org/patches/focusurgent.md @@ -1,15 +0,0 @@ -# focusurgent - -## Description - - * Selects the next window having the urgent flag regardless of the tag it is on - * The urgent flag can be artificially set with the following xdotool command on - any window: `xdotool selectwindow -- set_window --urgency 1` - -## Download - - * [dwm-focusurgent-20160831-56a31dc.diff](dwm-focusurgent-20160831-56a31dc.diff) - -## Author - - * Jan Christoph Ebersbach <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-focusurgent-20160831-56a31dc.diff b/dwm.suckless.org/patches/focusurgent/dwm-focusurgent-20160831-56a31dc.diff diff --git a/dwm.suckless.org/patches/focusurgent/index.md b/dwm.suckless.org/patches/focusurgent/index.md @@ -0,0 +1,15 @@ +# focusurgent + +## Description + + * Selects the next window having the urgent flag regardless of the tag it is on + * The urgent flag can be artificially set with the following xdotool command on + any window: `xdotool selectwindow -- set_window --urgency 1` + +## Download + + * [dwm-focusurgent-20160831-56a31dc.diff](dwm-focusurgent-20160831-56a31dc.diff) + +## Author + + * Jan Christoph Ebersbach <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/gapless_grid.md b/dwm.suckless.org/patches/gapless_grid.md @@ -1,33 +0,0 @@ -# gapless grid layout - -## Description - -This patch is an altered [gridmode](historical/gridmode) layout for dwm, -which arranges the windows in a grid. -Instead of using a regular grid, which might leave empty cells when there are -not enough windows to fill the grid, it adjusts the number of windows in the -first few columns to avoid empty cells. - -## Usage - -Download `gaplessgrid.c` and add the gapless layout to your `config.h`: - - #include "gaplessgrid.c" - - static const Layout layouts[] = { - /* symbol arrange function */ - { "###", gaplessgrid }, - ... - - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_g, setlayout, {.v = &layouts[0] } }, - ... - -## Download - -* [dwm-gaplessgrid-20160731-56a31dc.diff](dwm-gaplessgrid-20160731-56a31dc.diff) -* [dwm-gaplessgrid-6.1.diff](dwm-gaplessgrid-6.1.diff) (1180b) (20140209) -* [gaplessgrid.c](gaplessgrid.c) (dwm 5.6.1) (20090908) -* [dwm-r1437-gaplessgrid.diff](historical/dwm-r1437-gaplessgrid.diff) (1.9k) (20090704) -* [dwm-5.2-gaplessgrid.diff](historical/dwm-5.2-gaplessgrid.diff) (1.9k) (20081020) diff --git a/dwm.suckless.org/patches/gaplessgrid.c b/dwm.suckless.org/patches/gaplessgrid.c @@ -1,36 +0,0 @@ -void -gaplessgrid(Monitor *m) { - unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) - n++; - if(n == 0) - return; - - /* grid dimensions */ - for(cols = 0; cols <= n/2; cols++) - if(cols*cols >= n) - break; - if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ - cols = 2; - rows = n/cols; - - /* window geometries */ - cw = cols ? m->ww / cols : m->ww; - cn = 0; /* current column number */ - rn = 0; /* current row number */ - for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { - if(i/rows + 1 > cols - n%cols) - rows = n/cols + 1; - ch = rows ? m->wh / rows : m->wh; - cx = m->wx + cn*cw; - cy = m->wy + rn*ch; - resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); - rn++; - if(rn >= rows) { - rn = 0; - cn++; - } - } -} diff --git a/dwm.suckless.org/patches/gaplessgrid/dwm-5.2-gaplessgrid.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-5.2-gaplessgrid.diff @@ -0,0 +1,59 @@ +diff -up dwm-5.2-original/config.def.h dwm-5.2-modified/config.def.h +--- dwm-5.2-original/config.def.h 2008-09-09 21:46:17.000000000 +0200 ++++ dwm-5.2-modified/config.def.h 2008-10-20 20:07:42.000000000 +0200 +@@ -28,11 +28,13 @@ static Rule rules[] = { + static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ + static Bool resizehints = True; /* False means respect size hints in tiled resizals */ + ++#include "gaplessgrid.c" + static Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "###", gaplessgrid }, + }; + + /* key definitions */ +diff -up dwm-5.2-original/gaplessgrid.c dwm-5.2-modified/gaplessgrid.c +--- /dev/null 2008-10-20 20:09:51.000000000 +0200 ++++ dwm-5.2-modified/gaplessgrid.c 2008-10-20 20:06:59.000000000 +0200 +@@ -0,0 +1,38 @@ ++void ++gaplessgrid() { ++ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; ++ Client *c; ++ ++ for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) ++ n++; ++ if(n == 0) ++ return; ++ ++ /* grid dimensions */ ++ for(cols = 0; cols <= n/2; cols++) ++ if(cols*cols >= n) ++ break; ++ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ ++ cols = 2; ++ rows = n/cols; ++ ++ /* window geometries (cell height/width/x/y) */ ++ cw = ww / (cols ? cols : 1); ++ cn = 0; /* current column number */ ++ rn = 0; /* current row number */ ++ for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { ++ if(i/rows+1 > cols-n%cols) ++ rows = n/cols+1; ++ ch = wh / (rows ? rows : 1); ++ cx = wx + cn*cw; ++ cy = wy + rn*ch; ++ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); ++ ++ i++; ++ rn++; ++ if(rn >= rows) { /* jump to the next column */ ++ rn = 0; ++ cn++; ++ } ++ } ++} diff --git a/dwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-gaplessgrid-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-gaplessgrid-6.1.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-gaplessgrid-6.1.diff diff --git a/dwm.suckless.org/patches/gaplessgrid/dwm-r1437-gaplessgrid.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-r1437-gaplessgrid.diff @@ -0,0 +1,59 @@ +diff -up dwm-5.2-original/config.def.h dwm-5.2-modified/config.def.h +--- dwm-5.2-original/config.def.h 2008-09-09 21:46:17.000000000 +0200 ++++ dwm-5.2-modified/config.def.h 2008-10-20 20:07:42.000000000 +0200 +@@ -28,11 +28,13 @@ static Rule rules[] = { + static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ + static Bool resizehints = True; /* False means respect size hints in tiled resizals */ + ++#include "gaplessgrid.c" + static Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, ++ { "###", gaplessgrid }, + }; + + /* key definitions */ +diff -up dwm-5.2-original/gaplessgrid.c dwm-5.2-modified/gaplessgrid.c +--- /dev/null 2008-10-20 20:09:51.000000000 +0200 ++++ dwm-5.2-modified/gaplessgrid.c 2008-10-20 20:06:59.000000000 +0200 +@@ -0,0 +1,38 @@ ++void ++gaplessgrid(Monitor *m) { ++ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; ++ Client *c; ++ ++ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) ++ n++; ++ if(n == 0) ++ return; ++ ++ /* grid dimensions */ ++ for(cols = 0; cols <= n/2; cols++) ++ if(cols*cols >= n) ++ break; ++ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ ++ cols = 2; ++ rows = n/cols; ++ ++ /* window geometries (cell height/width/x/y) */ ++ cw = m->ww / (cols ? cols : 1); ++ cn = 0; /* current column number */ ++ rn = 0; /* current row number */ ++ for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { ++ if(i/rows+1 > cols-n%cols) ++ rows = n/cols+1; ++ ch = m->wh / (rows ? rows : 1); ++ cx = m->wx + cn*cw; ++ cy = m->wy + rn*ch; ++ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw); ++ ++ i++; ++ rn++; ++ if(rn >= rows) { /* jump to the next column */ ++ rn = 0; ++ cn++; ++ } ++ } ++} diff --git a/dwm.suckless.org/patches/gaplessgrid/gaplessgrid.c b/dwm.suckless.org/patches/gaplessgrid/gaplessgrid.c @@ -0,0 +1,36 @@ +void +gaplessgrid(Monitor *m) { + unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; + Client *c; + + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) + n++; + if(n == 0) + return; + + /* grid dimensions */ + for(cols = 0; cols <= n/2; cols++) + if(cols*cols >= n) + break; + if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ + cols = 2; + rows = n/cols; + + /* window geometries */ + cw = cols ? m->ww / cols : m->ww; + cn = 0; /* current column number */ + rn = 0; /* current row number */ + for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { + if(i/rows + 1 > cols - n%cols) + rows = n/cols + 1; + ch = rows ? m->wh / rows : m->wh; + cx = m->wx + cn*cw; + cy = m->wy + rn*ch; + resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); + rn++; + if(rn >= rows) { + rn = 0; + cn++; + } + } +} diff --git a/dwm.suckless.org/patches/gaplessgrid/index.md b/dwm.suckless.org/patches/gaplessgrid/index.md @@ -0,0 +1,33 @@ +# gapless grid layout + +## Description + +This patch is an altered [gridmode](historical/gridmode) layout for dwm, +which arranges the windows in a grid. +Instead of using a regular grid, which might leave empty cells when there are +not enough windows to fill the grid, it adjusts the number of windows in the +first few columns to avoid empty cells. + +## Usage + +Download `gaplessgrid.c` and add the gapless layout to your `config.h`: + + #include "gaplessgrid.c" + + static const Layout layouts[] = { + /* symbol arrange function */ + { "###", gaplessgrid }, + ... + + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_g, setlayout, {.v = &layouts[0] } }, + ... + +## Download + +* [dwm-gaplessgrid-20160731-56a31dc.diff](dwm-gaplessgrid-20160731-56a31dc.diff) +* [dwm-gaplessgrid-6.1.diff](dwm-gaplessgrid-6.1.diff) (20140209) +* [gaplessgrid.c](gaplessgrid.c) (dwm 5.6.1) (20090908) +* [dwm-r1437-gaplessgrid.diff](dwm-r1437-gaplessgrid.diff) (20090704) +* [dwm-5.2-gaplessgrid.diff](dwm-5.2-gaplessgrid.diff) (20081020) diff --git a/dwm.suckless.org/patches/gaps.md b/dwm.suckless.org/patches/gaps.md @@ -1,27 +0,0 @@ - -Gaps -==== - -Description ------------ - -This patch modifies the tile layout to add a gap between clients that helps to visually -differentiate between selected borders and normal borders and so provides an additional -visual hint to identify the currently selected client. OTOH, there's no gap between a -client and the screen frame in order to reduce the waste of screen space. - -To configure the gap size just set the configuration variable `gappx`. - -There is a variation of the patch for the [xtile](xtile) layout also. - -Download --------- - -* For vanilla tile: [dwm-gaps-6.0.diff](dwm-gaps-6.0.diff) - -* For xtile tile: [dwm-6.0-xtile-gaps.diff](dwm-6.0-xtile-gaps.diff) - -Author ------- - -* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-gaps-6.0.diff b/dwm.suckless.org/patches/gaps/dwm-gaps-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-xtile-gaps.diff b/dwm.suckless.org/patches/gaps/dwm-gaps-xtile-6.0.diff diff --git a/dwm.suckless.org/patches/gaps/index.md b/dwm.suckless.org/patches/gaps/index.md @@ -0,0 +1,26 @@ +gaps +==== + +Description +----------- + +This patch modifies the tile layout to add a gap between clients that helps to visually +differentiate between selected borders and normal borders and so provides an additional +visual hint to identify the currently selected client. OTOH, there's no gap between a +client and the screen frame in order to reduce the waste of screen space. + +To configure the gap size just set the configuration variable `gappx`. + +There is a variation of the patch for the [xtile](xtile) layout also. + +Download +-------- + +* For vanilla tile: [dwm-gaps-6.0.diff](dwm-gaps-6.0.diff) + +* For xtile tile: [dwm-gaps-xtile-6.0.diff](dwm-gaps-xtile-6.0.diff) + +Author +------ + +* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/gestures.md b/dwm.suckless.org/patches/gestures.md @@ -1,16 +0,0 @@ -gestures -======== - -Description ------------ -`gestures` adds support for simple mouse gestures to dwm. The patch assumes make has been run -and adds a gestures array to config.h. A gesture can call any dwm function. I usually call spawn. - -Download --------- -<!-- Author email bounced (removed it), patch needs fixed --> -* [dwm-5.8-gestures.diff](dwm-5.8-gestures.diff) (Unclean patch) - -Author ------- -* David Galos diff --git a/dwm.suckless.org/patches/dwm-5.8-gestures.diff b/dwm.suckless.org/patches/gestures/dwm-5.8-gestures.diff diff --git a/dwm.suckless.org/patches/gestures/index.md b/dwm.suckless.org/patches/gestures/index.md @@ -0,0 +1,16 @@ +gestures +======== + +Description +----------- +`gestures` adds support for simple mouse gestures to dwm. The patch assumes make has been run +and adds a gestures array to config.h. A gesture can call any dwm function. I usually call spawn. + +Download +-------- +<!-- Author email bounced (removed it), patch needs fixed --> +* [dwm-5.8-gestures.diff](dwm-5.8-gestures.diff) (Unclean patch) + +Author +------ +* David Galos diff --git a/dwm.suckless.org/patches/gridmode.md b/dwm.suckless.org/patches/gridmode.md @@ -1,27 +0,0 @@ -gridmode -======== - -Description ------------ -This patch adds an extra layout mode to dwm called `grid` in which the windows -are arranged in a grid of equal sizes. It comes in very handy, especially with -tools that operate on multiple windows at once; e.g. Cluster SSH. - -Download --------- -* [dwm-gridmode-20170909-ceac8c9.diff](dwm-grid-20170909-ceac8c9.diff) -* [dwm-gridmode-5.8.2.diff](dwm-gridmode-5.8.2.diff) -* See older versions in [historical](historical/gridmode). - -Authors -------- -* Alexandru E. Ungur - `<grid at rb.no-ip dot biz>` -* Updated by Jan Christoph Ebersbach - `<jceb at e-jc dot de>` -* Updated to 5.2 & small fix by V4hn - `v4hn.de` - -Feedback is more than welcome :-) - -Acknowledgements ----------------- -The patch would look a lot uglier without Jukka Salmi's constant help. -Thanks Jukka :-) diff --git a/dwm.suckless.org/patches/dwm-gridmode-20170909-ceac8c9.diff b/dwm.suckless.org/patches/gridmode/dwm-gridmode-20170909-ceac8c9.diff diff --git a/dwm.suckless.org/patches/dwm-gridmode-5.8.2.diff b/dwm.suckless.org/patches/gridmode/dwm-gridmode-5.8.2.diff diff --git a/dwm.suckless.org/patches/gridmode/index.md b/dwm.suckless.org/patches/gridmode/index.md @@ -0,0 +1,27 @@ +gridmode +======== + +Description +----------- +This patch adds an extra layout mode to dwm called `grid` in which the windows +are arranged in a grid of equal sizes. It comes in very handy, especially with +tools that operate on multiple windows at once; e.g. Cluster SSH. + +Download +-------- +* [dwm-gridmode-20170909-ceac8c9.diff](dwm-grid-20170909-ceac8c9.diff) +* [dwm-gridmode-5.8.2.diff](dwm-gridmode-5.8.2.diff) +* See older versions in [historical](historical/gridmode). + +Authors +------- +* Alexandru E. Ungur - `<grid at rb.no-ip dot biz>` +* Updated by Jan Christoph Ebersbach - `<jceb at e-jc dot de>` +* Updated to 5.2 & small fix by V4hn - `v4hn.de` + +Feedback is more than welcome :-) + +Acknowledgements +---------------- +The patch would look a lot uglier without Jukka Salmi's constant help. +Thanks Jukka :-) diff --git a/dwm.suckless.org/patches/hide_vacant_tags.md b/dwm.suckless.org/patches/hide_vacant_tags.md @@ -1,29 +0,0 @@ -hide vacant tags -================ - -Description ------------ - -This patch prevents dwm from drawing tags with no clients -(i.e. vacant) on the bar. - -It also makes sure that pressing a tag on the bar behaves accordingly -by not reserving reactive regions on the bar for vacant tags. - -It also stops drawing empty rectangles on the bar for non-vacant -tags as there is no need anymore to distinguish vacant -tags and it offers a more visible contrast than if there were -filled/empty rectangles. - -Download --------- - -* [dwm-hide_vacant_tags-6.1.diff](dwm-hide_vacant_tags-6.1.diff) - 2016-01-22 -* [dwm-hide_vacant_tags-git-20160626-7af4d43.diff](dwm-hide_vacant_tags-git-20160626-7af4d43.diff) - -Author ------- - -* [Ondřej Grover](mailto:ondrej.grover@gmail.com) -* Matthew Boswell - mordervomubel+suckless at lockmail dot us (mechanical update for dwm 6.1 release) -* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (hide 0 tagged clients) diff --git a/dwm.suckless.org/patches/dwm-hide_vacant_tags-6.1.diff b/dwm.suckless.org/patches/hide_vacant_tags/dwm-hide_vacant_tags-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-hide_vacant_tags-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/hide_vacant_tags/dwm-hide_vacant_tags-git-20160626-7af4d43.diff diff --git a/dwm.suckless.org/patches/hide_vacant_tags/index.md b/dwm.suckless.org/patches/hide_vacant_tags/index.md @@ -0,0 +1,29 @@ +hide vacant tags +================ + +Description +----------- + +This patch prevents dwm from drawing tags with no clients +(i.e. vacant) on the bar. + +It also makes sure that pressing a tag on the bar behaves accordingly +by not reserving reactive regions on the bar for vacant tags. + +It also stops drawing empty rectangles on the bar for non-vacant +tags as there is no need anymore to distinguish vacant +tags and it offers a more visible contrast than if there were +filled/empty rectangles. + +Download +-------- + +* [dwm-hide_vacant_tags-6.1.diff](dwm-hide_vacant_tags-6.1.diff) - 2016-01-22 +* [dwm-hide_vacant_tags-git-20160626-7af4d43.diff](dwm-hide_vacant_tags-git-20160626-7af4d43.diff) + +Author +------ + +* [Ondřej Grover](mailto:ondrej.grover@gmail.com) +* Matthew Boswell - mordervomubel+suckless at lockmail dot us (mechanical update for dwm 6.1 release) +* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (hide 0 tagged clients) diff --git a/dwm.suckless.org/patches/historical/dwm-5.2-gaplessgrid.diff b/dwm.suckless.org/patches/historical/dwm-5.2-gaplessgrid.diff @@ -1,59 +0,0 @@ -diff -up dwm-5.2-original/config.def.h dwm-5.2-modified/config.def.h ---- dwm-5.2-original/config.def.h 2008-09-09 21:46:17.000000000 +0200 -+++ dwm-5.2-modified/config.def.h 2008-10-20 20:07:42.000000000 +0200 -@@ -28,11 +28,13 @@ static Rule rules[] = { - static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static Bool resizehints = True; /* False means respect size hints in tiled resizals */ - -+#include "gaplessgrid.c" - static Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "###", gaplessgrid }, - }; - - /* key definitions */ -diff -up dwm-5.2-original/gaplessgrid.c dwm-5.2-modified/gaplessgrid.c ---- /dev/null 2008-10-20 20:09:51.000000000 +0200 -+++ dwm-5.2-modified/gaplessgrid.c 2008-10-20 20:06:59.000000000 +0200 -@@ -0,0 +1,38 @@ -+void -+gaplessgrid() { -+ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) -+ n++; -+ if(n == 0) -+ return; -+ -+ /* grid dimensions */ -+ for(cols = 0; cols <= n/2; cols++) -+ if(cols*cols >= n) -+ break; -+ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ -+ cols = 2; -+ rows = n/cols; -+ -+ /* window geometries (cell height/width/x/y) */ -+ cw = ww / (cols ? cols : 1); -+ cn = 0; /* current column number */ -+ rn = 0; /* current row number */ -+ for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { -+ if(i/rows+1 > cols-n%cols) -+ rows = n/cols+1; -+ ch = wh / (rows ? rows : 1); -+ cx = wx + cn*cw; -+ cy = wy + rn*ch; -+ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); -+ -+ i++; -+ rn++; -+ if(rn >= rows) { /* jump to the next column */ -+ rn = 0; -+ cn++; -+ } -+ } -+} diff --git a/dwm.suckless.org/patches/historical/dwm-5.7.2-statuscolors.diff b/dwm.suckless.org/patches/historical/dwm-5.7.2-statuscolors.diff @@ -1,234 +0,0 @@ -diff -r 2bcd25cce4ab config.def.h ---- a/config.def.h Sun Sep 27 20:20:14 2009 +0100 -+++ b/config.def.h Mon Oct 05 22:01:49 2009 -0300 -@@ -1,13 +1,16 @@ - /* See LICENSE file for copyright and license details. */ - - /* appearance */ -+#define NUMCOLORS 4 // need at least 3 -+static const char colors[NUMCOLORS][ColLast][8] = { -+ // border foreground background -+ { "#cccccc", "#000000", "#cccccc" }, // 0 = normal -+ { "#0066ff", "#ffffff", "#0066ff" }, // 1 = selected -+ { "#0066ff", "#0066ff", "#ffffff" }, // 2 = urgent/warning -+ { "#ff0000", "#ffffff", "#ff0000" }, // 3 = error -+ // add more here -+}; - static const char font[] = "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*"; --static const char normbordercolor[] = "#cccccc"; --static const char normbgcolor[] = "#cccccc"; --static const char normfgcolor[] = "#000000"; --static const char selbordercolor[] = "#0066ff"; --static const char selbgcolor[] = "#0066ff"; --static const char selfgcolor[] = "#ffffff"; - 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 */ -@@ -45,7 +48,7 @@ - #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - - /* commands */ --static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; -+static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG], "-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL }; - static const char *termcmd[] = { "uxterm", NULL }; - - static Key keys[] = { -diff -r 2bcd25cce4ab dwm.c ---- a/dwm.c Sun Sep 27 20:20:14 2009 +0100 -+++ b/dwm.c Mon Oct 05 22:01:49 2009 -0300 -@@ -48,6 +48,7 @@ - #define LENGTH(X) (sizeof X / sizeof X[0]) - #define MAX(A, B) ((A) > (B) ? (A) : (B)) - #define MIN(A, B) ((A) < (B) ? (A) : (B)) -+#define MAXCOLORS 8 - #define MOUSEMASK (BUTTONMASK|PointerMotionMask) - #define WIDTH(X) ((X)->w + 2 * (X)->bw) - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) -@@ -95,8 +96,7 @@ - - typedef struct { - int x, y, w, h; -- unsigned long norm[ColLast]; -- unsigned long sel[ColLast]; -+ unsigned long colors[MAXCOLORS][ColLast]; - Drawable drawable; - GC gc; - struct { -@@ -172,8 +172,9 @@ - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); --static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); --static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); -+static void drawcoloredtext(char *text); -+static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]); -+static void drawtext(const char *text, unsigned long col[ColLast], Bool pad); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); -@@ -691,14 +692,13 @@ - dc.x = 0; - for(i = 0; i < LENGTH(tags); i++) { - dc.w = TEXTW(tags[i]); -- col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; -- drawtext(tags[i], col, urg & 1 << i); -- drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, -- occ & 1 << i, urg & 1 << i, col); -+ col = dc.colors[ (m->tagset[m->seltags] & 1 << i ? 1:(urg & 1 << i ? 2:0))]; -+ drawtext(tags[i], col, True); -+ drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, col); - dc.x += dc.w; - } - dc.w = blw = TEXTW(m->ltsymbol); -- drawtext(m->ltsymbol, dc.norm, False); -+ drawtext(m->ltsymbol, dc.colors[0], True); - dc.x += dc.w; - x = dc.x; - if(m == selmon) { /* status is only drawn on selected monitor */ -@@ -708,19 +708,19 @@ - dc.x = x; - dc.w = m->ww - x; - } -- drawtext(stext, dc.norm, False); -+ drawcoloredtext(stext); - } - else - dc.x = m->ww; - if((dc.w = dc.x - x) > bh) { - dc.x = x; - if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); -+ col = m == selmon ? dc.colors[1] : dc.colors[0]; -+ drawtext(m->sel->name, col, True); -+ drawsquare(m->sel->isfixed, m->sel->isfloating, col); - } - else -- drawtext(NULL, dc.norm, False); -+ drawtext(NULL, dc.colors[0], False); - } - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); -@@ -735,12 +735,42 @@ - } - - void --drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { -+drawcoloredtext(char *text) { -+ Bool first=True; -+ char *buf = text, *ptr = buf, c = 1; -+ unsigned long *col = dc.colors[0]; -+ int i, ox = dc.x; -+ -+ while( *ptr ) { -+ for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++); -+ if( !*ptr ) break; -+ c=*ptr; -+ *ptr=0; -+ if( i ) { -+ dc.w = selmon->ww - dc.x; -+ drawtext(buf, col, first); -+ dc.x += textnw(buf, i) + textnw(&c,1); -+ if( first ) dc.x += ( dc.font.ascent + dc.font.descent ) / 2; -+ first = False; -+ } else if( first ) { -+ ox = dc.x += textnw(&c,1); -+ } -+ *ptr = c; -+ col = dc.colors[ c-1 ]; -+ buf = ++ptr; -+ } -+ if( !first ) dc.x-=(dc.font.ascent+dc.font.descent)/2; -+ drawtext(buf, col, True); -+ dc.x = ox; -+} -+ -+void -+drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) { - int x; - XGCValues gcv; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - -- gcv.foreground = col[invert ? ColBG : ColFG]; -+ gcv.foreground = col[ ColFG ]; - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - x = (dc.font.ascent + dc.font.descent + 2) / 4; - r.x = dc.x + 1; -@@ -756,18 +786,18 @@ - } - - void --drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -+drawtext(const char *text, unsigned long col[ColLast], Bool pad) { - char buf[256]; - int i, x, y, h, len, olen; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - -- XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -+ XSetForeground(dpy, dc.gc, col[ ColBG ]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - olen = strlen(text); -- h = dc.font.ascent + dc.font.descent; -- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; -+ h = pad ? (dc.font.ascent + dc.font.descent) : 0; -+ y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2); - x = dc.x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); -@@ -776,7 +806,7 @@ - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); -- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); -+ XSetForeground(dpy, dc.gc, col[ ColFG ]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - else -@@ -824,7 +854,7 @@ - detachstack(c); - attachstack(c); - grabbuttons(c, True); -- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); -+ XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - } - else -@@ -1132,7 +1162,7 @@ - } - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); -- XSetWindowBorder(dpy, w, dc.norm[ColBorder]); -+ XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]); - configure(c); /* propagates border_width, if size doesn't change */ - updatesizehints(c); - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); -@@ -1498,12 +1528,11 @@ - cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); - cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); - /* init appearance */ -- dc.norm[ColBorder] = getcolor(normbordercolor); -- dc.norm[ColBG] = getcolor(normbgcolor); -- dc.norm[ColFG] = getcolor(normfgcolor); -- dc.sel[ColBorder] = getcolor(selbordercolor); -- dc.sel[ColBG] = getcolor(selbgcolor); -- dc.sel[ColFG] = getcolor(selfgcolor); -+ for(int i=0; i<NUMCOLORS; i++) { -+ dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] ); -+ dc.colors[i][ColFG] = getcolor( colors[i][ColFG] ); -+ dc.colors[i][ColBG] = getcolor( colors[i][ColBG] ); -+ } - 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); -@@ -1665,7 +1694,7 @@ - if(!c) - return; - grabbuttons(c, False); -- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); -+ XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]); - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-pertag_without_bar.diff b/dwm.suckless.org/patches/historical/dwm-5.8.2-pertag_without_bar.diff @@ -1,165 +0,0 @@ -diff --git a/dwm.c b/dwm.c ---- a/dwm.c -+++ b/dwm.c -@@ -122,26 +122,6 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - --struct Monitor { -- char ltsymbol[16]; -- float mfact; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; --}; -- - typedef struct { - const char *class; - const char *instance; -@@ -278,6 +258,30 @@ static Window root; - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+struct Monitor { -+ char ltsymbol[16]; -+ float mfact; -+ int num; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+ int curtag; -+ int prevtag; -+ const Layout *lts[LENGTH(tags) + 1]; -+ double mfacts[LENGTH(tags) + 1]; -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -609,6 +613,7 @@ configurerequest(XEvent *e) { - Monitor * - createmon(void) { - Monitor *m; -+ unsigned int i; - - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); -@@ -619,6 +624,14 @@ createmon(void) { - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -+ -+ /* pertag init */ -+ m->curtag = m->prevtag = 1; -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ m->mfacts[i] = mfact; -+ m->lts[i] = &layouts[0]; -+ } -+ - return m; - } - -@@ -1486,7 +1499,7 @@ setlayout(const Arg *arg) { - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if(arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) - arrange(selmon); -@@ -1504,7 +1517,7 @@ setmfact(const Arg *arg) { - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->mfacts[selmon->curtag] = f; - arrange(selmon); - } - -@@ -1547,7 +1560,6 @@ setup(void) { - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -- /* init bars */ - updatebars(); - updatestatus(); - /* EWMH support per view */ -@@ -1678,12 +1690,25 @@ togglefloating(const Arg *arg) { - void - toggletag(const Arg *arg) { - unsigned int newtags; -+ unsigned int i; - - if(!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { - selmon->sel->tags = newtags; -+ if(newtags == ~0) { -+ selmon->prevtag = selmon->curtag; -+ selmon->curtag = 0; -+ } -+ if(!(newtags & 1 << (selmon->curtag - 1))) { -+ selmon->prevtag = selmon->curtag; -+ for (i=0; !(newtags & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ selmon->sel->tags = newtags; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; - arrange(selmon); - } - } -@@ -1950,11 +1975,27 @@ updatewmhints(Client *c) { - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->prevtag = selmon->curtag; -+ if(arg->ui == ~0) -+ selmon->curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ } else { -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ selmon->curtag^= selmon->prevtag; -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ } -+ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; - arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-statuscolors.diff b/dwm.suckless.org/patches/historical/dwm-5.8.2-statuscolors.diff @@ -1,232 +0,0 @@ ---- a/config.def.h 2010-10-16 15:49:03.000000000 +0200 -+++ b/config.def.h 2010-10-16 15:51:35.000000000 +0200 -@@ -1,13 +1,16 @@ - /* See LICENSE file for copyright and license details. */ - - /* appearance */ -+#define NUMCOLORS 4 // need at least 3 -+static const char colors[NUMCOLORS][ColLast][8] = { -+ // border foreground background -+ { "#cccccc", "#000000", "#cccccc" }, // 0 = normal -+ { "#0066ff", "#ffffff", "#0066ff" }, // 1 = selected -+ { "#0066ff", "#0066ff", "#ffffff" }, // 2 = urgent/warning -+ { "#ff0000", "#ffffff", "#ff0000" }, // 3 = error -+ // add more here -+}; - static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; --static const char normbordercolor[] = "#cccccc"; --static const char normbgcolor[] = "#cccccc"; --static const char normfgcolor[] = "#000000"; --static const char selbordercolor[] = "#0066ff"; --static const char selbgcolor[] = "#0066ff"; --static const char selfgcolor[] = "#ffffff"; - 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 */ -@@ -45,7 +48,7 @@ - #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - - /* commands */ --static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; -+static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG],"-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL }; - static const char *termcmd[] = { "uxterm", NULL }; - - static Key keys[] = { ---- a//dwm.c 2010-06-04 12:39:15.000000000 +0200 -+++ b/dwm.c 2010-11-03 20:36:50.000000000 +0100 -@@ -48,6 +48,7 @@ - #define LENGTH(X) (sizeof X / sizeof X[0]) - #define MAX(A, B) ((A) > (B) ? (A) : (B)) - #define MIN(A, B) ((A) < (B) ? (A) : (B)) -+#define MAXCOLORS 8 - #define MOUSEMASK (BUTTONMASK|PointerMotionMask) - #define WIDTH(X) ((X)->w + 2 * (X)->bw) - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) -@@ -97,8 +98,7 @@ - - typedef struct { - int x, y, w, h; -- unsigned long norm[ColLast]; -- unsigned long sel[ColLast]; -+ unsigned long colors[MAXCOLORS][ColLast]; - Drawable drawable; - GC gc; - struct { -@@ -175,8 +175,9 @@ - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); --static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); --static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); -+static void drawcoloredtext(char *text); -+static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]); -+static void drawtext(const char *text, unsigned long col[ColLast], Bool pad); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); -@@ -696,14 +697,13 @@ - dc.x = 0; - for(i = 0; i < LENGTH(tags); i++) { - dc.w = TEXTW(tags[i]); -- col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; -- drawtext(tags[i], col, urg & 1 << i); -- drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, -- occ & 1 << i, urg & 1 << i, col); -+ col = dc.colors[ (m->tagset[m->seltags] & 1 << i ? 1:(urg & 1 << i ? 2:0))]; -+ drawtext(tags[i], col, True); -+ drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, col); - dc.x += dc.w; - } - dc.w = blw = TEXTW(m->ltsymbol); -- drawtext(m->ltsymbol, dc.norm, False); -+ drawtext(m->ltsymbol, dc.colors[0], True); - dc.x += dc.w; - x = dc.x; - if(m == selmon) { /* status is only drawn on selected monitor */ -@@ -713,19 +713,19 @@ - dc.x = x; - dc.w = m->ww - x; - } -- drawtext(stext, dc.norm, False); -+ drawcoloredtext(stext); - } - else - dc.x = m->ww; - if((dc.w = dc.x - x) > bh) { - dc.x = x; - if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); -+ col = m == selmon ? dc.colors[1] : dc.colors[0]; -+ drawtext(m->sel->name, col, True); -+ drawsquare(m->sel->isfixed, m->sel->isfloating, col); - } - else -- drawtext(NULL, dc.norm, False); -+ drawtext(NULL, dc.colors[0], False); - } - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); -@@ -740,12 +740,42 @@ - } - - void --drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { -+drawcoloredtext(char *text) { -+ Bool first=True; -+ char *buf = text, *ptr = buf, c = 1; -+ unsigned long *col = dc.colors[0]; -+ int i, ox = dc.x; -+ -+ while( *ptr ) { -+ for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++); -+ if( !*ptr ) break; -+ c=*ptr; -+ *ptr=0; -+ if( i ) { -+ dc.w = selmon->ww - dc.x; -+ drawtext(buf, col, first); -+ dc.x += textnw(buf, i) + textnw(&c,1); -+ if( first ) dc.x += ( dc.font.ascent + dc.font.descent ) / 2; -+ first = False; -+ } else if( first ) { -+ ox = dc.x += textnw(&c,1); -+ } -+ *ptr = c; -+ col = dc.colors[ c-1 ]; -+ buf = ++ptr; -+ } -+ if( !first ) dc.x-=(dc.font.ascent+dc.font.descent)/2; -+ drawtext(buf, col, True); -+ dc.x = ox; -+} -+ -+void -+drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) { - int x; - XGCValues gcv; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - -- gcv.foreground = col[invert ? ColBG : ColFG]; -+ gcv.foreground = col[ ColFG ]; - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - x = (dc.font.ascent + dc.font.descent + 2) / 4; - r.x = dc.x + 1; -@@ -761,18 +791,18 @@ - } - - void --drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -+drawtext(const char *text, unsigned long col[ColLast], Bool pad) { - char buf[256]; - int i, x, y, h, len, olen; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - -- XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -+ XSetForeground(dpy, dc.gc, col[ ColBG ]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - olen = strlen(text); -- h = dc.font.ascent + dc.font.descent; -- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; -+ h = pad ? (dc.font.ascent + dc.font.descent) : 0; -+ y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2); - x = dc.x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); -@@ -781,7 +811,7 @@ - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); -- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); -+ XSetForeground(dpy, dc.gc, col[ ColFG ]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - else -@@ -830,7 +860,7 @@ - detachstack(c); - attachstack(c); - grabbuttons(c, True); -- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); -+ XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - } - else -@@ -1139,7 +1169,7 @@ - } - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); -- XSetWindowBorder(dpy, w, dc.norm[ColBorder]); -+ XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]); - configure(c); /* propagates border_width, if size doesn't change */ - updatesizehints(c); - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); -@@ -1544,12 +1574,11 @@ - cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); - cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); - /* init appearance */ -- dc.norm[ColBorder] = getcolor(normbordercolor); -- dc.norm[ColBG] = getcolor(normbgcolor); -- dc.norm[ColFG] = getcolor(normfgcolor); -- dc.sel[ColBorder] = getcolor(selbordercolor); -- dc.sel[ColBG] = getcolor(selbgcolor); -- dc.sel[ColFG] = getcolor(selfgcolor); -+ for(int i=0; i<NUMCOLORS; i++) { -+ dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] ); -+ dc.colors[i][ColFG] = getcolor( colors[i][ColFG] ); -+ dc.colors[i][ColBG] = getcolor( colors[i][ColBG] ); -+ } - 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); -@@ -1711,7 +1740,7 @@ - if(!c) - return; - grabbuttons(c, False); -- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); -+ XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]); - if(setfocus) - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - } diff --git a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2.diff b/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2.diff @@ -1,720 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..666b9c0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,6 +12,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -25,7 +32,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -54,6 +61,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -101,5 +109,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 5268a06..d213208 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation from window to window, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is recalled in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "always" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1d78655..a892b7a 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -44,7 +44,7 @@ - #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) - #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))) -+ * 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 LENGTH(X) (sizeof X / sizeof X[0]) - #define MAX(A, B) ((A) > (B) ? (A) : (B)) -@@ -62,7 +62,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -102,6 +102,7 @@ typedef struct { - unsigned long norm[ColLast]; - unsigned long sel[ColLast]; - Drawable drawable; -+ Drawable tabdrawable; - GC gc; - struct { - int ascent; -@@ -124,24 +125,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -178,11 +187,15 @@ static void die(const char *errstr, ...); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); --static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); -+static void drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert); -+//static void drawtabtext(const char *text, unsigned long col[ColLast], Bool invert); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); -+static void focuswin(const Arg* arg); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -@@ -229,6 +242,7 @@ static void tagmon(const Arg *arg); - static int textnw(const char *text, unsigned int len); - static void tile(Monitor *); - static void togglebar(const Arg *arg); -+static void tabmode(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); -@@ -258,6 +272,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -405,6 +420,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -454,14 +472,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -491,6 +527,7 @@ cleanup(void) { - XFreeFont(dpy, dc.font.xfont); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XFreePixmap(dpy, dc.drawable); -+ XFreePixmap(dpy, dc.tabdrawable); - XFreeGC(dpy, dc.gc); - XFreeCursor(dpy, cursor[CurNormal]); - XFreeCursor(dpy, cursor[CurResize]); -@@ -513,6 +550,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -538,7 +577,7 @@ clientmessage(XEvent *e) { - if(cme->message_type == netatom[NetWMState]) { - if(cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ -- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); -+ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } - else if(cme->message_type == netatom[NetActiveWindow]) { - if(!ISVISIBLE(c)) { -@@ -581,9 +620,13 @@ configurenotify(XEvent *e) { - if(dc.drawable != 0) - XFreePixmap(dpy, dc.drawable); - dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); -+ if(dc.tabdrawable != 0) -+ XFreePixmap(dpy, dc.tabdrawable); -+ dc.tabdrawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); - updatebars(); -- for(m = mons; m; m = m->next) -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -653,7 +696,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -731,13 +777,13 @@ drawbar(Monitor *m) { - for(i = 0; i < LENGTH(tags); i++) { - dc.w = TEXTW(tags[i]); - col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; -- drawtext(tags[i], col, urg & 1 << i); -+ drawtext(dc.drawable, tags[i], col, urg & 1 << i); - drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, -- occ & 1 << i, urg & 1 << i, col); -+ occ & 1 << i, urg & 1 << i, col); - dc.x += dc.w; - } - dc.w = blw = TEXTW(m->ltsymbol); -- drawtext(m->ltsymbol, dc.norm, False); -+ drawtext(dc.drawable, m->ltsymbol, dc.norm, False); - dc.x += dc.w; - x = dc.x; - if(m == selmon) { /* status is only drawn on selected monitor */ -@@ -747,19 +793,20 @@ drawbar(Monitor *m) { - dc.x = x; - dc.w = m->ww - x; - } -- drawtext(stext, dc.norm, False); -+ drawtext(dc.drawable, stext, dc.norm, False); - } - else - dc.x = m->ww; - if((dc.w = dc.x - x) > bh) { - dc.x = x; - if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -+ // col = m == selmon ? dc.sel : dc.norm; -+ // drawtext(dc.drawable, m->sel->name, col, False); -+ drawtext(dc.drawable, m->sel->name, dc.norm, False); - drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); - } - else -- drawtext(NULL, dc.norm, False); -+ drawtext(dc.drawable, NULL, dc.norm, False); - } - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); -@@ -774,6 +821,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ unsigned long *col; -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ dc.x = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ dc.w = m->tab_widths[i]; -+ col = (c == m->sel) ? dc.sel : dc.norm; -+ drawtext(dc.tabdrawable, c->name, col, 0); -+ dc.x += dc.w; -+ ++i; -+ } -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ dc.w = m->ww - view_info_w - dc.x; -+ drawtext(dc.tabdrawable, NULL, dc.norm, 0); -+ -+ /* view info */ -+ dc.x += dc.w; -+ dc.w = view_info_w; -+ drawtext(dc.tabdrawable, view_info, dc.norm, 0); -+ -+ XCopyArea(dpy, dc.tabdrawable, m->tabwin, dc.gc, 0, 0, m->ww, th, 0, 0); -+ XSync(dpy, False); -+} -+ -+ -+void - drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - int x; - -@@ -785,13 +930,14 @@ drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x); - } - -+ - void --drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -+drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert) { - char buf[256]; - int i, x, y, h, len, olen; - - XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -- XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); -+ XFillRectangle(dpy, drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); - if(!text) - return; - olen = strlen(text); -@@ -807,11 +953,12 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); - if(dc.font.set) -- XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); -+ XmbDrawString(dpy, drawable, dc.font.set, dc.gc, x, y, buf, len); - else -- XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -+ XDrawString(dpy, drawable, dc.gc, x, y, buf, len); - } - -+ - void - enternotify(XEvent *e) { - Client *c; -@@ -836,8 +983,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -862,6 +1011,7 @@ focus(Client *c) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -911,6 +1061,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -919,7 +1082,7 @@ getatomprop(Client *c, Atom prop) { - Atom da, atom = None; - - if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, -- &da, &di, &dl, &dl, &p) == Success && p) { -+ &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - XFree(p); - } -@@ -954,7 +1117,7 @@ getstate(Window w) { - Atom real; - - if(XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], -- &real, &format, &n, &extra, (unsigned char **)&p) != Success) -+ &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if(n != 0) - result = *p; -@@ -999,13 +1162,13 @@ grabbuttons(Client *c, Bool focused) { - if(buttons[i].click == ClkClientWin) - for(j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, -- buttons[i].mask | modifiers[j], -- c->win, False, BUTTONMASK, -- GrabModeAsync, GrabModeSync, None, None); -+ buttons[i].mask | modifiers[j], -+ c->win, False, BUTTONMASK, -+ GrabModeAsync, GrabModeSync, None, None); - } - else - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, -- BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); -+ BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - } - } - -@@ -1139,7 +1302,7 @@ manage(Window w, XWindowAttributes *wa) { - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) -- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); -+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; -@@ -1311,12 +1474,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1375,7 +1540,7 @@ resizemouse(const Arg *arg) { - ocx = c->x; - ocy = c->y; - if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, -- None, cursor[CurResize], CurrentTime) != GrabSuccess) -+ None, cursor[CurResize], CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { -@@ -1418,6 +1583,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1529,7 +1695,7 @@ void - setfullscreen(Client *c, Bool fullscreen) { - if(fullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); -+ PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = True; - c->oldstate = c->isfloating; - c->oldbw = c->bw; -@@ -1540,7 +1706,7 @@ setfullscreen(Client *c, Bool fullscreen) { - } - else { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)0, 0); -+ PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = False; - c->isfloating = c->oldstate; - c->bw = c->oldbw; -@@ -1594,6 +1760,7 @@ setup(void) { - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - bh = dc.h = dc.font.height + 2; -+ th = bh; - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1619,6 +1786,7 @@ setup(void) { - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); - dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); -+ dc.tabdrawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), th, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) -@@ -1632,7 +1800,7 @@ setup(void) { - /* select for events */ - wa.cursor = cursor[CurNormal]; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask -- |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; -+ |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); -@@ -1736,6 +1904,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1828,24 +2006,47 @@ updatebars(void) { - }; - for(m = mons; m; m = m->next) { - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), -- CopyFromParent, DefaultVisual(dpy, screen), -- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - Bool -@@ -1992,7 +2193,7 @@ updatesizehints(Client *c) { - else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->minw && c->maxh && c->minh -- && c->maxw == c->minw && c->maxh == c->minh); -+ && c->maxw == c->minw && c->maxh == c->minh); - } - - void -@@ -2073,7 +2274,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2a.diff b/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2a.diff @@ -1,720 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..666b9c0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,6 +12,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -25,7 +32,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -54,6 +61,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -101,5 +109,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 5268a06..19b4f1d 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1d78655..a892b7a 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -44,7 +44,7 @@ - #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) - #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))) -+ * 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 LENGTH(X) (sizeof X / sizeof X[0]) - #define MAX(A, B) ((A) > (B) ? (A) : (B)) -@@ -62,7 +62,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -102,6 +102,7 @@ typedef struct { - unsigned long norm[ColLast]; - unsigned long sel[ColLast]; - Drawable drawable; -+ Drawable tabdrawable; - GC gc; - struct { - int ascent; -@@ -124,24 +125,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -178,11 +187,15 @@ static void die(const char *errstr, ...); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); --static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); -+static void drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert); -+//static void drawtabtext(const char *text, unsigned long col[ColLast], Bool invert); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); -+static void focuswin(const Arg* arg); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -@@ -229,6 +242,7 @@ static void tagmon(const Arg *arg); - static int textnw(const char *text, unsigned int len); - static void tile(Monitor *); - static void togglebar(const Arg *arg); -+static void tabmode(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); -@@ -258,6 +272,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -405,6 +420,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -454,14 +472,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -491,6 +527,7 @@ cleanup(void) { - XFreeFont(dpy, dc.font.xfont); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XFreePixmap(dpy, dc.drawable); -+ XFreePixmap(dpy, dc.tabdrawable); - XFreeGC(dpy, dc.gc); - XFreeCursor(dpy, cursor[CurNormal]); - XFreeCursor(dpy, cursor[CurResize]); -@@ -513,6 +550,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -538,7 +577,7 @@ clientmessage(XEvent *e) { - if(cme->message_type == netatom[NetWMState]) { - if(cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ -- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); -+ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } - else if(cme->message_type == netatom[NetActiveWindow]) { - if(!ISVISIBLE(c)) { -@@ -581,9 +620,13 @@ configurenotify(XEvent *e) { - if(dc.drawable != 0) - XFreePixmap(dpy, dc.drawable); - dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); -+ if(dc.tabdrawable != 0) -+ XFreePixmap(dpy, dc.tabdrawable); -+ dc.tabdrawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); - updatebars(); -- for(m = mons; m; m = m->next) -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -653,7 +696,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -731,13 +777,13 @@ drawbar(Monitor *m) { - for(i = 0; i < LENGTH(tags); i++) { - dc.w = TEXTW(tags[i]); - col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; -- drawtext(tags[i], col, urg & 1 << i); -+ drawtext(dc.drawable, tags[i], col, urg & 1 << i); - drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, -- occ & 1 << i, urg & 1 << i, col); -+ occ & 1 << i, urg & 1 << i, col); - dc.x += dc.w; - } - dc.w = blw = TEXTW(m->ltsymbol); -- drawtext(m->ltsymbol, dc.norm, False); -+ drawtext(dc.drawable, m->ltsymbol, dc.norm, False); - dc.x += dc.w; - x = dc.x; - if(m == selmon) { /* status is only drawn on selected monitor */ -@@ -747,19 +793,20 @@ drawbar(Monitor *m) { - dc.x = x; - dc.w = m->ww - x; - } -- drawtext(stext, dc.norm, False); -+ drawtext(dc.drawable, stext, dc.norm, False); - } - else - dc.x = m->ww; - if((dc.w = dc.x - x) > bh) { - dc.x = x; - if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -+ // col = m == selmon ? dc.sel : dc.norm; -+ // drawtext(dc.drawable, m->sel->name, col, False); -+ drawtext(dc.drawable, m->sel->name, dc.norm, False); - drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); - } - else -- drawtext(NULL, dc.norm, False); -+ drawtext(dc.drawable, NULL, dc.norm, False); - } - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); -@@ -774,6 +821,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ unsigned long *col; -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ dc.x = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ dc.w = m->tab_widths[i]; -+ col = (c == m->sel) ? dc.sel : dc.norm; -+ drawtext(dc.tabdrawable, c->name, col, 0); -+ dc.x += dc.w; -+ ++i; -+ } -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ dc.w = m->ww - view_info_w - dc.x; -+ drawtext(dc.tabdrawable, NULL, dc.norm, 0); -+ -+ /* view info */ -+ dc.x += dc.w; -+ dc.w = view_info_w; -+ drawtext(dc.tabdrawable, view_info, dc.norm, 0); -+ -+ XCopyArea(dpy, dc.tabdrawable, m->tabwin, dc.gc, 0, 0, m->ww, th, 0, 0); -+ XSync(dpy, False); -+} -+ -+ -+void - drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - int x; - -@@ -785,13 +930,14 @@ drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x); - } - -+ - void --drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -+drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert) { - char buf[256]; - int i, x, y, h, len, olen; - - XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -- XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); -+ XFillRectangle(dpy, drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); - if(!text) - return; - olen = strlen(text); -@@ -807,11 +953,12 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); - if(dc.font.set) -- XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); -+ XmbDrawString(dpy, drawable, dc.font.set, dc.gc, x, y, buf, len); - else -- XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -+ XDrawString(dpy, drawable, dc.gc, x, y, buf, len); - } - -+ - void - enternotify(XEvent *e) { - Client *c; -@@ -836,8 +983,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -862,6 +1011,7 @@ focus(Client *c) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -911,6 +1061,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -919,7 +1082,7 @@ getatomprop(Client *c, Atom prop) { - Atom da, atom = None; - - if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, -- &da, &di, &dl, &dl, &p) == Success && p) { -+ &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - XFree(p); - } -@@ -954,7 +1117,7 @@ getstate(Window w) { - Atom real; - - if(XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], -- &real, &format, &n, &extra, (unsigned char **)&p) != Success) -+ &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if(n != 0) - result = *p; -@@ -999,13 +1162,13 @@ grabbuttons(Client *c, Bool focused) { - if(buttons[i].click == ClkClientWin) - for(j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, -- buttons[i].mask | modifiers[j], -- c->win, False, BUTTONMASK, -- GrabModeAsync, GrabModeSync, None, None); -+ buttons[i].mask | modifiers[j], -+ c->win, False, BUTTONMASK, -+ GrabModeAsync, GrabModeSync, None, None); - } - else - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, -- BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); -+ BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - } - } - -@@ -1139,7 +1302,7 @@ manage(Window w, XWindowAttributes *wa) { - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) -- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); -+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; -@@ -1311,12 +1474,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1375,7 +1540,7 @@ resizemouse(const Arg *arg) { - ocx = c->x; - ocy = c->y; - if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, -- None, cursor[CurResize], CurrentTime) != GrabSuccess) -+ None, cursor[CurResize], CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { -@@ -1418,6 +1583,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1529,7 +1695,7 @@ void - setfullscreen(Client *c, Bool fullscreen) { - if(fullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); -+ PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = True; - c->oldstate = c->isfloating; - c->oldbw = c->bw; -@@ -1540,7 +1706,7 @@ setfullscreen(Client *c, Bool fullscreen) { - } - else { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)0, 0); -+ PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = False; - c->isfloating = c->oldstate; - c->bw = c->oldbw; -@@ -1594,6 +1760,7 @@ setup(void) { - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - bh = dc.h = dc.font.height + 2; -+ th = bh; - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1619,6 +1786,7 @@ setup(void) { - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); - dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); -+ dc.tabdrawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), th, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) -@@ -1632,7 +1800,7 @@ setup(void) { - /* select for events */ - wa.cursor = cursor[CurNormal]; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask -- |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; -+ |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); -@@ -1736,6 +1904,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1828,24 +2006,47 @@ updatebars(void) { - }; - for(m = mons; m; m = m->next) { - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), -- CopyFromParent, DefaultVisual(dpy, screen), -- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - Bool -@@ -1992,7 +2193,7 @@ updatesizehints(Client *c) { - else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->minw && c->maxh && c->minh -- && c->maxw == c->minw && c->maxh == c->minh); -+ && c->maxw == c->minw && c->maxh == c->minh); - } - - void -@@ -2073,7 +2274,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2b.diff @@ -1,720 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..666b9c0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,6 +12,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -25,7 +32,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -54,6 +61,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -101,5 +109,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 5268a06..19b4f1d 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1d78655..a892b7a 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -44,7 +44,7 @@ - #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) - #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))) -+ * 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 LENGTH(X) (sizeof X / sizeof X[0]) - #define MAX(A, B) ((A) > (B) ? (A) : (B)) -@@ -62,7 +62,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -102,6 +102,7 @@ typedef struct { - unsigned long norm[ColLast]; - unsigned long sel[ColLast]; - Drawable drawable; -+ Drawable tabdrawable; - GC gc; - struct { - int ascent; -@@ -124,24 +125,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -178,11 +187,15 @@ static void die(const char *errstr, ...); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); --static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); -+static void drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert); -+//static void drawtabtext(const char *text, unsigned long col[ColLast], Bool invert); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); -+static void focuswin(const Arg* arg); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -@@ -229,6 +242,7 @@ static void tagmon(const Arg *arg); - static int textnw(const char *text, unsigned int len); - static void tile(Monitor *); - static void togglebar(const Arg *arg); -+static void tabmode(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); -@@ -258,6 +272,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -405,6 +420,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -454,14 +472,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -491,6 +527,7 @@ cleanup(void) { - XFreeFont(dpy, dc.font.xfont); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XFreePixmap(dpy, dc.drawable); -+ XFreePixmap(dpy, dc.tabdrawable); - XFreeGC(dpy, dc.gc); - XFreeCursor(dpy, cursor[CurNormal]); - XFreeCursor(dpy, cursor[CurResize]); -@@ -513,6 +550,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -538,7 +577,7 @@ clientmessage(XEvent *e) { - if(cme->message_type == netatom[NetWMState]) { - if(cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ -- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); -+ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } - else if(cme->message_type == netatom[NetActiveWindow]) { - if(!ISVISIBLE(c)) { -@@ -581,9 +620,13 @@ configurenotify(XEvent *e) { - if(dc.drawable != 0) - XFreePixmap(dpy, dc.drawable); - dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); -+ if(dc.tabdrawable != 0) -+ XFreePixmap(dpy, dc.tabdrawable); -+ dc.tabdrawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); - updatebars(); -- for(m = mons; m; m = m->next) -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -653,7 +696,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -731,13 +777,13 @@ drawbar(Monitor *m) { - for(i = 0; i < LENGTH(tags); i++) { - dc.w = TEXTW(tags[i]); - col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; -- drawtext(tags[i], col, urg & 1 << i); -+ drawtext(dc.drawable, tags[i], col, urg & 1 << i); - drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, -- occ & 1 << i, urg & 1 << i, col); -+ occ & 1 << i, urg & 1 << i, col); - dc.x += dc.w; - } - dc.w = blw = TEXTW(m->ltsymbol); -- drawtext(m->ltsymbol, dc.norm, False); -+ drawtext(dc.drawable, m->ltsymbol, dc.norm, False); - dc.x += dc.w; - x = dc.x; - if(m == selmon) { /* status is only drawn on selected monitor */ -@@ -747,19 +793,20 @@ drawbar(Monitor *m) { - dc.x = x; - dc.w = m->ww - x; - } -- drawtext(stext, dc.norm, False); -+ drawtext(dc.drawable, stext, dc.norm, False); - } - else - dc.x = m->ww; - if((dc.w = dc.x - x) > bh) { - dc.x = x; - if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -+ // col = m == selmon ? dc.sel : dc.norm; -+ // drawtext(dc.drawable, m->sel->name, col, False); -+ drawtext(dc.drawable, m->sel->name, dc.norm, False); - drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); - } - else -- drawtext(NULL, dc.norm, False); -+ drawtext(dc.drawable, NULL, dc.norm, False); - } - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); -@@ -774,6 +821,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ unsigned long *col; -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ dc.x = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ dc.w = m->tab_widths[i]; -+ col = (c == m->sel) ? dc.sel : dc.norm; -+ drawtext(dc.tabdrawable, c->name, col, 0); -+ dc.x += dc.w; -+ ++i; -+ } -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ dc.w = m->ww - view_info_w - dc.x; -+ drawtext(dc.tabdrawable, NULL, dc.norm, 0); -+ -+ /* view info */ -+ dc.x += dc.w; -+ dc.w = view_info_w; -+ drawtext(dc.tabdrawable, view_info, dc.norm, 0); -+ -+ XCopyArea(dpy, dc.tabdrawable, m->tabwin, dc.gc, 0, 0, m->ww, th, 0, 0); -+ XSync(dpy, False); -+} -+ -+ -+void - drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - int x; - -@@ -785,13 +930,14 @@ drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x); - } - -+ - void --drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -+drawtext(Drawable drawable, const char *text, unsigned long col[ColLast], Bool invert) { - char buf[256]; - int i, x, y, h, len, olen; - - XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -- XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); -+ XFillRectangle(dpy, drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); - if(!text) - return; - olen = strlen(text); -@@ -807,11 +953,12 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); - if(dc.font.set) -- XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); -+ XmbDrawString(dpy, drawable, dc.font.set, dc.gc, x, y, buf, len); - else -- XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -+ XDrawString(dpy, drawable, dc.gc, x, y, buf, len); - } - -+ - void - enternotify(XEvent *e) { - Client *c; -@@ -836,8 +983,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -862,6 +1011,7 @@ focus(Client *c) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -911,6 +1061,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -919,7 +1082,7 @@ getatomprop(Client *c, Atom prop) { - Atom da, atom = None; - - if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, -- &da, &di, &dl, &dl, &p) == Success && p) { -+ &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - XFree(p); - } -@@ -954,7 +1117,7 @@ getstate(Window w) { - Atom real; - - if(XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], -- &real, &format, &n, &extra, (unsigned char **)&p) != Success) -+ &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if(n != 0) - result = *p; -@@ -999,13 +1162,13 @@ grabbuttons(Client *c, Bool focused) { - if(buttons[i].click == ClkClientWin) - for(j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, -- buttons[i].mask | modifiers[j], -- c->win, False, BUTTONMASK, -- GrabModeAsync, GrabModeSync, None, None); -+ buttons[i].mask | modifiers[j], -+ c->win, False, BUTTONMASK, -+ GrabModeAsync, GrabModeSync, None, None); - } - else - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, -- BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); -+ BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - } - } - -@@ -1139,7 +1302,7 @@ manage(Window w, XWindowAttributes *wa) { - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) -- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); -+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; -@@ -1311,12 +1474,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1375,7 +1540,7 @@ resizemouse(const Arg *arg) { - ocx = c->x; - ocy = c->y; - if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, -- None, cursor[CurResize], CurrentTime) != GrabSuccess) -+ None, cursor[CurResize], CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { -@@ -1418,6 +1583,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1529,7 +1695,7 @@ void - setfullscreen(Client *c, Bool fullscreen) { - if(fullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); -+ PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = True; - c->oldstate = c->isfloating; - c->oldbw = c->bw; -@@ -1540,7 +1706,7 @@ setfullscreen(Client *c, Bool fullscreen) { - } - else { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, -- PropModeReplace, (unsigned char*)0, 0); -+ PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = False; - c->isfloating = c->oldstate; - c->bw = c->oldbw; -@@ -1594,6 +1760,7 @@ setup(void) { - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - bh = dc.h = dc.font.height + 2; -+ th = bh; - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1619,6 +1786,7 @@ setup(void) { - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); - dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); -+ dc.tabdrawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), th, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) -@@ -1632,7 +1800,7 @@ setup(void) { - /* select for events */ - wa.cursor = cursor[CurNormal]; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask -- |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; -+ |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); -@@ -1736,6 +1904,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1828,24 +2006,47 @@ updatebars(void) { - }; - for(m = mons; m; m = m->next) { - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), -- CopyFromParent, DefaultVisual(dpy, screen), -- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - Bool -@@ -1992,7 +2193,7 @@ updatesizehints(Client *c) { - else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->minw && c->maxh && c->minh -- && c->maxw == c->minw && c->maxh == c->minh); -+ && c->maxw == c->minw && c->maxh == c->minh); - } - - void -@@ -2073,7 +2274,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-6.0-winview.diff b/dwm.suckless.org/patches/historical/dwm-6.0-winview.diff @@ -1,65 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..3ba0efe 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -84,6 +84,7 @@ static Key keys[] = { - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -+ { MODKEY, XK_o, winview, {0} }, - }; - - /* button definitions */ -diff --git a/dwm.1 b/dwm.1 -index 5268a06..1188c82 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -104,6 +104,9 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-o -+Select view of the window in focus. The list of tags to be displayed is matched to the window tag list. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1d78655..abf944c 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -247,6 +247,7 @@ static void updatewmhints(Client *c); - static void view(const Arg *arg); - static Client *wintoclient(Window w); - static Monitor *wintomon(Window w); -+static void winview(const Arg* arg); - static int xerror(Display *dpy, XErrorEvent *ee); - static int xerrordummy(Display *dpy, XErrorEvent *ee); - static int xerrorstart(Display *dpy, XErrorEvent *ee); -@@ -2080,6 +2081,26 @@ wintomon(Window w) { - return selmon; - } - -+/* Selects for the view of the focused window. The list of tags */ -+/* to be displayed is matched to the focused window tag list. */ -+void -+winview(const Arg* arg){ -+ Window win, win_r, win_p, *win_c; -+ unsigned nc; -+ int unused; -+ Client* c; -+ Arg a; -+ -+ if (!XGetInputFocus(dpy, &win, &unused)) return; -+ while(XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc) -+ && win_p != win_r) win = win_p; -+ -+ if (!(c = wintoclient(win))) return; -+ -+ a.ui = c->tags; -+ view(&a); -+} -+ - /* 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/historical/dwm-fancybar-5.6.1.diff b/dwm.suckless.org/patches/historical/dwm-fancybar-5.6.1.diff @@ -1,121 +0,0 @@ -diff -r e47a47bd3ed4 dwm.c ---- a/dwm.c Tue Jul 21 10:57:54 2009 +0100 -+++ b/dwm.c Mon Aug 24 18:28:57 2009 +0200 -@@ -169,6 +169,7 @@ - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawvline(unsigned long col[ColLast]); - static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); - static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); - static void enternotify(XEvent *e); -@@ -648,10 +649,11 @@ - - void - drawbar(Monitor *m) { -- int x; -+ int x, ow, mw = 0, extra, tw; - unsigned int i, n = 0, occ = 0, urg = 0; - unsigned long *col; -- Client *c; -+ Client *c, *firstvis, *lastvis = NULL; -+ DC seldc; - - for(c = m->clients; c; c = c->next) { - if(ISVISIBLE(c)) -@@ -689,16 +691,62 @@ - } - else - dc.x = m->ww; -- if((dc.w = dc.x - x) > bh) { -- dc.x = x; -- if(m->sel) { -- col = m == selmon ? dc.sel : dc.norm; -- drawtext(m->sel->name, col, False); -- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); -+ -+ for(c = m->clients; c && !ISVISIBLE(c); c = c->next); -+ firstvis = c; -+ -+ col = m == selmon ? dc.sel : dc.norm; -+ dc.w = dc.x - x; -+ dc.x = x; -+ -+ if(n > 0) { -+ mw = dc.w / n; -+ extra = 0; -+ seldc = dc; -+ i = 0; -+ -+ while(c) { -+ lastvis = c; -+ tw = TEXTW(c->name); -+ if(tw < mw) extra += (mw - tw); else i++; -+ for(c = c->next; c && !ISVISIBLE(c); c = c->next); - } -- else -+ -+ if(i > 0) mw += extra / i; -+ -+ c = firstvis; -+ x = dc.x; -+ } -+ -+ while(dc.w > bh) { -+ if(c) { -+ ow = dc.w; -+ tw = TEXTW(c->name); -+ dc.w = MIN(ow, tw); -+ -+ if(dc.w > mw) dc.w = mw; -+ if(m->sel == c) seldc = dc; -+ if(c == lastvis) dc.w = ow; -+ -+ drawtext(c->name, col, False); -+ if(c != firstvis) drawvline(col); -+ drawsquare(c->isfixed, c->isfloating, False, col); -+ -+ dc.x += dc.w; -+ dc.w = ow - dc.w; -+ for(c = c->next; c && !ISVISIBLE(c); c = c->next); -+ } else { - drawtext(NULL, dc.norm, False); -+ break; -+ } - } -+ -+ if(m == selmon && m->sel && ISVISIBLE(m->sel)) { -+ dc = seldc; -+ drawtext(m->sel->name, col, True); -+ drawsquare(m->sel->isfixed, m->sel->isfloating, True, col); -+ } -+ - XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); - XSync(dpy, False); - } -@@ -709,6 +757,15 @@ - - for(m = mons; m; m = m->next) - drawbar(m); -+} -+ -+void -+drawvline(unsigned long col[ColLast]) { -+ XGCValues gcv; -+ -+ gcv.foreground = col[ColFG]; -+ XChangeGC(dpy, dc.gc, GCForeground, &gcv); -+ XDrawLine(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.x, dc.y + (dc.font.ascent + dc.font.descent + 2)); - } - - void -@@ -1235,8 +1292,7 @@ - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); -- if(c == selmon->sel) -- drawbars(); -+ drawbars(); - } - } - } diff --git a/dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff b/dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff @@ -1,418 +0,0 @@ -diff -up ../dwm-5.8.1-0/config.def.h ./config.def.h ---- ../dwm-5.8.1-0/config.def.h 2010-05-29 13:49:12.000000000 +0200 -+++ ./config.def.h 2010-05-31 15:18:43.686311000 +0200 -@@ -25,6 +25,11 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const int layoutaxis[] = { -+ 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ -+ 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ -+ 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ -+}; - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -81,6 +86,12 @@ static Key keys[] = { - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -+ { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0} }, /* 0 = layout axis */ -+ { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1} }, /* 1 = master axis */ -+ { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2} }, /* 2 = stack axis */ -+ { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, -+ { MODKEY|ControlMask, XK_j, shiftmastersplit, {.i = -1} }, /* reduce the number of tiled clients in the master area */ -+ { MODKEY|ControlMask, XK_k, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ - }; - - /* button definitions */ -diff -up ../dwm-5.8.1-0/dwm.c ./dwm.c ---- ../dwm-5.8.1-0/dwm.c 2010-05-29 13:49:12.000000000 +0200 -+++ ./dwm.c 2010-05-31 16:02:14.553316000 +0200 -@@ -120,26 +120,6 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - --struct Monitor { -- char ltsymbol[16]; -- float mfact; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; --}; -- - typedef struct { - const char *class; - const char *instance; -@@ -193,6 +173,7 @@ static void killclient(const Arg *arg); - static void manage(Window w, XWindowAttributes *wa); - static void mappingnotify(XEvent *e); - static void maprequest(XEvent *e); -+static void mirrorlayout(const Arg *arg); - static void monocle(Monitor *m); - static void movemouse(const Arg *arg); - static Client *nexttiled(Client *c); -@@ -202,6 +183,7 @@ static void quit(const Arg *arg); - static void resize(Client *c, int x, int y, int w, int h, Bool interact); - static void resizemouse(const Arg *arg); - static void restack(Monitor *m); -+static void rotatelayoutaxis(const Arg *arg); - static void run(void); - static void scan(void); - static void sendmon(Client *c, Monitor *m); -@@ -209,6 +191,7 @@ static void setclientstate(Client *c, lo - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -+static void shiftmastersplit(const Arg *arg); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -@@ -275,6 +258,34 @@ static Window root; - - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; -+struct Monitor { -+ char ltsymbol[16]; -+ float mfact; -+ double mfacts[LENGTH(tags) + 1]; -+ int ltaxis[3]; -+ int ltaxes[LENGTH(tags) + 1][3]; -+ int num; -+ int curtag; -+ int prevtag; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int msplit; -+ unsigned int msplits[LENGTH(tags) + 1]; -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool showbars[LENGTH(tags) + 1]; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+ const Layout *lts[LENGTH(tags) + 1]; -+}; - - /* function implementations */ - void -@@ -616,6 +627,10 @@ createmon(void) { - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -+ m->ltaxis[0] = layoutaxis[0]; -+ m->ltaxis[1] = layoutaxis[1]; -+ m->ltaxis[2] = layoutaxis[2]; -+ m->msplit = 1; - return m; - } - -@@ -1173,6 +1188,15 @@ maprequest(XEvent *e) { - } - - void -+mirrorlayout(const Arg *arg) { -+ if(!selmon->lt[selmon->sellt]->arrange) -+ return; -+ selmon->ltaxis[0] *= -1; -+ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0]; -+ arrange(selmon); -+} -+ -+void - monocle(Monitor *m) { - unsigned int n = 0; - Client *c; -@@ -1387,6 +1411,21 @@ restack(Monitor *m) { - } - - void -+rotatelayoutaxis(const Arg *arg) { -+ if(!selmon->lt[selmon->sellt]->arrange) -+ return; -+ if(arg->i == 0) { -+ if(selmon->ltaxis[0] > 0) -+ selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 2 ? 1 : selmon->ltaxis[0] + 1; -+ else -+ selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -2 ? -1 : selmon->ltaxis[0] - 1; -+ } else -+ selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 3 ? 1 : selmon->ltaxis[arg->i] + 1; -+ selmon->ltaxes[selmon->curtag][arg->i] = selmon->ltaxis[arg->i]; -+ arrange(selmon); -+} -+ -+void - run(void) { - XEvent ev; - /* main event loop */ -@@ -1451,7 +1490,7 @@ setlayout(const Arg *arg) { - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if(arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) - arrange(selmon); -@@ -1469,14 +1508,16 @@ setmfact(const Arg *arg) { - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->mfacts[selmon->curtag] = f; - arrange(selmon); - } - - void - setup(void) { - XSetWindowAttributes wa; -- -+ Monitor *m; -+ unsigned int i; -+ - /* clean up any zombies immediately */ - sigchld(0); - -@@ -1511,7 +1552,19 @@ setup(void) { - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -- /* init bars */ -+ /* init tags, bars, layouts, axes, msplits and mfacts */ -+ for(m = mons; m; m = m->next) { -+ m->curtag = m->prevtag = 1; -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ m->showbars[i] = m->showbar; -+ m->lts[i] = &layouts[0]; -+ m->mfacts[i] = m->mfact; -+ m->ltaxes[i][0] = m->ltaxis[0]; -+ m->ltaxes[i][1] = m->ltaxis[1]; -+ m->ltaxes[i][2] = m->ltaxis[2]; -+ m->msplits[i] = m->msplit; -+ } -+ } - updatebars(); - updatestatus(); - /* EWMH support per view */ -@@ -1528,6 +1581,19 @@ setup(void) { - } - - void -+shiftmastersplit(const Arg *arg) { -+ unsigned int n; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(selmon->clients); c; c = nexttiled(c->next), n++); -+ if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->msplit + arg->i < 1 || selmon->msplit + arg->i > n) -+ return; -+ selmon->msplit += arg->i; -+ selmon->msplits[selmon->curtag] = selmon->msplit; -+ arrange(selmon); -+} -+ -+void - showhide(Client *c) { - if(!c) - return; -@@ -1592,37 +1658,95 @@ textnw(const char *text, unsigned int le - - void - tile(Monitor *m) { -- int x, y, h, w, mw; -- unsigned int i, n; -+ char sym1 = 61, sym2 = 93, sym3 = 61, sym; -+ int x1 = m->wx, y1 = m->wy, h1 = m->wh, w1 = m->ww, X1 = x1 + w1, Y1 = y1 + h1; -+ int x2 = m->wx, y2 = m->wy, h2 = m->wh, w2 = m->ww, X2 = x2 + w2, Y2 = y2 + h2; -+ unsigned int i, n, n1, n2; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -+ if(m->msplit > n) -+ m->msplit = (n == 0) ? 1 : n; -+ if(n == 0 && m->ltaxis[1] != 3) -+ return; -+ /* layout symbol */ -+ if(abs(m->ltaxis[0]) == m->ltaxis[1]) /* explicitly: ((abs(m->ltaxis[0]) == 1 && m->ltaxis[1] == 1) || (abs(m->ltaxis[0]) == 2 && m->ltaxis[1] == 2)) */ -+ sym1 = 124; -+ if(abs(m->ltaxis[0]) == m->ltaxis[2]) -+ sym3 = 124; -+ if(m->ltaxis[1] == 3) -+ sym1 = (n == 0) ? 0 : m->msplit; -+ if(m->ltaxis[2] == 3) -+ sym3 = (n == 0) ? 0 : n - m->msplit; -+ if(m->ltaxis[0] < 0) { -+ sym = sym1; -+ sym1 = sym3; -+ sym2 = 91; -+ sym3 = sym; -+ } -+ if(m->msplit == 1) { -+ if(m->ltaxis[0] > 0) -+ sym1 = 91; -+ else -+ sym3 = 93; -+ } -+ if(m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[2] == 3) -+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3); -+ else if((m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] > 0) || (m->ltaxis[2] == 3 && m->ltaxis[0] < 0)) -+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3); -+ else if((m->ltaxis[2] == 3 && m->ltaxis[0] > 0) || (m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] < 0)) -+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, sym3); -+ else -+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); - if(n == 0) - return; -+ /* master and stack area */ -+ if(abs(m->ltaxis[0]) == 1 && n > m->msplit) { -+ w1 *= m->mfact; -+ w2 -= w1; -+ x1 += (m->ltaxis[0] < 0) ? w2 : 0; -+ x2 += (m->ltaxis[0] < 0) ? 0 : w1; -+ X1 = x1 + w1; -+ X2 = x2 + w2; -+ } else if(abs(m->ltaxis[0]) == 2 && n > m->msplit) { -+ h1 *= m->mfact; -+ h2 -= h1; -+ y1 += (m->ltaxis[0] < 0) ? h2 : 0; -+ y2 += (m->ltaxis[0] < 0) ? 0 : h1; -+ Y1 = y1 + h1; -+ Y2 = y2 + h2; -+ } - /* master */ -- c = nexttiled(m->clients); -- mw = m->mfact * m->ww; -- resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw, False); -- if(--n == 0) -- return; -- /* tile stack */ -- x = (m->wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : m->wx + mw; -- y = m->wy; -- w = (m->wx + mw > c->x + c->w) ? m->wx + m->ww - x : m->ww - mw; -- h = m->wh / n; -- if(h < bh) -- h = m->wh; -- for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { -- resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) -- ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); -- if(h != m->wh) -- y = c->y + HEIGHT(c); -+ n1 = (m->ltaxis[1] != 1 || w1 / m->msplit < bh) ? 1 : m->msplit; -+ n2 = (m->ltaxis[1] != 2 || h1 / m->msplit < bh) ? 1 : m->msplit; -+ for(i = 0, c = nexttiled(m->clients); i < m->msplit; c = nexttiled(c->next), i++) { -+ resize(c, x1, y1, -+ (m->ltaxis[1] == 1 && i + 1 == m->msplit) ? X1 - x1 - 2 * c->bw : w1 / n1 - 2 * c->bw, -+ (m->ltaxis[1] == 2 && i + 1 == m->msplit) ? Y1 - y1 - 2 * c->bw : h1 / n2 - 2 * c->bw, False); -+ if(n1 > 1) -+ x1 = c->x + WIDTH(c); -+ if(n2 > 1) -+ y1 = c->y + HEIGHT(c); -+ } -+ /* stack */ -+ if(n > m->msplit) { -+ n1 = (m->ltaxis[2] != 1 || w2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; -+ n2 = (m->ltaxis[2] != 2 || h2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; -+ for(i = 0; c; c = nexttiled(c->next), i++) { -+ resize(c, x2, y2, -+ (m->ltaxis[2] == 1 && i + 1 == n - m->msplit) ? X2 - x2 - 2 * c->bw : w2 / n1 - 2 * c->bw, -+ (m->ltaxis[2] == 2 && i + 1 == n - m->msplit) ? Y2 - y2 - 2 * c->bw : h2 / n2 - 2 * c->bw, False); -+ if(n1 > 1) -+ x2 = c->x + WIDTH(c); -+ if(n2 > 1) -+ y2 = c->y + HEIGHT(c); -+ } - } - } - - void - togglebar(const Arg *arg) { -- selmon->showbar = !selmon->showbar; -+ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); - arrange(selmon); -@@ -1642,12 +1766,31 @@ togglefloating(const Arg *arg) { - void - toggletag(const Arg *arg) { - unsigned int newtags; -+ unsigned int i; - - if(!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { - selmon->sel->tags = newtags; -+ if(newtags == ~0) { -+ selmon->prevtag = selmon->curtag; -+ selmon->curtag = 0; -+ } -+ if(!(newtags & 1 << (selmon->curtag - 1))) { -+ selmon->prevtag = selmon->curtag; -+ for (i=0; !(newtags & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ selmon->sel->tags = newtags; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if (selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); -+ selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; -+ selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; -+ selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; -+ selmon->msplit = selmon->msplits[selmon->curtag]; - arrange(selmon); - } - } -@@ -1914,11 +2057,33 @@ updatewmhints(Client *c) { - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->prevtag = selmon->curtag; -+ if(arg->ui == ~0) -+ selmon->curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ } else { -+ selmon->prevtag = selmon->curtag ^ selmon->prevtag; -+ selmon->curtag ^= selmon->prevtag; -+ selmon->prevtag = selmon->curtag ^ selmon->prevtag; -+ } -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if(selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); -+ selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; -+ selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; -+ selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; -+ selmon->msplit = selmon->msplits[selmon->curtag]; - arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-gap-5.7.2.diff b/dwm.suckless.org/patches/historical/dwm-gap-5.7.2.diff @@ -1,23 +0,0 @@ ---- a/dwm.c 2009-09-17 10:48:57.000000000 +0200 -+++ b/dwm.c 2009-09-16 18:54:37.000000000 +0200 -@@ -1270,10 +1270,10 @@ - XWindowChanges wc; - - if(applysizehints(c, &x, &y, &w, &h, interact)) { -- c->x = wc.x = x; -- c->y = wc.y = y; -- c->w = wc.width = w; -- c->h = wc.height = h; -+ c->x = wc.x = x + gappx; -+ c->y = wc.y = y + gappx; -+ c->w = wc.width = w - 2 * gappx ; -+ c->h = wc.height = h - 2 * gappx ; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - -diff -r 72e52c5333ef config.def.h ---- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 -+++ b/config.def.h Tue Dec 15 18:39:44 2009 +0100 -@@ -7,14 +7,15 @@ -+static const unsigned int gappx = 4; /* gap pixel between windows */ diff --git a/dwm.suckless.org/patches/historical/dwm-git-20100321-focusonclick.diff b/dwm.suckless.org/patches/historical/dwm-git-20100321-focusonclick.diff @@ -1,38 +0,0 @@ -diff -r 72e52c5333ef config.def.h ---- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 -+++ b/config.def.h Sun Mar 21 00:38:45 2010 +0100 -@@ -12,6 +12,7 @@ - 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 Bool focusonclick = True; /* Change focus only on click */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -diff -r 72e52c5333ef dwm.c ---- a/dwm.c Wed Nov 25 13:56:17 2009 +0000 -+++ b/dwm.c Sun Mar 21 00:38:45 2010 +0100 -@@ -791,14 +791,16 @@ - - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; -- if((m = wintomon(ev->window)) && m != selmon) { -- unfocus(selmon->sel); -- selmon = m; -+ if (!focusonclick) { -+ if((m = wintomon(ev->window)) && m != selmon) { -+ unfocus(selmon->sel); -+ selmon = m; -+ } -+ if((c = wintoclient(ev->window))) -+ focus(c); -+ else -+ focus(NULL); - } -- if((c = wintoclient(ev->window))) -- focus(c); -- else -- focus(NULL); - } - - void diff --git a/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-pertag-tab-v2a.diff b/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-pertag-tab-v2a.diff @@ -1,672 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 875885b..406fdd8 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,10 +12,22 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* default layout per tags */ -+/* The first element is for all-tag view, following i-th element corresponds to */ -+/* tags[i]. Layout is referred using the layouts array index.*/ -+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -@@ -29,7 +41,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -59,6 +71,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -106,5 +119,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..9f5c274 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..a9a11b2 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -63,7 +63,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -110,25 +110,36 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+typedef struct Pertag Pertag; -+ -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; -+ Pertag *pertag; - }; - - typedef struct { -@@ -163,12 +174,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -205,6 +219,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -239,6 +254,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -270,6 +286,15 @@ static Window root; - /* 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]; }; - -@@ -389,6 +414,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +465,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -499,6 +545,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -567,8 +615,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -631,6 +682,7 @@ configurerequest(XEvent *e) { - Monitor * - createmon(void) { - Monitor *m; -+ int i; - - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); -@@ -638,10 +690,31 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -- m->lt[0] = &layouts[0]; -+ m->ntabs = 0; -+ m->sellt = 0; -+ m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)]; - 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; - } - -@@ -750,6 +823,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -773,8 +944,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -801,6 +974,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -851,6 +1025,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -958,7 +1145,7 @@ grabkeys(void) { - - 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); - } - -@@ -1212,12 +1399,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1321,6 +1510,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1462,10 +1652,13 @@ setfullscreen(Client *c, Bool fullscreen) { - - 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); -@@ -1483,7 +1676,7 @@ setmfact(const Arg *arg) { - 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); - } - -@@ -1501,6 +1694,7 @@ setup(void) { - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - bh = fnt->h + 2; -+ th = bh; - drw = drw_create(dpy, screen, root, sw, sh); - drw_setfont(drw, fnt); - updategeom(); -@@ -1627,13 +1821,23 @@ tile(Monitor *m) { - - 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); - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1663,9 +1867,29 @@ toggletag(const Arg *arg) { - 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); - } -@@ -1737,20 +1961,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1960,11 +2207,33 @@ updatewmhints(Client *c) { - - 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); - } -@@ -1990,7 +2259,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-tab-v2a.diff b/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-tab-v2a.diff @@ -1,505 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 875885b..4f653c5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -12,6 +12,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -29,7 +36,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -59,6 +66,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -106,5 +114,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..9f5c274 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 1bbb4b3..b73d6ca 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -63,7 +63,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -110,24 +110,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -163,12 +171,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -205,6 +216,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -239,6 +251,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -389,6 +402,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +453,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -499,6 +533,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -567,8 +603,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -638,7 +677,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -750,6 +792,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -773,8 +913,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -801,6 +943,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -851,6 +994,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -1212,12 +1368,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1321,6 +1479,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1501,6 +1660,7 @@ setup(void) { - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - bh = fnt->h + 2; -+ th = bh; - drw = drw_create(dpy, screen, root, sw, sh); - drw_setfont(drw, fnt); - updategeom(); -@@ -1634,6 +1794,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1737,20 +1907,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1990,7 +2183,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-pertag-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-pertag-tab-v2b.diff @@ -1,693 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index eaae8f3..a07814b 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -17,10 +17,22 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* default layout per tags */ -+/* The first element is for all-tag view, following i-th element corresponds to */ -+/* tags[i]. Layout is referred using the layouts array index.*/ -+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -@@ -34,7 +46,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -64,6 +76,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -111,5 +124,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..077d92b 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 169adcb..515a30f 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,25 +111,35 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ -+typedef struct Pertag Pertag; - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; -+ Pertag *pertag; - }; - - typedef struct { -@@ -164,12 +174,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +219,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +254,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -270,6 +285,16 @@ static Window root; - /* 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 */ -+ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -389,6 +414,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +465,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -498,6 +544,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -517,6 +565,7 @@ void - clientmessage(XEvent *e) { - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); -+ int i; - - if(!c) - return; -@@ -529,6 +578,8 @@ clientmessage(XEvent *e) { - if(!ISVISIBLE(c)) { - c->mon->seltags ^= 1; - c->mon->tagset[c->mon->seltags] = c->tags; -+ for(i=0; !(c->tags & 1 << i); i++); -+ view(&(Arg){.ui = 1 << i}); - } - pop(c); - } -@@ -566,8 +617,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -630,6 +684,7 @@ configurerequest(XEvent *e) { - Monitor * - createmon(void) { - Monitor *m; -+ int i; - - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); -@@ -637,10 +692,34 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -- m->lt[0] = &layouts[0]; -+ m->toptab = toptab; -+ m->ntabs = 0; -+ m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)]; - 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] = &layouts[def_layouts[i % LENGTH(def_layouts)] % LENGTH(layouts)]; -+ m->pertag->ltidxs[i][1] = m->lt[1]; -+ m->pertag->sellts[i] = m->sellt; -+ -+ /* init showbar */ -+ m->pertag->showbars[i] = m->showbar; -+ -+ /* swap focus and zoomswap*/ -+ m->pertag->prevzooms[i] = NULL; -+ } - return m; - } - -@@ -749,6 +828,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -772,8 +949,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -800,6 +979,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -850,6 +1030,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -957,7 +1150,7 @@ grabkeys(void) { - - 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); - } - -@@ -1216,12 +1409,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1329,6 +1524,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1470,10 +1666,13 @@ setfullscreen(Client *c, Bool fullscreen) { - - 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); -@@ -1491,7 +1690,7 @@ setmfact(const Arg *arg) { - 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); - } - -@@ -1512,6 +1711,8 @@ setup(void) { - if (!drw->fontcount) - die("No fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; -+ - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1636,13 +1837,23 @@ tile(Monitor *m) { - - 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); - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1672,9 +1883,29 @@ toggletag(const Arg *arg) { - 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); - } -@@ -1746,20 +1977,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1969,11 +2223,33 @@ updatewmhints(Client *c) { - - 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); - } -@@ -1999,7 +2275,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-tab-v2b.diff @@ -1,506 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index eaae8f3..9161486 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -17,6 +17,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -34,7 +41,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -64,6 +71,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -111,5 +119,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..9f5c274 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 169adcb..4ec61fb 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,24 +111,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -164,12 +172,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +217,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +252,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -389,6 +402,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +453,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -498,6 +532,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -566,8 +602,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -637,7 +676,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -749,6 +791,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -772,8 +912,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -800,6 +942,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -850,6 +993,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -1216,12 +1372,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1329,6 +1487,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1512,6 +1671,8 @@ setup(void) { - if (!drw->fontcount) - die("No fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; -+ - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1643,6 +1804,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1746,20 +1917,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1999,7 +2193,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-pertag-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-pertag-tab-v2b.diff @@ -1,692 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 3fde3cf..ef6d4d3 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,10 +15,22 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* default layout per tags */ -+/* The first element is for all-tag view, following i-th element corresponds to */ -+/* tags[i]. Layout is referred using the layouts array index.*/ -+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -@@ -32,7 +44,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -62,6 +74,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -109,5 +122,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..077d92b 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 96b43f7..c0aab5d 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,25 +111,35 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ -+typedef struct Pertag Pertag; - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; -+ Pertag *pertag; - }; - - typedef struct { -@@ -164,12 +174,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +219,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +254,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -270,6 +285,16 @@ static Window root; - /* 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 */ -+ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -389,6 +414,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +465,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -497,6 +543,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -516,6 +564,7 @@ void - clientmessage(XEvent *e) { - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); -+ int i; - - if(!c) - return; -@@ -528,6 +577,8 @@ clientmessage(XEvent *e) { - if(!ISVISIBLE(c)) { - c->mon->seltags ^= 1; - c->mon->tagset[c->mon->seltags] = c->tags; -+ for(i=0; !(c->tags & 1 << i); i++); -+ view(&(Arg){.ui = 1 << i}); - } - pop(c); - } -@@ -565,8 +616,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -629,16 +683,41 @@ configurerequest(XEvent *e) { - Monitor * - createmon(void) { - Monitor *m; -+ int i; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -- m->lt[0] = &layouts[0]; -+ m->toptab = toptab; -+ m->ntabs = 0; -+ m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)]; - 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] = &layouts[def_layouts[i % LENGTH(def_layouts)] % LENGTH(layouts)]; -+ m->pertag->ltidxs[i][1] = m->lt[1]; -+ m->pertag->sellts[i] = m->sellt; -+ -+ /* init showbar */ -+ m->pertag->showbars[i] = m->showbar; -+ -+ /* swap focus and zoomswap*/ -+ m->pertag->prevzooms[i] = NULL; -+ } - return m; - } - -@@ -749,6 +828,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -772,8 +949,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -800,6 +979,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -850,6 +1030,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -957,7 +1150,7 @@ grabkeys(void) { - - 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); - } - -@@ -1215,12 +1408,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1328,6 +1523,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1469,10 +1665,13 @@ setfullscreen(Client *c, Bool fullscreen) { - - 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); -@@ -1490,7 +1689,7 @@ setmfact(const Arg *arg) { - 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); - } - -@@ -1511,6 +1710,8 @@ setup(void) { - if (!drw->fontcount) - die("no fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; -+ - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1635,13 +1836,23 @@ tile(Monitor *m) { - - 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); - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1671,9 +1882,29 @@ toggletag(const Arg *arg) { - 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); - } -@@ -1745,20 +1976,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1967,11 +2221,33 @@ updatewmhints(Client *c) { - - 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); - } -@@ -1997,7 +2273,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-tab-v2b.diff @@ -1,506 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 3fde3cf..6a7ad0f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,6 +15,13 @@ 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 */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ -+ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -32,7 +39,7 @@ static const Rule rules[] = { - /* layout(s) */ - static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static const int nmaster = 1; /* number of clients in master area */ --static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -+static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ - - static const Layout layouts[] = { - /* symbol arrange function */ -@@ -62,6 +69,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -109,5 +117,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..f736591 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. -+The selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left -+corner of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index 96b43f7..585dd7b 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,24 +111,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - Bool showbar; -+ Bool showtab; - Bool topbar; -+ Bool toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -164,12 +172,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +217,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +252,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -389,6 +402,9 @@ arrange(Monitor *m) { - - void - arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -437,14 +453,32 @@ buttonpress(XEvent *e) { - else - click = ClkWinTitle; - } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } - else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -497,6 +531,8 @@ cleanupmon(Monitor *mon) { - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -565,8 +601,11 @@ configurenotify(XEvent *e) { - if(updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for(m = mons; m; m = m->next) -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ } - focus(NULL); - arrange(NULL); - } -@@ -635,7 +674,10 @@ createmon(void) { - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -749,6 +791,104 @@ drawbars(void) { - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, NULL, 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) { - Client *c; - Monitor *m; -@@ -772,8 +912,10 @@ expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if(ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -800,6 +942,7 @@ focus(Client *c) { - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - void -@@ -850,6 +993,19 @@ focusstack(const Arg *arg) { - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) { - int di; -@@ -1215,12 +1371,14 @@ propertynotify(XEvent *e) { - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if(ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1328,6 +1486,7 @@ restack(Monitor *m) { - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if(!m->sel) - return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1511,6 +1670,8 @@ setup(void) { - if (!drw->fontcount) - die("no fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; -+ - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1642,6 +1803,16 @@ togglebar(const Arg *arg) { - } - - void -+tabmode(const Arg *arg) { -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) { - if(!selmon->sel) - return; -@@ -1745,20 +1916,43 @@ updatebars(void) { - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if(m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } -- else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -1997,7 +2191,7 @@ wintomon(Window w) { - if(w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) -- if(w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-pertag-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-pertag-tab-v2b.diff @@ -1,844 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 7054c06..f0b33c5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,10 +15,21 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const Bool toptab = False; /* False means bottom tab bar */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* default layout per tags */ -+/* The first element is for all-tag view, following i-th element corresponds to */ -+/* tags[i]. Layout is referred using the layouts array index.*/ -+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -@@ -62,6 +73,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -109,5 +121,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..077d92b 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, that tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index ff7e096..830d2c2 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,25 +111,35 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ -+typedef struct Pertag Pertag; - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; -+ int showtab; - int topbar; -+ int toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; -+ Pertag *pertag; - }; - - typedef struct { -@@ -164,12 +174,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static int getrootptr(int *x, int *y); - static long getstate(Window w); - static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +219,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +254,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -270,6 +285,16 @@ static Window root; - /* 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 */ -+ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -393,6 +418,8 @@ arrange(Monitor *m) - void - arrangemon(Monitor *m) - { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -442,14 +469,33 @@ buttonpress(XEvent *e) - click = ClkStatusText; - else - click = ClkWinTitle; -- } else if ((c = wintoclient(ev->window))) { -+ } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } -+ else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } -- for (i = 0; i < LENGTH(buttons); i++) -- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ for(i = 0; i < LENGTH(buttons); i++) -+ if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -469,23 +515,24 @@ cleanup(void) - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; -- size_t i; - - view(&a); - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) -- while (m->stack) -- unmanage(m->stack, 0); -+ while(m->stack) -+ unmanage(m->stack, False); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); -- for (i = 0; i < CurLast; i++) -- drw_cur_free(drw, cursor[i]); -- for (i = 0; i < SchemeLast; i++) { -- drw_clr_free(scheme[i].border); -- drw_clr_free(scheme[i].bg); -- drw_clr_free(scheme[i].fg); -- } -+ drw_cur_free(drw, cursor[CurNormal]); -+ drw_cur_free(drw, cursor[CurResize]); -+ drw_cur_free(drw, cursor[CurMove]); -+ drw_clr_free(scheme[SchemeNorm].border); -+ drw_clr_free(scheme[SchemeNorm].bg); -+ drw_clr_free(scheme[SchemeNorm].fg); -+ drw_clr_free(scheme[SchemeSel].border); -+ drw_clr_free(scheme[SchemeSel].bg); -+ drw_clr_free(scheme[SchemeSel].fg); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); -@@ -505,6 +552,8 @@ cleanupmon(Monitor *mon) - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -526,6 +575,7 @@ clientmessage(XEvent *e) - { - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); -+ int i; - - if (!c) - return; -@@ -537,6 +587,8 @@ clientmessage(XEvent *e) - if (!ISVISIBLE(c)) { - c->mon->seltags ^= 1; - c->mon->tagset[c->mon->seltags] = c->tags; -+ for(i=0; !(c->tags & 1 << i); i++); -+ view(&(Arg){.ui = 1 << i}); - } - pop(c); - } -@@ -565,11 +617,10 @@ void - configurenotify(XEvent *e) - { - Monitor *m; -- Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - -- /* TODO: updategeom handling sucks, needs to be simplified */ -+ // TODO: updategeom handling sucks, needs to be simplified - if (ev->window == root) { - dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; -@@ -577,10 +628,9 @@ configurenotify(XEvent *e) - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for (m = mons; m; m = m->next) { -- for (c = m->clients; c; c = c->next) -- if (c->isfullscreen) -- resizeclient(c, m->mx, m->my, m->mw, m->mh); -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for (m = mons; m; m = m->next){ - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); - } - focus(NULL); -@@ -645,16 +695,41 @@ Monitor * - createmon(void) - { - Monitor *m; -+ int i; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -- m->lt[0] = &layouts[0]; -+ m->toptab = toptab; -+ m->ntabs = 0; -+ m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)]; - 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] = &layouts[def_layouts[i % LENGTH(def_layouts)] % LENGTH(layouts)]; -+ m->pertag->ltidxs[i][1] = m->lt[1]; -+ m->pertag->sellts[i] = m->sellt; -+ -+ /* init showbar */ -+ m->pertag->showbars[i] = m->showbar; -+ -+ /* swap focus and zoomswap*/ -+ m->pertag->prevzooms[i] = NULL; -+ } - return m; - } - -@@ -768,6 +843,104 @@ drawbars(void) - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, "", 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) - { - Client *c; -@@ -792,8 +965,10 @@ expose(XEvent *e) - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if (ev->count == 0 && (m = wintomon(ev->window))) -+ if (ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -811,7 +986,7 @@ focus(Client *c) - clearurgent(c); - detachstack(c); - attachstack(c); -- grabbuttons(c, 1); -+ grabbuttons(c, True); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->pix); - setfocus(c); - } else { -@@ -820,6 +995,7 @@ focus(Client *c) - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - /* there are some broken focus acquiring clients */ -@@ -873,6 +1049,19 @@ focusstack(const Arg *arg) - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) - { -@@ -986,7 +1175,7 @@ grabkeys(void) - 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); - } - -@@ -1144,7 +1333,7 @@ motionnotify(XEvent *e) - if (ev->window != root) - return; - if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { -- unfocus(selmon->sel, 1); -+ unfocus(selmon->sel, True); - selmon = m; - focus(NULL); - } -@@ -1164,11 +1353,13 @@ movemouse(const Arg *arg) - return; - if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ - return; -+ if(c->isfullscreen) /* no support moving fullscreen windows by mouse */ -+ return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, -- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) -+ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) - return; - if (!getrootptr(&x, &y)) - return; -@@ -1255,12 +1446,14 @@ propertynotify(XEvent *e) - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1322,11 +1515,13 @@ resizemouse(const Arg *arg) - return; - if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ - return; -+ if(c->isfullscreen) /* no support resizing fullscreen windows by mouse */ -+ return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, -- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) -+ None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { -@@ -1374,6 +1569,7 @@ restack(Monitor *m) - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1482,11 +1678,11 @@ sendevent(Client *c, Atom proto) - void - setfocus(Client *c) - { -- if (!c->neverfocus) { -+ if(!c->neverfocus) { - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XChangeProperty(dpy, root, netatom[NetActiveWindow], -- XA_WINDOW, 32, PropModeReplace, -- (unsigned char *) &(c->win), 1); -+ XA_WINDOW, 32, PropModeReplace, -+ (unsigned char *) &(c->win), 1); - } - sendevent(c, wmatom[WMTakeFocus]); - } -@@ -1522,10 +1718,13 @@ setfullscreen(Client *c, int fullscreen) - void - setlayout(const Arg *arg) - { -- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -- selmon->sellt ^= 1; -- if (arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ 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->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); -@@ -1544,7 +1743,7 @@ setmfact(const Arg *arg) - 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); - } - -@@ -1564,8 +1763,9 @@ setup(void) - drw = drw_create(dpy, screen, root, sw, sh); - drw_load_fonts(drw, fonts, LENGTH(fonts)); - if (!drw->fontcount) -- die("no fonts could be loaded.\n"); -+ die("No fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1637,10 +1837,10 @@ sigchld(int unused) - void - spawn(const Arg *arg) - { -- if (arg->v == dmenucmd) -+ if(arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; -- if (fork() == 0) { -- if (dpy) -+ if(fork() == 0) { -+ if(dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); -@@ -1697,18 +1897,29 @@ tile(Monitor *m) - 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); - } - - void -+tabmode(const Arg *arg) -+{ -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) - { -- if (!selmon->sel) -+ if(!selmon->sel) - return; -- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ -+ if(selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if (selmon->sel->isfloating) -@@ -1736,9 +1947,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); - } -@@ -1749,7 +1980,7 @@ unfocus(Client *c, int setfocus) - { - if (!c) - return; -- grabbuttons(c, 0); -+ grabbuttons(c, False); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->pix); - if (setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); -@@ -1814,20 +2045,44 @@ updatebars(void) - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) - { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -2009,9 +2264,9 @@ updatewindowtype(Client *c) - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - - if (state == netatom[NetWMFullscreen]) -- setfullscreen(c, 1); -+ setfullscreen(c, True); - if (wtype == netatom[NetWMWindowTypeDialog]) -- c->isfloating = 1; -+ c->isfloating = True; - } - - void -@@ -2036,11 +2291,33 @@ updatewmhints(Client *c) - void - view(const Arg *arg) - { -- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) -+ 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); - } -@@ -2068,7 +2345,7 @@ wintomon(Window w) - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) -- if (w == m->barwin) -+ if(w == m->barwin || w == m->tabwin) - return m; - if ((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-tab-v2b.diff b/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-tab-v2b.diff @@ -1,500 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 7054c06..e784231 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -15,6 +15,12 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -+/* Display modes of the tab bar: never shown, always shown, shown only in */ -+/* monocle mode in presence of several windows. */ -+/* Modes after showtab_nmodes are disabled */ -+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; -+static const int showtab = showtab_auto; /* Default tab bar show mode */ -+static const int toptab = False; /* False means bottom tab bar */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -@@ -62,6 +68,7 @@ static Key keys[] = { - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -+ { MODKEY, XK_w, tabmode, {-1} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, -@@ -109,5 +116,6 @@ static Button buttons[] = { - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -+ { ClkTabBar, 0, Button1, focuswin, {0} }, - }; - -diff --git a/dwm.1 b/dwm.1 -index 6687011..9ff827c 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -19,14 +19,22 @@ layout applied. - Windows are grouped by tags. Each window can be tagged with one or multiple - tags. Selecting certain tags displays all windows with these tags. - .P --Each screen contains a small status bar which displays all available tags, the --layout, the title of the focused window, and the text read from the root window --name property, if the screen is focused. A floating window is indicated with an --empty square and a maximised floating window is indicated with a filled square --before the windows title. The selected tags are indicated with a different --color. The tags of the focused window are indicated with a filled square in the --top left corner. The tags which are applied to one or more windows are --indicated with an empty square in the top left corner. -+Each screen contains two small status bars. -+.P -+One bar displays all available tags, the layout, the title of the focused -+window, and the text read from the root window name property, if the screen is -+focused. A floating window is indicated with an empty square and a maximised -+floating window is indicated with a filled square before the windows title. The -+selected tags are indicated with a different color. The tags of the focused -+window are indicated with a filled square in the top left corner. The tags -+which are applied to one or more windows are indicated with an empty square in -+the top left corner. -+.P -+Another bar contains a tab for each window of the current view and allows -+navigation between windows, especially in the monocle mode. The different -+display modes of this bar are described under the Mod1\-w Keybord command -+section. When a single tag is selected, this tag is indicated in the left corner -+of the tab bar. - .P - dwm draws a small border around windows to indicate the focus state. - .SH OPTIONS -@@ -43,7 +51,8 @@ command. - .TP - .B Button1 - click on a tag label to display all windows with that tag, click on the layout --label toggles between tiled and floating layout. -+label toggles between tiled and floating layout, click on a window name in the -+tab bar brings focus to that window. - .TP - .B Button3 - click on a tag label adds/removes all windows with that tag to/from the view. -@@ -104,6 +113,12 @@ Increase master area size. - .B Mod1\-h - Decrease master area size. - .TP -+.B Mod1\-w -+Cycle over the tab bar display modes: never displayed, always displayed, -+displayed only in monocle mode when the view contains more than one window (auto -+mode). Some display modes can be disabled in the configuration, config.h. In -+the default configuration only "never" and "auto" display modes are enabled. -+.TP - .B Mod1\-Return - Zooms/cycles focused window to/from master area (tiled layouts only). - .TP -diff --git a/dwm.c b/dwm.c -index ff7e096..fb285ec 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - - typedef union { -@@ -111,24 +111,32 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+#define MAXTABS 50 -+ - struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ -+ int ty; /* tab bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; -+ int showtab; - int topbar; -+ int toptab; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; -+ Window tabwin; -+ int ntabs; -+ int tab_widths[MAXTABS]; - const Layout *lt[2]; - }; - -@@ -164,12 +172,15 @@ static void detachstack(Client *c); - static Monitor *dirtomon(int dir); - static void drawbar(Monitor *m); - static void drawbars(void); -+static void drawtab(Monitor *m); -+static void drawtabs(void); - static void enternotify(XEvent *e); - static void expose(XEvent *e); - static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); -+static void focuswin(const Arg* arg); - static int getrootptr(int *x, int *y); - static long getstate(Window w); - static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -206,6 +217,7 @@ static void setup(void); - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void tabmode(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -240,6 +252,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int th = 0; /* tab bar geometry */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -391,8 +404,9 @@ arrange(Monitor *m) - } - - void --arrangemon(Monitor *m) --{ -+arrangemon(Monitor *m) { -+ updatebarpos(m); -+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -@@ -442,14 +456,33 @@ buttonpress(XEvent *e) - click = ClkStatusText; - else - click = ClkWinTitle; -- } else if ((c = wintoclient(ev->window))) { -+ } -+ if(ev->window == selmon->tabwin) { -+ i = 0; x = 0; -+ for(c = selmon->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ x += selmon->tab_widths[i]; -+ if (ev->x > x) -+ ++i; -+ else -+ break; -+ if(i >= m->ntabs) break; -+ } -+ if(c) { -+ click = ClkTabBar; -+ arg.ui = i; -+ } -+ } -+ else if((c = wintoclient(ev->window))) { - focus(c); - click = ClkClientWin; - } - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button -- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ -+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) -+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); -+ } - } - - void -@@ -505,6 +538,8 @@ cleanupmon(Monitor *mon) - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); -+ XUnmapWindow(dpy, mon->tabwin); -+ XDestroyWindow(dpy, mon->tabwin); - free(mon); - } - -@@ -577,7 +612,9 @@ configurenotify(XEvent *e) - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); -- for (m = mons; m; m = m->next) { -+ //refreshing display of status bar. The tab bar is handled by the arrange() -+ //method, which is called below -+ for(m = mons; m; m = m->next){ - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); -@@ -651,7 +688,10 @@ createmon(void) - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; -+ m->showtab = showtab; - m->topbar = topbar; -+ m->toptab = toptab; -+ m->ntabs = 0; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -768,6 +808,105 @@ drawbars(void) - } - - void -+drawtabs(void) { -+ Monitor *m; -+ -+ for(m = mons; m; m = m->next) -+ drawtab(m); -+} -+ -+static int -+cmpint(const void *p1, const void *p2) { -+ /* The actual arguments to this function are "pointers to -+ pointers to char", but strcmp(3) arguments are "pointers -+ to char", hence the following cast plus dereference */ -+ return *((int*) p1) > * (int*) p2; -+} -+ -+ -+void -+drawtab(Monitor *m) { -+ Client *c; -+ int i; -+ int itag = -1; -+ char view_info[50]; -+ int view_info_w = 0; -+ int sorted_label_widths[MAXTABS]; -+ int tot_width; -+ int maxsize = bh; -+ int x = 0; -+ int w = 0; -+ -+ //view_info: indicate the tag which is displayed in the view -+ for(i = 0; i < LENGTH(tags); ++i){ -+ if((selmon->tagset[selmon->seltags] >> i) & 1) { -+ if(itag >=0){ //more than one tag selected -+ itag = -1; -+ break; -+ } -+ itag = i; -+ } -+ } -+ -+ if(0 <= itag && itag < LENGTH(tags)){ -+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); -+ } else { -+ strncpy(view_info, "[...]", sizeof view_info); -+ } -+ view_info[sizeof(view_info) - 1 ] = 0; -+ view_info_w = TEXTW(view_info); -+ tot_width = view_info_w; -+ -+ /* Calculates number of labels and their width */ -+ m->ntabs = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ m->tab_widths[m->ntabs] = TEXTW(c->name); -+ tot_width += m->tab_widths[m->ntabs]; -+ ++m->ntabs; -+ if(m->ntabs >= MAXTABS) break; -+ } -+ -+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated -+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); -+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); -+ tot_width = view_info_w; -+ for(i = 0; i < m->ntabs; ++i){ -+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) -+ break; -+ tot_width += sorted_label_widths[i]; -+ } -+ maxsize = (m->ww - tot_width) / (m->ntabs - i); -+ } else{ -+ maxsize = m->ww; -+ } -+ i = 0; -+ for(c = m->clients; c; c = c->next){ -+ if(!ISVISIBLE(c)) continue; -+ if(i >= m->ntabs) break; -+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; -+ w = m->tab_widths[i]; -+ drw_setscheme(drw, (c == m->sel) ? &scheme[SchemeSel] : &scheme[SchemeNorm]); -+ drw_text(drw, x, 0, w, th, c->name, 0); -+ x += w; -+ ++i; -+ } -+ -+ drw_setscheme(drw, &scheme[SchemeNorm]); -+ -+ /* cleans interspace between window names and current viewed tag label */ -+ w = m->ww - view_info_w - x; -+ drw_text(drw, x, 0, w, th, "", 0); -+ -+ /* view info */ -+ x += w; -+ w = view_info_w; -+ drw_text(drw, x, 0, w, th, view_info, 0); -+ -+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); -+} -+ -+void - enternotify(XEvent *e) - { - Client *c; -@@ -792,8 +931,10 @@ expose(XEvent *e) - Monitor *m; - XExposeEvent *ev = &e->xexpose; - -- if (ev->count == 0 && (m = wintomon(ev->window))) -+ if(ev->count == 0 && (m = wintomon(ev->window))){ - drawbar(m); -+ drawtab(m); -+ } - } - - void -@@ -820,6 +961,7 @@ focus(Client *c) - } - selmon->sel = c; - drawbars(); -+ drawtabs(); - } - - /* there are some broken focus acquiring clients */ -@@ -873,6 +1015,19 @@ focusstack(const Arg *arg) - } - } - -+void -+focuswin(const Arg* arg){ -+ int iwin = arg->i; -+ Client* c = NULL; -+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ -+ if(ISVISIBLE(c)) --iwin; -+ }; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ - Atom - getatomprop(Client *c, Atom prop) - { -@@ -1255,12 +1410,14 @@ propertynotify(XEvent *e) - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); -+ drawtabs(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); -+ drawtab(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); -@@ -1374,6 +1531,7 @@ restack(Monitor *m) - XWindowChanges wc; - - drawbar(m); -+ drawtab(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) -@@ -1566,6 +1724,8 @@ setup(void) - if (!drw->fontcount) - die("no fonts could be loaded.\n"); - bh = drw->fonts[0]->h + 2; -+ th = bh; -+ - updategeom(); - /* init atoms */ - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1704,6 +1864,17 @@ togglebar(const Arg *arg) - } - - void -+tabmode(const Arg *arg) -+{ -+ if(arg && arg->i >= 0) -+ selmon->showtab = arg->ui % showtab_nmodes; -+ else -+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; -+ arrange(selmon); -+} -+ -+ -+void - togglefloating(const Arg *arg) - { - if (!selmon->sel) -@@ -1814,20 +1985,44 @@ updatebars(void) - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); -+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), -+ CopyFromParent, DefaultVisual(dpy, screen), -+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); -+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); -+ XMapRaised(dpy, m->tabwin); - } - } - - void - updatebarpos(Monitor *m) - { -+ Client *c; -+ int nvis = 0; -+ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -- } else -+ if ( m->topbar ) -+ m->wy += bh; -+ } else { - m->by = -bh; -+ } -+ -+ for(c = m->clients; c; c = c->next){ -+ if(ISVISIBLE(c)) ++nvis; -+ } -+ -+ if(m->showtab == showtab_always -+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ -+ m->wh -= th; -+ m->ty = m->toptab ? m->wy : m->wy + m->wh; -+ if ( m->toptab ) -+ m->wy += th; -+ } else { -+ m->ty = -th; -+ } - } - - void -@@ -2068,7 +2263,7 @@ wintomon(Window w) - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) -- if (w == m->barwin) -+ if (w == m->barwin || w == m->tabwin) - return m; - if ((c = wintoclient(w))) - return c->mon; diff --git a/dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff b/dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff @@ -1,73 +0,0 @@ -diff -r 050d521d66d8 config.def.h ---- a/config.def.h Tue Aug 24 13:13:20 2010 +0100 -+++ b/config.def.h Sun Sep 05 18:43:07 2010 +0200 -@@ -48,6 +48,7 @@ - static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; - static const char *termcmd[] = { "uxterm", NULL }; - -+#include "movestack.c" - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, -@@ -57,6 +58,8 @@ - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, -+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, -diff -r 050d521d66d8 movestack.c ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/movestack.c Sun Sep 05 18:43:07 2010 +0200 -@@ -0,0 +1,49 @@ -+void -+movestack(const Arg *arg) { -+ Client *c = NULL, *p = NULL, *pc = NULL, *i; -+ -+ if(arg->i > 0) { -+ /* find the client after selmon->sel */ -+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); -+ if(!c) -+ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); -+ -+ } -+ else { -+ /* find the client before selmon->sel */ -+ for(i = selmon->clients; i != selmon->sel; i = i->next) -+ if(ISVISIBLE(i) && !i->isfloating) -+ c = i; -+ if(!c) -+ for(; i; i = i->next) -+ if(ISVISIBLE(i) && !i->isfloating) -+ c = i; -+ } -+ /* find the client before selmon->sel and c */ -+ for(i = selmon->clients; i && (!p || !pc); i = i->next) { -+ if(i->next == selmon->sel) -+ p = i; -+ if(i->next == c) -+ pc = i; -+ } -+ -+ /* swap c and selmon->sel selmon->clients in the selmon->clients list */ -+ if(c && c != selmon->sel) { -+ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; -+ selmon->sel->next = c->next==selmon->sel?c:c->next; -+ c->next = temp; -+ -+ if(p && p != c) -+ p->next = c; -+ if(pc && pc != selmon->sel) -+ pc->next = selmon->sel; -+ -+ if(selmon->sel == selmon->clients) -+ selmon->clients = c; -+ else if(c == selmon->clients) -+ selmon->clients = selmon->sel; -+ -+ arrange(selmon); -+ } -+} -+ diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff @@ -1,125 +0,0 @@ -diff -NrU3 dwm-5.1/dwm.c dwm-5.1.playground-pertag/dwm.c ---- dwm-5.1/dwm.c 2008-07-29 20:18:32.000000000 +0200 -+++ dwm-5.1-pertag/dwm.c 2008-08-01 18:46:49.000000000 +0200 -@@ -238,6 +238,11 @@ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+static int curtag = 1, prevtag = 1; -+static Layout *lts[LENGTH(tags) + 1]; -+static double mfacts[LENGTH(tags) + 1]; -+static Bool showbars[LENGTH(tags) + 1]; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; - -@@ -1307,7 +1312,7 @@ - if(!arg || !arg->v || arg->v != lt[sellt]) - sellt ^= 1; - if(arg && arg->v) -- lt[sellt] = (Layout *)arg->v; -+ lt[sellt] = lts[curtag] = (Layout *)arg->v; - if(sel) - arrange(); - else -@@ -1324,7 +1329,7 @@ - f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- mfact = f; -+ mfact = mfacts[curtag] = f; - arrange(); - } - -@@ -1373,12 +1378,27 @@ - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); - -+ /* init mfacts */ -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ mfacts[i] = mfact; -+ } -+ -+ /* init layouts */ -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ lts[i] = &layouts[0]; -+ } -+ -+ - /* init bar */ - for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { - w = TEXTW(layouts[i].symbol); - blw = MAX(blw, w); - } - -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ showbars[i] = showbar; -+ } -+ - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; - wa.event_mask = ButtonPressMask|ExposureMask; -@@ -1479,7 +1499,7 @@ - - void - togglebar(const Arg *arg) { -- showbar = !showbar; -+ showbar = showbars[curtag] = !showbar; - updategeom(); - updatebar(); - arrange(); -@@ -1508,9 +1528,23 @@ - void - toggleview(const Arg *arg) { - unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); -+ unsigned int i; - - if(mask) { -+ if(mask == ~0) { -+ prevtag = curtag; -+ curtag = 0; -+ } -+ if(!(mask & 1 << (curtag - 1))) { -+ prevtag = curtag; -+ for (i=0; !(mask & 1 << i); i++); -+ curtag = i + 1; -+ } - tagset[seltags] = mask; -+ lt[sellt] = lts[curtag]; -+ mfact = mfacts[curtag]; -+ if (showbar != showbars[curtag]) -+ togglebar(NULL); - clearurgent(); - arrange(); - } -@@ -1663,11 +1697,29 @@ - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if(arg && (arg->i & TAGMASK) == tagset[seltags]) - return; - seltags ^= 1; /* toggle sel tagset */ -- if(arg && (arg->ui & TAGMASK)) -+ if(arg && (arg->ui & TAGMASK)) { - tagset[seltags] = arg->i & TAGMASK; -+ prevtag = curtag; -+ if(arg->ui == ~0) -+ curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ curtag = i + 1; -+ } -+ } else { -+ prevtag= curtag ^ prevtag; -+ curtag^= prevtag; -+ prevtag= curtag ^ prevtag; -+ } -+ lt[sellt]= lts[curtag]; -+ mfact = mfacts[curtag]; -+ if(showbar != showbars[curtag]) -+ togglebar(NULL); - clearurgent(); - arrange(); - } diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff @@ -1,123 +0,0 @@ ---- dwm-5.2/dwm.c 2008-09-09 21:46:17.000000000 +0200 -+++ dwm-5.2-pertag/dwm.c 2008-10-12 23:53:30.000000000 +0200 -@@ -240,6 +240,11 @@ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+static int curtag = 1, prevtag = 1; -+static Layout *lts[LENGTH(tags) + 1]; -+static double mfacts[LENGTH(tags) + 1]; -+static Bool showbars[LENGTH(tags) + 1]; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; - -@@ -1272,7 +1277,7 @@ - if(!arg || !arg->v || arg->v != lt[sellt]) - sellt ^= 1; - if(arg && arg->v) -- lt[sellt] = (Layout *)arg->v; -+ lt[sellt] = lts[curtag] = (Layout *)arg->v; - if(sel) - arrange(); - else -@@ -1289,7 +1294,7 @@ - f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- mfact = f; -+ mfact = mfacts[curtag] = f; - arrange(); - } - -@@ -1337,12 +1342,27 @@ - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); - -+ /* init mfacts */ -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ mfacts[i] = mfact; -+ } -+ -+ /* init layouts */ -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ lts[i] = &layouts[0]; -+ } -+ -+ - /* init bar */ - for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { - w = TEXTW(layouts[i].symbol); - blw = MAX(blw, w); - } - -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ showbars[i] = showbar; -+ } -+ - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; - wa.event_mask = ButtonPressMask|ExposureMask; -@@ -1457,7 +1477,7 @@ - - void - togglebar(const Arg *arg) { -- showbar = !showbar; -+ showbar = showbars[curtag] = !showbar; - updategeom(); - updatebar(); - arrange(); -@@ -1490,9 +1510,23 @@ - void - toggleview(const Arg *arg) { - unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); -+ unsigned int i; - - if(mask) { -+ if(mask == ~0) { -+ prevtag = curtag; -+ curtag = 0; -+ } -+ if(!(mask & 1 << (curtag - 1))) { -+ prevtag = curtag; -+ for (i=0; !(mask & 1 << i); i++); -+ curtag = i + 1; -+ } - tagset[seltags] = mask; -+ lt[sellt] = lts[curtag]; -+ mfact = mfacts[curtag]; -+ if (showbar != showbars[curtag]) -+ togglebar(NULL); - clearurgent(); - arrange(); - } -@@ -1661,11 +1695,28 @@ - - void - view(const Arg *arg) { -+ unsigned int i; - if((arg->ui & TAGMASK) == tagset[seltags]) - return; - seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - tagset[seltags] = arg->ui & TAGMASK; -+ prevtag = curtag; -+ if(arg->ui == ~0) -+ curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ curtag = i + 1; -+ } -+ } else { -+ prevtag= curtag ^ prevtag; -+ curtag^= prevtag; -+ prevtag= curtag ^ prevtag; -+ } -+ lt[sellt]= lts[curtag]; -+ mfact = mfacts[curtag]; -+ if(showbar != showbars[curtag]) -+ togglebar(NULL); - clearurgent(); - arrange(); - } diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff @@ -1,123 +0,0 @@ -diff -r add6eb26ebaa dwm.c ---- a/dwm.c Sat Dec 20 12:02:14 2008 +0000 -+++ b/dwm.c Sun Dec 21 18:39:14 2008 +0100 -@@ -240,6 +240,11 @@ static Window root, barwin; - static Window root, barwin; - /* configuration, allows nested code to access above variables */ - #include "config.h" -+ -+static int curtag = 1, prevtag = 1; -+static Layout *lts[LENGTH(tags) + 1]; -+static double mfacts[LENGTH(tags) + 1]; -+static Bool showbars[LENGTH(tags) + 1]; - - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; -@@ -1244,7 +1249,7 @@ setlayout(const Arg *arg) { - if(!arg || !arg->v || arg->v != lt[sellt]) - sellt ^= 1; - if(arg && arg->v) -- lt[sellt] = (Layout *)arg->v; -+ lt[sellt] = lts[curtag] = (Layout *)arg->v; - if(sel) - arrange(); - else -@@ -1261,7 +1266,7 @@ setmfact(const Arg *arg) { - f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- mfact = f; -+ mfact = mfacts[curtag] = f; - arrange(); - } - -@@ -1309,11 +1314,26 @@ setup(void) { - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); - -+ /* init mfacts */ -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ mfacts[i] = mfact; -+ } -+ -+ /* init layouts */ -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ lts[i] = &layouts[0]; -+ } -+ -+ - /* init bar */ - for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { - w = TEXTW(layouts[i].symbol); - blw = MAX(blw, w); - } -+ -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ showbars[i] = showbar; -+ } - - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; -@@ -1434,7 +1454,7 @@ tile(void) { - - void - togglebar(const Arg *arg) { -- showbar = !showbar; -+ showbar = showbars[curtag] = !showbar; - updategeom(); - updatebar(); - arrange(); -@@ -1467,9 +1487,23 @@ void - void - toggleview(const Arg *arg) { - unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); -+ unsigned int i; - - if(mask) { -+ if(mask == ~0) { -+ prevtag = curtag; -+ curtag = 0; -+ } -+ if(!(mask & 1 << (curtag - 1))) { -+ prevtag = curtag; -+ for (i=0; !(mask & 1 << i); i++); -+ curtag = i + 1; -+ } - tagset[seltags] = mask; -+ lt[sellt] = lts[curtag]; -+ mfact = mfacts[curtag]; -+ if (showbar != showbars[curtag]) -+ togglebar(NULL); - arrange(); - } - } -@@ -1644,11 +1678,28 @@ updatewmhints(Client *c) { - - void - view(const Arg *arg) { -+ unsigned int i; - if((arg->ui & TAGMASK) == tagset[seltags]) - return; - seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - tagset[seltags] = arg->ui & TAGMASK; -+ prevtag = curtag; -+ if(arg->ui == ~0) -+ curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ curtag = i + 1; -+ } -+ } else { -+ prevtag= curtag ^ prevtag; -+ curtag^= prevtag; -+ prevtag= curtag ^ prevtag; -+ } -+ lt[sellt]= lts[curtag]; -+ mfact = mfacts[curtag]; -+ if(showbar != showbars[curtag]) -+ togglebar(NULL); - arrange(); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.6.1.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.6.1.diff @@ -1,184 +0,0 @@ ---- dwm.c 2009-09-18 18:12:50.000000000 +0200 -+++ dwm.c.working 2009-09-18 18:14:04.000000000 +0200 -@@ -131,6 +131,25 @@ - void (*arrange) (Monitor *); - } Layout; - -+struct Monitor { -+ float mfact; -+ int num; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+}; -+ - typedef struct { - const char *class; - const char *instance; -@@ -263,30 +282,6 @@ - /* configuration, allows nested code to access above variables */ - #include "config.h" - --struct Monitor { -- float mfact; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; -- int curtag; -- int prevtag; -- const Layout *lts[LENGTH(tags) + 1]; -- double mfacts[LENGTH(tags) + 1]; -- Bool showbars[LENGTH(tags) + 1]; --}; -- - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { - char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; -@@ -1484,7 +1479,7 @@ - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) -- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *) arg->v; -+ selmon->lt[selmon->sellt] = (Layout *) arg->v; - if (selmon->sel) - arrange(); - else -@@ -1502,7 +1497,7 @@ - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.1 || f > 0.9) - return; -- selmon->mfact = selmon->mfacts[selmon->curtag] = f; -+ selmon->mfact = f; - arrange(); - } - -@@ -1512,7 +1507,6 @@ - unsigned int i; - int w; - XSetWindowAttributes wa; -- Monitor *m; - - /* clean up any zombies immediately */ - sigchld(0); -@@ -1547,31 +1541,11 @@ - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if (!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -- /* init tags */ -- for (m = mons; m; m = m->next) -- m->curtag = m->prevtag = 1; -- /* init mfacts */ -- for (m = mons; m; m = m->next) { -- for (i = 0; i < LENGTH(tags) + 1; i++) { -- m->mfacts[i] = m->mfact; -- } -- } -- /* init layouts */ -- for (m = mons; m; m = m->next) { -- for (i = 0; i < LENGTH(tags) + 1; i++) { -- m->lts[i] = &layouts[0]; -- } -- } - /* init bars */ - for (blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { - w = TEXTW(layouts[i].symbol); - blw = MAX(blw, w); - } -- for (m = mons; m; m = m->next) { -- for (i = 0; i < LENGTH(tags) + 1; i++) { -- m->showbars[i] = m->showbar; -- } -- } - updatebars(); - updatestatus(); - /* EWMH support per view */ -@@ -1689,7 +1663,7 @@ - void - togglebar(const Arg * arg) - { -- selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; -+ selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); - arrange(); -@@ -1710,27 +1684,13 @@ - void - toggletag(const Arg * arg) - { -- unsigned int i; - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { -- if (newtags == ~0) { -- selmon->prevtag = selmon->curtag; -- selmon->curtag = 0; -- } -- if (!(newtags & 1 << (selmon->curtag - 1))) { -- selmon->prevtag = selmon->curtag; -- for (i = 0; !(newtags & 1 << i); i++); -- selmon->curtag = i + 1; -- } - selmon->sel->tags = newtags; -- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -- selmon->mfact = selmon->mfacts[selmon->curtag]; -- if (selmon->showbar != selmon->showbars[selmon->curtag]) -- togglebar(NULL); - arrange(); - } - } -@@ -1993,28 +1953,11 @@ - void - view(const Arg * arg) - { -- unsigned int i; - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if (arg->ui & TAGMASK) { -+ if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -- selmon->prevtag = selmon->curtag; -- if (arg->ui == ~0) -- selmon->curtag = 0; -- else { -- for (i = 0; !(arg->ui & 1 << i); i++); -- selmon->curtag = i + 1; -- } -- } else { -- selmon->prevtag = selmon->curtag ^ selmon->prevtag; -- selmon->curtag ^= selmon->prevtag; -- selmon->prevtag = selmon->curtag ^ selmon->prevtag; -- } -- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -- selmon->mfact = selmon->mfacts[selmon->curtag]; -- if (selmon->showbar != selmon->showbars[selmon->curtag]) -- togglebar(NULL); - arrange(); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff @@ -1,184 +0,0 @@ -diff -r 2bcd25cce4ab dwm.c ---- a/dwm.c Sun Sep 27 20:20:14 2009 +0100 -+++ b/dwm.c Tue Oct 20 18:27:52 2009 -0300 -@@ -120,26 +120,6 @@ - void (*arrange)(Monitor *); - } Layout; - --struct Monitor { -- char ltsymbol[16]; -- float mfact; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; --}; -- - typedef struct { - const char *class; - const char *instance; -@@ -273,6 +253,31 @@ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+struct Monitor { -+ char ltsymbol[16]; -+ float mfact; -+ int num; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+ int curtag; -+ int prevtag; -+ const Layout *lts[LENGTH(tags) + 1]; -+ double mfacts[LENGTH(tags) + 1]; -+ Bool showbars[LENGTH(tags) + 1]; -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -1450,7 +1455,7 @@ - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if(arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) - arrange(selmon); -@@ -1468,13 +1473,15 @@ - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->mfacts[selmon->curtag] = f; - arrange(selmon); - } - - void - setup(void) { - XSetWindowAttributes wa; -+ Monitor *m; -+ unsigned int i; - - /* clean up any zombies immediately */ - sigchld(0); -@@ -1509,7 +1516,27 @@ - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -+ /* init tags */ -+ for(m = mons; m; m = m->next) -+ m->curtag = m->prevtag = 1; -+ /* init mfacts */ -+ for(m = mons; m; m = m->next) { -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ m->mfacts[i] = m->mfact; -+ } -+ } -+ /* init layouts */ -+ for(m = mons; m; m = m->next) { -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ m->lts[i] = &layouts[0]; -+ } -+ } - /* init bars */ -+ for(m = mons; m; m = m->next) { -+ for(i=0; i < LENGTH(tags) + 1; i++) { -+ m->showbars[i] = m->showbar; -+ } -+ } - updatebars(); - updatestatus(); - /* EWMH support per view */ -@@ -1620,7 +1647,7 @@ - - void - togglebar(const Arg *arg) { -- selmon->showbar = !selmon->showbar; -+ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); - arrange(selmon); -@@ -1640,12 +1667,27 @@ - void - toggletag(const Arg *arg) { - unsigned int newtags; -+ unsigned int i; - - if(!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { - selmon->sel->tags = newtags; -+ if(newtags == ~0) { -+ selmon->prevtag = selmon->curtag; -+ selmon->curtag = 0; -+ } -+ if(!(newtags & 1 << (selmon->curtag - 1))) { -+ selmon->prevtag = selmon->curtag; -+ for (i=0; !(newtags & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ selmon->sel->tags = newtags; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if (selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - arrange(selmon); - } - } -@@ -1912,11 +1954,29 @@ - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->prevtag = selmon->curtag; -+ if(arg->ui == ~0) -+ selmon->curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ } else { -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ selmon->curtag^= selmon->prevtag; -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ } -+ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if(selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff b/dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff @@ -1,180 +0,0 @@ -diff --git a/dwm.c b/dwm.c ---- a/dwm.c -+++ b/dwm.c -@@ -122,26 +122,6 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - --struct Monitor { -- char ltsymbol[16]; -- float mfact; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; --}; -- - typedef struct { - const char *class; - const char *instance; -@@ -278,6 +258,31 @@ static Window root; - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+struct Monitor { -+ char ltsymbol[16]; -+ float mfact; -+ int num; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+ int curtag; -+ int prevtag; -+ const Layout *lts[LENGTH(tags) + 1]; -+ double mfacts[LENGTH(tags) + 1]; -+ Bool showbars[LENGTH(tags) + 1]; -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -609,6 +614,7 @@ configurerequest(XEvent *e) { - Monitor * - createmon(void) { - Monitor *m; -+ unsigned int i; - - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); -@@ -619,6 +625,15 @@ createmon(void) { - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -+ -+ /* pertag init */ -+ m->curtag = m->prevtag = 1; -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ m->mfacts[i] = mfact; -+ m->lts[i] = &layouts[0]; -+ m->showbars[i] = m->showbar; -+ } -+ - return m; - } - -@@ -1486,7 +1501,7 @@ setlayout(const Arg *arg) { - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if(arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) - arrange(selmon); -@@ -1504,7 +1519,7 @@ setmfact(const Arg *arg) { - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->mfacts[selmon->curtag] = f; - arrange(selmon); - } - -@@ -1547,7 +1562,6 @@ setup(void) { - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -- /* init bars */ - updatebars(); - updatestatus(); - /* EWMH support per view */ -@@ -1658,7 +1672,7 @@ tile(Monitor *m) { - - void - togglebar(const Arg *arg) { -- selmon->showbar = !selmon->showbar; -+ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); - arrange(selmon); -@@ -1678,12 +1692,27 @@ togglefloating(const Arg *arg) { - void - toggletag(const Arg *arg) { - unsigned int newtags; -+ unsigned int i; - - if(!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { - selmon->sel->tags = newtags; -+ if(newtags == ~0) { -+ selmon->prevtag = selmon->curtag; -+ selmon->curtag = 0; -+ } -+ if(!(newtags & 1 << (selmon->curtag - 1))) { -+ selmon->prevtag = selmon->curtag; -+ for (i=0; !(newtags & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ selmon->sel->tags = newtags; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if (selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - arrange(selmon); - } - } -@@ -1950,11 +1979,29 @@ updatewmhints(Client *c) { - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->prevtag = selmon->curtag; -+ if(arg->ui == ~0) -+ selmon->curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ } else { -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ selmon->curtag^= selmon->prevtag; -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ } -+ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ if(selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - arrange(selmon); - } - diff --git a/dwm.suckless.org/patches/historical/dwm-r1437-gaplessgrid.diff b/dwm.suckless.org/patches/historical/dwm-r1437-gaplessgrid.diff @@ -1,59 +0,0 @@ -diff -up dwm-5.2-original/config.def.h dwm-5.2-modified/config.def.h ---- dwm-5.2-original/config.def.h 2008-09-09 21:46:17.000000000 +0200 -+++ dwm-5.2-modified/config.def.h 2008-10-20 20:07:42.000000000 +0200 -@@ -28,11 +28,13 @@ static Rule rules[] = { - static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ - static Bool resizehints = True; /* False means respect size hints in tiled resizals */ - -+#include "gaplessgrid.c" - static Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "###", gaplessgrid }, - }; - - /* key definitions */ -diff -up dwm-5.2-original/gaplessgrid.c dwm-5.2-modified/gaplessgrid.c ---- /dev/null 2008-10-20 20:09:51.000000000 +0200 -+++ dwm-5.2-modified/gaplessgrid.c 2008-10-20 20:06:59.000000000 +0200 -@@ -0,0 +1,38 @@ -+void -+gaplessgrid(Monitor *m) { -+ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) -+ n++; -+ if(n == 0) -+ return; -+ -+ /* grid dimensions */ -+ for(cols = 0; cols <= n/2; cols++) -+ if(cols*cols >= n) -+ break; -+ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ -+ cols = 2; -+ rows = n/cols; -+ -+ /* window geometries (cell height/width/x/y) */ -+ cw = m->ww / (cols ? cols : 1); -+ cn = 0; /* current column number */ -+ rn = 0; /* current row number */ -+ for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { -+ if(i/rows+1 > cols-n%cols) -+ rows = n/cols+1; -+ ch = m->wh / (rows ? rows : 1); -+ cx = m->wx + cn*cw; -+ cy = m->wy + rn*ch; -+ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw); -+ -+ i++; -+ rn++; -+ if(rn >= rows) { /* jump to the next column */ -+ rn = 0; -+ cn++; -+ } -+ } -+} diff --git a/dwm.suckless.org/patches/historical/dwm-r1578-pertag.diff b/dwm.suckless.org/patches/historical/dwm-r1578-pertag.diff @@ -1,189 +0,0 @@ -diff --git a/dwm.c b/dwm.c ---- a/dwm.c -+++ b/dwm.c -@@ -122,27 +122,6 @@ - void (*arrange)(Monitor *); - } Layout; - --struct Monitor { -- char ltsymbol[16]; -- float mfact; -- int nmaster; -- int num; -- int by; /* bar geometry */ -- int mx, my, mw, mh; /* screen size */ -- int wx, wy, ww, wh; /* window area */ -- unsigned int seltags; -- unsigned int sellt; -- unsigned int tagset[2]; -- Bool showbar; -- Bool topbar; -- Client *clients; -- Client *sel; -- Client *stack; -- Monitor *next; -- Window barwin; -- const Layout *lt[2]; --}; -- - typedef struct { - const char *class; - const char *instance; -@@ -281,6 +260,33 @@ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -+struct Monitor { -+ char ltsymbol[16]; -+ float mfact; -+ int nmaster; -+ int num; -+ int by; /* bar geometry */ -+ int mx, my, mw, mh; /* screen size */ -+ int wx, wy, ww, wh; /* window area */ -+ unsigned int seltags; -+ unsigned int sellt; -+ unsigned int tagset[2]; -+ Bool showbar; -+ Bool topbar; -+ Client *clients; -+ Client *sel; -+ Client *stack; -+ Monitor *next; -+ Window barwin; -+ const Layout *lt[2]; -+ int curtag; -+ int prevtag; -+ const Layout *lts[LENGTH(tags) + 1]; -+ float mfacts[LENGTH(tags) + 1]; -+ int nmasters[LENGTH(tags) + 1]; -+ Bool showbars[LENGTH(tags) + 1]; -+}; -+ - /* compile-time check if all tags fit into an unsigned int bit array. */ - struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -@@ -661,6 +667,7 @@ - Monitor * - createmon(void) { - Monitor *m; -+ unsigned int i; - - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); -@@ -672,6 +679,16 @@ - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -+ -+ /* pertag init */ -+ m->curtag = m->prevtag = 1; -+ for(i=0; i < LENGTH(tags) + 1 ; i++) { -+ m->mfacts[i] = mfact; -+ m->nmasters[i] = nmaster; -+ m->lts[i] = &layouts[0]; -+ m->showbars[i] = m->showbar; -+ } -+ - return m; - } - -@@ -1028,7 +1045,8 @@ - - void - incnmaster(const Arg *arg) { -- selmon->nmaster = MAX(selmon->nmaster + arg->i, 1); -+ selmon->nmasters[selmon->curtag] = MAX(selmon->nmaster + arg->i, 1); -+ selmon->nmaster = selmon->nmasters[selmon->curtag]; - arrange(selmon); - } - -@@ -1515,7 +1533,7 @@ - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if(arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) - arrange(selmon); -@@ -1533,7 +1551,7 @@ - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if(f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->mfacts[selmon->curtag] = f; - arrange(selmon); - } - -@@ -1680,7 +1698,7 @@ - - void - togglebar(const Arg *arg) { -- selmon->showbar = !selmon->showbar; -+ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); - arrange(selmon); -@@ -1699,13 +1717,28 @@ - - void - toggletag(const Arg *arg) { -- unsigned int newtags; -+ unsigned int i, newtags; - - if(!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { - selmon->sel->tags = newtags; -+ if(newtags == ~0) { -+ selmon->prevtag = selmon->curtag; -+ selmon->curtag = 0; -+ } -+ if(!(newtags & 1 << (selmon->curtag - 1))) { -+ selmon->prevtag = selmon->curtag; -+ for (i=0; !(newtags & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ selmon->sel->tags = newtags; -+ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ selmon->nmaster = selmon->nmasters[selmon->curtag]; -+ if (selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - focus(NULL); - arrange(selmon); - } -@@ -1982,11 +2015,30 @@ - - void - view(const Arg *arg) { -+ unsigned int i; -+ - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if(arg->ui & TAGMASK) -+ if(arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->prevtag = selmon->curtag; -+ if(arg->ui == ~0) -+ selmon->curtag = 0; -+ else { -+ for (i=0; !(arg->ui & 1 << i); i++); -+ selmon->curtag = i + 1; -+ } -+ } else { -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ selmon->curtag^= selmon->prevtag; -+ selmon->prevtag= selmon->curtag ^ selmon->prevtag; -+ } -+ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; -+ selmon->mfact = selmon->mfacts[selmon->curtag]; -+ selmon->nmaster = selmon->nmasters[selmon->curtag]; -+ if(selmon->showbar != selmon->showbars[selmon->curtag]) -+ togglebar(NULL); - focus(NULL); - arrange(selmon); - } diff --git a/dwm.suckless.org/patches/historical/dwm-uselessgap-5.8.diff b/dwm.suckless.org/patches/historical/dwm-uselessgap-5.8.diff @@ -1,49 +0,0 @@ -diff -r 72e52c5333ef config.def.h ---- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 -+++ b/config.def.h Thu Mar 11 16:32:24 2010 +0100 -@@ -9,6 +9,7 @@ - static const char selbgcolor[] = "#0066ff"; - static const char selfgcolor[] = "#ffffff"; - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int gappx = 6; /* gap pixel between 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 */ -diff -r 72e52c5333ef dwm.c ---- a/dwm.c Wed Nov 25 13:56:17 2009 +0000 -+++ b/dwm.c Thu Mar 11 16:32:24 2010 +0100 -@@ -269,6 +269,7 @@ - static DC dc; - static Monitor *mons = NULL, *selmon = NULL; - static Window root; -+static int globalborder ; - - /* configuration, allows nested code to access above variables */ - #include "config.h" -@@ -1299,16 +1300,21 @@ - resize(Client *c, int x, int y, int w, int h, Bool interact) { - XWindowChanges wc; - -+ if(c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) { globalborder = 0 ; } -+ else { -+ if (selmon->lt[selmon->sellt]->arrange == monocle) { globalborder = 0 - borderpx ; } -+ else { globalborder = gappx ; } -+ } - if(applysizehints(c, &x, &y, &w, &h, interact)) { -- c->x = wc.x = x; -- c->y = wc.y = y; -- c->w = wc.width = w; -- c->h = wc.height = h; -+ c->x = wc.x = x + globalborder; -+ c->y = wc.y = y + globalborder; -+ c->w = wc.width = w - 2 * globalborder ; -+ c->h = wc.height = h - 2 * globalborder ; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -- } -+ } - } - - void diff --git a/dwm.suckless.org/patches/horizgrid.md b/dwm.suckless.org/patches/horizgrid.md @@ -1,37 +0,0 @@ -horizontal grid -=============== - -Description ------------ -This patch is a variant of [gapless_grid](gapless_grid). It arranges windows in a grid pattern in which every window is roughly the same size, adjusted such that there are no gaps. However, this layout arranges the windows in a horizontal grid, rather than a vertical grid. - -Horizontal Grid Layout ----------------------- - - horizgrid (###) - +--------+--------+ - | | | - | | | - +-----+--+--+-----+ - | | | | - | | | | - +-----+-----+-----+ - - gapless_grid - +--------+--------+ - | | | - | +--------+ - +--------+ | - | +--------+ - | | | - +--------+--------+ - -Download --------- - - * [dwm-horizgrid-6.1.diff](dwm-horizgrid-6.1.diff) (20160108) - -Authors -------- - - * Marshall Mason - `<marshallmason2@gmail.com>` diff --git a/dwm.suckless.org/patches/dwm-horizgrid-6.1.diff b/dwm.suckless.org/patches/horizgrid/dwm-horizgrid-6.1.diff diff --git a/dwm.suckless.org/patches/horizgrid/index.md b/dwm.suckless.org/patches/horizgrid/index.md @@ -0,0 +1,37 @@ +horizontal grid +=============== + +Description +----------- +This patch is a variant of [gapless_grid](gapless_grid). It arranges windows in a grid pattern in which every window is roughly the same size, adjusted such that there are no gaps. However, this layout arranges the windows in a horizontal grid, rather than a vertical grid. + +Horizontal Grid Layout +---------------------- + + horizgrid (###) + +--------+--------+ + | | | + | | | + +-----+--+--+-----+ + | | | | + | | | | + +-----+-----+-----+ + + gapless_grid + +--------+--------+ + | | | + | +--------+ + +--------+ | + | +--------+ + | | | + +--------+--------+ + +Download +-------- + + * [dwm-horizgrid-6.1.diff](dwm-horizgrid-6.1.diff) (20160108) + +Authors +------- + + * Marshall Mason - `<marshallmason2@gmail.com>` diff --git a/dwm.suckless.org/patches/ispermanent.md b/dwm.suckless.org/patches/ispermanent.md @@ -1,18 +0,0 @@ -ispermanent -=========== - -Description ------------ - -Property for clients to avoid accidental termination by `killclient` for sticky -windows. - -Download --------- - -* [dwm-6.0-ispermanent.diff](dwm-6.0-ispermanent.diff) - -Author ------- - -* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> diff --git a/dwm.suckless.org/patches/dwm-6.0-ispermanent.diff b/dwm.suckless.org/patches/ispermanent/dwm-ispermanent-6.0.diff diff --git a/dwm.suckless.org/patches/ispermanent/index.md b/dwm.suckless.org/patches/ispermanent/index.md @@ -0,0 +1,18 @@ +ispermanent +=========== + +Description +----------- + +Property for clients to avoid accidental termination by `killclient` for sticky +windows. + +Download +-------- + +* [dwm-ispermanent-6.0.diff](dwm-ispermanent-6.0.diff) + +Author +------ + +* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> diff --git a/dwm.suckless.org/patches/keycodes.md b/dwm.suckless.org/patches/keycodes.md @@ -1,14 +0,0 @@ -Keycodes -======== -With this patch, handling key input is done with keycodes instead of keysyms. -This way, input is independent from keyboard layout (you can get keycodes -using xev to adapt config.h) - -Download --------- -* [dwm-keycodes-6.1.diff](dwm-keycodes-6.1.diff) -* [dwm-keycodes-20170511-ceac8c9.diff](dwm-keycodes-20170511-ceac8c9.diff) - -Author ------- -* Quentin Rameau <quinq@fifth.space> diff --git a/dwm.suckless.org/patches/dwm-keycodes-20170511-ceac8c9.diff b/dwm.suckless.org/patches/keycodes/dwm-keycodes-20170511-ceac8c9.diff diff --git a/dwm.suckless.org/patches/dwm-keycodes-6.1.diff b/dwm.suckless.org/patches/keycodes/dwm-keycodes-6.1.diff diff --git a/dwm.suckless.org/patches/keycodes/index.md b/dwm.suckless.org/patches/keycodes/index.md @@ -0,0 +1,14 @@ +Keycodes +======== +With this patch, handling key input is done with keycodes instead of keysyms. +This way, input is independent from keyboard layout (you can get keycodes +using xev to adapt config.h) + +Download +-------- +* [dwm-keycodes-6.1.diff](dwm-keycodes-6.1.diff) +* [dwm-keycodes-20170511-ceac8c9.diff](dwm-keycodes-20170511-ceac8c9.diff) + +Author +------ +* Quentin Rameau <quinq@fifth.space> diff --git a/dwm.suckless.org/patches/keymodes-5.8.2-vim-config.h b/dwm.suckless.org/patches/keymodes-5.8.2-vim-config.h @@ -1,163 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -static const char normbordercolor[] = "#1f1f1f"; -static const char normbgcolor[] = "#1f1f1f"; -static const char normfgcolor[] = "#c0c0c0"; -static const char selbordercolor[] = "#ff8000"; -static const char selbgcolor[] = "#1f1f1f"; -static const char selfgcolor[] = "#ff8000"; -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 */ - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5" }; - -/* include(s) depending on the tags array */ -#include "flextile.h" - -/* include(s) defining functions */ -#include "keymodes.pre.h" - -static const Rule rules[] = { - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, True, -1 }, - { "Firefox", NULL, NULL, 1 << 4, False, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.6; /* factor of master area size [0.05..0.95] */ -static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ -static const int layoutaxis[] = { - 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ - 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ - 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ -}; - -static const Layout layouts[] = { - /* symbol arrange function */ - { "[M]", monocle }, /* first entry is default */ - { "[]=", tile }, - { "><>", NULL }, /* no layout function means floating behavior */ -}; - -/* key definitions */ -#define MODKEY Mod1Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; -static const char *haltcmd[] = { "sudo", "halt", NULL }; -static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; -static const char *sleepcmd[] = { "sudo", "pm-suspend", NULL }; -static const char *termcmd[] = { "uxterm", NULL }; -static const char *audio1cmd[] = { "amixer", "--quiet", "sset", "Master", "1+", NULL }; -static const char *audio2cmd[] = { "amixer", "--quiet", "sset", "Master", "1-", NULL }; -static const char *audio3cmd[] = { "amixer", "--quiet", "sset", "Master", "toggle", NULL }; - -#include <X11/XF86keysym.h> -static Key keys[] = { - /* modifier key function argument */ - { 0, XK_Super_L, setkeymode, {.ui = COMMANDMODE} }, - { 0, XF86XK_AudioRaiseVolume, spawn, {.v = audio1cmd} }, - { 0, XF86XK_AudioLowerVolume, spawn, {.v = audio2cmd} }, - { MODKEY|ShiftMask, XK_m, spawn, {.v = audio3cmd} }, - { MODKEY, XK_Down, focusstack, {.i = +1 } }, - { MODKEY, XK_Up, focusstack, {.i = -1 } }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) -}; - -static const int h_master[] = {+1, 2, 2}; -static const int j_master[] = {-2, 1, 1}; -static const int k_master[] = {+2, 1, 1}; -static const int l_master[] = {-1, 2, 2}; - -static Key cmdkeys[] = { - /* modifier keys function argument */ - { 0, XK_Escape, clearcmd, {0} }, - { ControlMask, XK_c, clearcmd, {0} }, - { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, - { 0, XF86XK_Standby, spawn, {.v = sleepcmd} }, -}; -static Command commands[] = { - /* modifier (4 keys) keysyms (4 keys) function argument */ - { {0, 0, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = +1} }, - { {0, ShiftMask, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = -1} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_c, 0, 0}, closewindow, {0} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_h, 0, 0}, focustiled, {.i = -1} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_j, 0, 0}, focustiled, {.i = +2} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_k, 0, 0}, focustiled, {.i = -2} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_l, 0, 0}, focustiled, {.i = +1} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setmaster, {.v = h_master} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_j, 0, 0}, setmaster, {.v = j_master} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_k, 0, 0}, setmaster, {.v = k_master} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_l, 0, 0}, setmaster, {.v = l_master} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[0]} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_s, 0, 0}, split, {.ui = 2} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = +1} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = -1} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, split, {.ui = 1} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = +1} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = -1} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = +1} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = -1} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = -10.05} }, - { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = +10.05} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_minus, 0, 0}, resizemaster, {.f = -20.05} }, - { {ControlMask, 0, 0, 0}, {XK_w, XK_plus, 0, 0}, resizemaster, {.f = +20.05} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, - { {ShiftMask, ShiftMask, 0, 0}, {XK_period, XK_1, 0, 0}, spawn, {.v = termcmd} }, - { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_1, XK_t, 0}, tag, {.ui = 1 << 0} }, - { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_2, XK_t, 0}, tag, {.ui = 1 << 1} }, - { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_3, XK_t, 0}, tag, {.ui = 1 << 2} }, - { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_4, XK_t, 0}, tag, {.ui = 1 << 3} }, - { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_5, XK_t, 0}, tag, {.ui = 1 << 4} }, - { {0, 0, 0, 0}, {XK_1, XK_g, XK_t, 0}, view, {.ui = 1 << 0} }, - { {0, 0, 0, 0}, {XK_2, XK_g, XK_t, 0}, view, {.ui = 1 << 1} }, - { {0, 0, 0, 0}, {XK_3, XK_g, XK_t, 0}, view, {.ui = 1 << 2} }, - { {0, 0, 0, 0}, {XK_4, XK_g, XK_t, 0}, view, {.ui = 1 << 3} }, - { {0, 0, 0, 0}, {XK_5, XK_g, XK_t, 0}, view, {.ui = 1 << 4} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, - { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, - { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_q, XK_1, XK_Return}, spawn, {.v = haltcmd} }, - { {ShiftMask, 0, 0, 0}, {XK_period, XK_g, XK_o, XK_Return}, togglebar, {0} }, -}; - -/* button definitions */ -/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static Button buttons[] = { - /* click event mask button function argument */ -}; - -/* include(s) depending on the configuration variables */ -#include "keymodes.post.h" diff --git a/dwm.suckless.org/patches/keymodes-5.8.2-vim.diff b/dwm.suckless.org/patches/keymodes-5.8.2-vim.diff @@ -1,583 +0,0 @@ -diff -up ../dwm-5.8.2-1/config.def.h ./config.def.h ---- ../dwm-5.8.2-1/config.def.h 2010-06-11 01:10:05.465026000 +0200 -+++ ./config.def.h 2010-06-11 01:13:49.211525000 +0200 -@@ -19,6 +19,9 @@ static const char *tags[] = { "1", "2", - /* include(s) depending on the tags array */ - #include "flextile.h" - -+/* include(s) defining functions */ -+#include "keymodes.pre.h" -+ - static const Rule rules[] = { - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, True, -1 }, -@@ -36,9 +39,9 @@ static const int layoutaxis[] = { - - static const Layout layouts[] = { - /* symbol arrange function */ -- { "[]=", tile }, /* first entry is default */ -+ { "[M]", monocle }, /* first entry is default */ -+ { "[]=", tile }, - { "><>", NULL }, /* no layout function means floating behavior */ -- { "[M]", monocle }, - }; - - /* key definitions */ -@@ -55,9 +58,11 @@ static const Layout layouts[] = { - /* commands */ - static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; - static const char *termcmd[] = { "uxterm", NULL }; -+static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; - - static Key keys[] = { - /* modifier key function argument */ -+ { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -@@ -68,9 +73,9 @@ static Key keys[] = { - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, -- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, -- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, -- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -+ { MODKEY, XK_m, setlayout, {.v = &layouts[0]} }, -+ { MODKEY, XK_t, setlayout, {.v = &layouts[1]} }, -+ { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, -@@ -97,6 +102,54 @@ static Key keys[] = { - { MODKEY|ControlMask, XK_l, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ - }; - -+static const int h_master[] = {+1, 2, 2}; -+static const int j_master[] = {-2, 1, 1}; -+static const int k_master[] = {+2, 1, 1}; -+static const int l_master[] = {-1, 2, 2}; -+ -+static Key cmdkeys[] = { -+ /* modifier keys function argument */ -+ { 0, XK_Escape, clearcmd, {0} }, -+ { ControlMask, XK_c, clearcmd, {0} }, -+ { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, -+}; -+static Command commands[] = { -+ /* modifier (4 keys) keysyms (4 keys) function argument */ -+ { {0, 0, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = +1} }, -+ { {0, ShiftMask, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = -1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_c, 0, 0}, closewindow, {0} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_h, 0, 0}, focustiled, {.i = -1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_j, 0, 0}, focustiled, {.i = +2} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_k, 0, 0}, focustiled, {.i = -2} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_l, 0, 0}, focustiled, {.i = +1} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setmaster, {.v = h_master} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_j, 0, 0}, setmaster, {.v = j_master} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_k, 0, 0}, setmaster, {.v = k_master} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_l, 0, 0}, setmaster, {.v = l_master} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[0]} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_s, 0, 0}, split, {.ui = 2} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = +1} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = -1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, split, {.ui = 1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = +1} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = -1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = +1} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = -1} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = -10.05} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = +10.05} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_minus, 0, 0}, resizemaster, {.f = -20.05} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_plus, 0, 0}, resizemaster, {.f = +20.05} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, -+ { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, -+}; -+ - /* button definitions */ - /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ - static Button buttons[] = { -@@ -114,3 +167,5 @@ static Button buttons[] = { - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, - }; - -+/* include(s) depending on the configuration variables */ -+#include "keymodes.post.h" -diff -up ../dwm-5.8.2-1/dwm.c ./dwm.c ---- ../dwm-5.8.2-1/dwm.c 2010-06-11 01:10:05.473958000 +0200 -+++ ./dwm.c 2010-06-11 01:13:49.226865000 +0200 -@@ -954,7 +954,7 @@ grabbuttons(Client *c, Bool focused) { - } - - void --grabkeys(void) { -+grabdefkeys(void) { - updatenumlockmask(); - { - unsigned int i, j; -@@ -1036,7 +1036,7 @@ isuniquegeom(XineramaScreenInfo *unique, - #endif /* XINERAMA */ - - void --keypress(XEvent *e) { -+defkeypress(XEvent *e) { - unsigned int i; - KeySym keysym; - XKeyEvent *ev; -diff -up ../dwm-5.8.2-1/keymodes.post.h ./keymodes.post.h ---- ../dwm-5.8.2-1/keymodes.post.h 2010-06-11 01:12:53.000000000 +0200 -+++ ./keymodes.post.h 2010-06-11 01:13:49.287434000 +0200 -@@ -0,0 +1,409 @@ -+/* See LICENSE file for copyright and license details. */ -+/* © 2010 joten <joten@freenet.de> */ -+ -+/* function implementations */ -+void -+adjacenttag(const Arg *arg) { -+ int nexttag = selmon->curtag + arg->i; -+ Arg a; -+ -+ if(nexttag > LENGTH(tags)) -+ nexttag = 1; -+ else if(nexttag < 1) -+ nexttag = LENGTH(tags); -+ a.ui = 1 << (nexttag - 1); -+ tag(&a); -+} -+ -+void -+adjacentview(const Arg *arg) { -+ int nexttag = selmon->curtag + arg->i; -+ Arg a; -+ -+ if(nexttag > LENGTH(tags)) -+ nexttag = 1; -+ else if(nexttag < 1) -+ nexttag = LENGTH(tags); -+ a.ui = 1 << (nexttag - 1); -+ view(&a); -+} -+ -+void -+clearcmd(const Arg *arg) { -+ unsigned int i; -+ -+ for(i = 0; i < LENGTH(cmdkeysym); i++) { -+ cmdkeysym[i] = 0; -+ cmdmod[i] = 0; -+ } -+} -+ -+void -+closewindow(const Arg *arg) { -+ unsigned int j, n; -+ Client *i; -+ -+ if(!selmon->sel || selmon->sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) -+ return; -+ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) -+ if(i == selmon->sel) -+ j = n + 1; -+ if(j == 0 || n < 2) -+ return; -+ if(j <= selmon->msplit) { -+ if(selmon->ltaxis[1] == 3 || selmon->msplit == 1) { -+ selmon->msplits[selmon->curtag] = selmon->msplit = n; -+ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = selmon->ltaxis[2]; -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; -+ } else if(j == selmon->msplit && (selmon->ltaxis[2] == 3 || selmon->msplit == n - 1)) { -+ selmon->msplits[selmon->curtag] = selmon->msplit -= 1; -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; -+ } else -+ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; -+ } else { -+ if(selmon->ltaxis[2] == 3 || selmon->msplit == n - 1) -+ selmon->msplits[selmon->curtag] = selmon->msplit = n; -+ else if(j == selmon->msplit + 1 && (selmon->ltaxis[1] == 3 || selmon->msplit == 1)) { -+ selmon->msplits[selmon->curtag] = selmon->msplit += 1; -+ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; -+ } else -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; -+ } -+ arrange(selmon); -+} -+ -+void -+exchangewindow(const Arg *arg) { -+ int j = 0, n; -+ Client *c, *i, *sel = selmon->sel; -+ -+ if(!sel || sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) -+ return; -+ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) -+ if(i == selmon->sel) -+ j = n + 1; -+ if(j == 0 || n < 2 -+ || (j <= selmon->msplit && selmon->ltaxis[1] == 3 && selmon->msplit > 1 && !(j == 1 && arg->i < 0) && !(j == selmon->msplit && arg->i > 0)) -+ || (j > selmon->msplit && selmon->ltaxis[2] == 3 && n - selmon->msplit > 1 && !(j == selmon->msplit + 1 && arg->i < 0) && !(j == n && arg->i > 0))) -+ return; -+ if(arg->i < 0) { -+ 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; -+ } -+ } else { -+ 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); -+} -+ -+void -+focustiled(const Arg *arg) { -+ float f; -+ unsigned int j = 0, k, n; -+ Client *c = NULL, *i; -+ -+ if(!selmon->sel || selmon->sel->isfloating || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) -+ return; -+ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) -+ if(i == selmon->sel) -+ j = n + 1; -+ if(n < 2) -+ return; -+ if(arg->i < 0 -+ && ((j > 1 && j <= selmon->msplit && selmon->ltaxis[1] == -(arg->i)) || (j > (selmon->msplit + 1) && j <= n && selmon->ltaxis[2] == -(arg->i)))) { -+ c = prevtiled(selmon->sel); -+ } else if(arg->i > 0 -+ && ((j > 0 && j < selmon->msplit && selmon->ltaxis[1] == arg->i) || (j > selmon->msplit && j < n && selmon->ltaxis[2] == arg->i))) { -+ c = nexttiled(selmon->sel->next); -+ } else if(arg->i < 0 -+ && n > selmon->msplit -+ && j > selmon->msplit && j <= n -+ && (selmon->ltaxis[2] - arg->i) == 3) -+ f = (float)(j - selmon->msplit) / (n - selmon->msplit) * selmon->msplit; -+ else if(arg->i > 0 -+ && n > selmon->msplit -+ && j > 0 && j <= selmon->msplit -+ && (selmon->ltaxis[1] + arg->i) == 3) -+ f = selmon->msplit + (float)j / selmon->msplit * (n - selmon->msplit); -+ if(f > 0) { -+ k = (unsigned int)f; -+ if(f - k > 0) -+ k++; -+ for(j = 1, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), j++) -+ if(j == k) -+ c = i; -+ } -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ -+void -+focuswindow(const Arg *arg) { -+ unsigned int j = 0, k = 0, n; -+ Client *c = NULL, *i; -+ -+ if(!selmon->sel || selmon->sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) -+ return; -+ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) -+ if(i == selmon->sel) -+ j = n + 1; -+ if(j == 0 || n < 2 || (selmon->msplit == n && selmon->ltaxis[1] == 3)) -+ return; -+ if(arg->i < 0) { -+ if((j > 1 && j <= selmon->msplit && selmon->ltaxis[1] == 3) || j == 1) { -+ k = n; -+ } else if(j > selmon->msplit + 1 && j <= n && selmon->ltaxis[2] == 3) { -+ k = selmon->msplit; -+ } else -+ c = prevtiled(selmon->sel); -+ } else { -+ if(j < selmon->msplit && selmon->ltaxis[1] == 3) { -+ k = selmon->msplit + 1; -+ } else if((j > selmon->msplit && j < n && selmon->ltaxis[2] == 3) || j == n) { -+ k = 1; -+ } else -+ c = nexttiled(selmon->sel->next); -+ } -+ if(!c && k) -+ for(j = 1, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), j++) -+ if(j == k) -+ c = i; -+ if(c) { -+ focus(c); -+ restack(selmon); -+ } -+} -+ -+void -+grabkeys(void) { -+ if(keymode == INSERTMODE) { -+ grabdefkeys(); -+ } else if(keymode == COMMANDMODE) { -+ XUngrabKey(dpy, AnyKey, AnyModifier, root); -+ XGrabKey(dpy, AnyKey, AnyModifier, root, -+ True, GrabModeAsync, GrabModeAsync); -+ } -+} -+ -+void -+keypress(XEvent *e) { -+ unsigned int i, j; -+ Arg a = {0}; -+ Bool ismatch = False, maybematch = False; -+ KeySym keysym; -+ XKeyEvent *ev; -+ -+ if(keymode == INSERTMODE) -+ defkeypress(e); -+ else if(keymode == COMMANDMODE) { -+ ev = &e->xkey; -+ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); -+ if(keysym < XK_Shift_L || keysym > XK_Hyper_R) { -+ for(i = 0; i < LENGTH(cmdkeys); i++) -+ if(keysym == cmdkeys[i].keysym -+ && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) -+ && cmdkeys[i].func) { -+ cmdkeys[i].func(&(cmdkeys[i].arg)); -+ ismatch = True; -+ break; -+ } -+ if(!ismatch) { -+ for(j = 0; j < LENGTH(cmdkeysym); j++) -+ if(cmdkeysym[j] == 0) { -+ cmdkeysym[j] = keysym; -+ cmdmod[j] = ev->state; -+ break; -+ } -+ for(i = 0; i < LENGTH(commands); i++) { -+ for(j = 0; j < LENGTH(cmdkeysym); j++) { -+ if(cmdkeysym[j] == commands[i].keysym[j] -+ && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) -+ ismatch = True; -+ else if(cmdkeysym[j] == 0 -+ && cmdmod[j] == 0) { -+ ismatch = False; -+ maybematch = True; -+ break; -+ } else { -+ ismatch = False; -+ break; -+ } -+ } -+ if(ismatch) { -+ if(commands[i].func) -+ commands[i].func(&(commands[i].arg)); -+ clearcmd(&a); -+ break; -+ } -+ -+ } -+ if(!maybematch) -+ clearcmd(&a); -+ } -+ } -+ } -+} -+ -+void -+onlyclient(const Arg *arg) { -+ Client *c; -+ XEvent ev; -+ -+ if(!selmon->sel) -+ return; -+ for(c = selmon->clients; c; c = c->next) -+ if(c != selmon->sel && ISVISIBLE(c)) { -+ if(isprotodel(c)) { -+ ev.type = ClientMessage; -+ ev.xclient.window = c->win; -+ ev.xclient.message_type = wmatom[WMProtocols]; -+ ev.xclient.format = 32; -+ ev.xclient.data.l[0] = wmatom[WMDelete]; -+ ev.xclient.data.l[1] = CurrentTime; -+ XSendEvent(dpy, c->win, False, NoEventMask, &ev); -+ } -+ else { -+ XGrabServer(dpy); -+ XSetErrorHandler(xerrordummy); -+ XSetCloseDownMode(dpy, DestroyAll); -+ XKillClient(dpy, c->win); -+ XSync(dpy, False); -+ XSetErrorHandler(xerror); -+ XUngrabServer(dpy); -+ } -+ } -+} -+ -+Client * -+prevtiled(Client *c) { -+ Client *i, *p; -+ -+ for(i = selmon->clients, p = NULL; i && i != c; i = i->next) -+ if(!i->isfloating && ISVISIBLE(i)) -+ p = i; -+ return p; -+} -+ -+void -+resizemaster(const Arg *arg) { -+ float f; -+ Arg a; -+ -+ if(!arg || selmon->lt[selmon->sellt]->arrange != tile) -+ return; -+ f = (arg->f < 0 ? -arg->f : arg->f) - selmon->ltaxis[0] * 10; -+ if(f < 0 || f > 1.9) -+ return; -+ a.f = arg->f / abs(arg->f) * f; -+ setmfact(&a); -+} -+ -+void -+setkeymode(const Arg *arg) { -+ Arg a = {0}; -+ -+ if(!arg) -+ return; -+ keymode = arg->ui; -+ clearcmd(&a); -+ grabkeys(); -+} -+ -+void -+setmaster(const Arg *arg) { -+ unsigned int i; -+ Arg a; -+ -+ if(!arg || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) -+ return; -+ for(i = 0; i < 3; i++) -+ selmon->ltaxes[selmon->curtag][i] = selmon->ltaxis[i] = ((int *)arg->i)[i]; -+ selmon->msplits[selmon->curtag] = selmon->msplit = 1; -+ if(selmon->sel && !selmon->sel->isfloating && selmon->sel != nexttiled(selmon->clients)) { -+ detach(selmon->sel); -+ attach(selmon->sel); -+ focus(selmon->sel); -+ } -+ if(selmon->lt[selmon->sellt]->arrange == monocle) { -+ for(i = 0; i < LENGTH(layouts) && (&layouts[i])->arrange != tile; i++); -+ a.v = &layouts[i]; -+ setlayout(&a); -+ if(!selmon->sel) -+ arrange(selmon); -+ } else -+ arrange(selmon); -+} -+ -+void -+split(const Arg *arg) { -+ unsigned int j = 0, k, n; -+ Arg a; -+ Client *i; -+ -+ if(!arg || !selmon->sel || selmon->sel->isfloating || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) -+ return; -+ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) -+ if(i == selmon->sel) -+ j = n + 1; -+ if(j == 0 || n < 2) -+ return; -+ if(selmon->lt[selmon->sellt]->arrange == monocle) { -+ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0] = arg->i; -+ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; -+ for(k = 0; k < LENGTH(layouts) && (&layouts[k])->arrange != tile; k++); -+ a.v = &layouts[k]; -+ setlayout(&a); -+ } else if(j <= selmon->msplit) { -+ if(selmon->ltaxis[1] == 3 || selmon->msplit == 1) { -+ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = arg->i; -+ if(selmon->ltaxis[2] == 3 || selmon->msplit == 1) -+ selmon->msplits[selmon->curtag] = selmon->msplit = 2; -+ arrange(selmon); -+ } else if(selmon->ltaxis[1] == arg->i && selmon->msplit < n) { -+ selmon->msplits[selmon->curtag] = selmon->msplit += 1; -+ arrange(selmon); -+ } else if(selmon->ltaxis[1] + arg->i == 3 && selmon->msplit == n) { -+ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0] = arg->i; -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; -+ selmon->msplits[selmon->curtag] = selmon->msplit = n - 1; -+ arrange(selmon); -+ } -+ } else if(n > 2) { -+ if(selmon->ltaxis[2] == 3 || selmon->msplit == n - 1) { -+ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = arg->i; -+ if(selmon->ltaxis[1] == 3 || selmon->msplit == n - 1) -+ selmon->msplits[selmon->curtag] = selmon->msplit = n - 2; -+ arrange(selmon); -+ } else if(selmon->ltaxis[2] == arg->i && selmon->msplit > 1) { -+ selmon->msplits[selmon->curtag] = selmon->msplit -= 1; -+ arrange(selmon); -+ } -+ } -+} -diff -up ../dwm-5.8.2-1/keymodes.pre.h ./keymodes.pre.h ---- ../dwm-5.8.2-1/keymodes.pre.h 2010-06-11 01:12:49.000000000 +0200 -+++ ./keymodes.pre.h 2010-06-11 01:13:50.660576000 +0200 -@@ -0,0 +1,34 @@ -+/* See LICENSE file for copyright and license details. */ -+/* © 2010 joten <joten@freenet.de> */ -+ -+#define COMMANDMODE 1 -+#define INSERTMODE 2 -+ -+typedef struct { -+ unsigned int mod[4]; -+ KeySym keysym[4]; -+ void (*func)(const Arg *); -+ const Arg arg; -+} Command; -+ -+/* function declarations */ -+static void adjacenttag(const Arg *arg); -+static void adjacentview(const Arg *arg); -+static void clearcmd(const Arg *arg); -+static void closewindow(const Arg *arg); -+static void defkeypress(XEvent *e); -+static void exchangewindow(const Arg *arg); -+static void focustiled(const Arg *arg); -+static void focuswindow(const Arg *arg); -+static void grabdefkeys(void); -+static void onlyclient(const Arg *arg); -+static Client *prevtiled(Client *c); -+static void resizemaster(const Arg *arg); -+static void setkeymode(const Arg *arg); -+static void setmaster(const Arg *arg); -+static void split(const Arg *arg); -+ -+/* variables */ -+static unsigned int cmdmod[4]; -+static unsigned int keymode = COMMANDMODE; -+static KeySym cmdkeysym[4]; diff --git a/dwm.suckless.org/patches/keymodes-5.8.2.diff b/dwm.suckless.org/patches/keymodes-5.8.2.diff @@ -1,239 +0,0 @@ -diff -up ../dwm-5.8.2-0/config.def.h ./config.def.h ---- ../dwm-5.8.2-0/config.def.h 2010-06-10 22:47:51.660949000 +0200 -+++ ./config.def.h 2010-06-11 00:18:55.082073000 +0200 -@@ -16,6 +16,9 @@ static const Bool topbar = Tr - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* include(s) defining functions */ -+#include "keymodes.pre.h" -+ - static const Rule rules[] = { - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, True, -1 }, -@@ -47,9 +50,11 @@ static const Layout layouts[] = { - /* commands */ - static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; - static const char *termcmd[] = { "uxterm", NULL }; -+static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; - - static Key keys[] = { - /* modifier key function argument */ -+ { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, -@@ -83,6 +88,30 @@ static Key keys[] = { - { MODKEY|ShiftMask, XK_q, quit, {0} }, - }; - -+static Key cmdkeys[] = { -+ /* modifier keys function argument */ -+ { 0, XK_Escape, clearcmd, {0} }, -+ { ControlMask, XK_c, clearcmd, {0} }, -+ { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, -+}; -+static Command commands[] = { -+ /* modifier (4 keys) keysyms (4 keys) function argument */ -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setlayout, {.v = &layouts[0]} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[2]} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, setlayout, {.v = &layouts[0]} }, -+ { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = -0.05} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = +0.05} }, -+ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, -+ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, -+ { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, -+}; -+ - /* button definitions */ - /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ - static Button buttons[] = { -@@ -100,3 +129,5 @@ static Button buttons[] = { - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, - }; - -+/* include(s) depending on the configuration variables */ -+#include "keymodes.post.h" -diff -up ../dwm-5.8.2-0/dwm.c ./dwm.c ---- ../dwm-5.8.2-0/dwm.c 2010-06-10 22:47:51.669677000 +0200 -+++ ./dwm.c 2010-06-11 00:18:55.106090000 +0200 -@@ -970,7 +970,7 @@ grabbuttons(Client *c, Bool focused) { - } - - void --grabkeys(void) { -+grabdefkeys(void) { - updatenumlockmask(); - { - unsigned int i, j; -@@ -1052,7 +1052,7 @@ isuniquegeom(XineramaScreenInfo *unique, - #endif /* XINERAMA */ - - void --keypress(XEvent *e) { -+defkeypress(XEvent *e) { - unsigned int i; - KeySym keysym; - XKeyEvent *ev; -diff -up ../dwm-5.8.2-0/keymodes.post.h ./keymodes.post.h ---- ../dwm-5.8.2-0/keymodes.post.h 2010-06-11 00:21:46.000000000 +0200 -+++ ./keymodes.post.h 2010-06-11 00:18:55.119222000 +0200 -@@ -0,0 +1,124 @@ -+/* See LICENSE file for copyright and license details. */ -+/* © 2010 joten <joten@freenet.de> */ -+ -+/* function implementations */ -+void -+clearcmd(const Arg *arg) { -+ unsigned int i; -+ -+ for(i = 0; i < LENGTH(cmdkeysym); i++) { -+ cmdkeysym[i] = 0; -+ cmdmod[i] = 0; -+ } -+} -+ -+void -+grabkeys(void) { -+ if(keymode == INSERTMODE) { -+ grabdefkeys(); -+ } else if(keymode == COMMANDMODE) { -+ XUngrabKey(dpy, AnyKey, AnyModifier, root); -+ XGrabKey(dpy, AnyKey, AnyModifier, root, -+ True, GrabModeAsync, GrabModeAsync); -+ } -+} -+ -+void -+keypress(XEvent *e) { -+ unsigned int i, j; -+ Arg a = {0}; -+ Bool ismatch = False, maybematch = False; -+ KeySym keysym; -+ XKeyEvent *ev; -+ -+ if(keymode == INSERTMODE) -+ defkeypress(e); -+ else if(keymode == COMMANDMODE) { -+ ev = &e->xkey; -+ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); -+ if(keysym < XK_Shift_L || keysym > XK_Hyper_R) { -+ for(i = 0; i < LENGTH(cmdkeys); i++) -+ if(keysym == cmdkeys[i].keysym -+ && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) -+ && cmdkeys[i].func) { -+ cmdkeys[i].func(&(cmdkeys[i].arg)); -+ ismatch = True; -+ break; -+ } -+ if(!ismatch) { -+ for(j = 0; j < LENGTH(cmdkeysym); j++) -+ if(cmdkeysym[j] == 0) { -+ cmdkeysym[j] = keysym; -+ cmdmod[j] = ev->state; -+ break; -+ } -+ for(i = 0; i < LENGTH(commands); i++) { -+ for(j = 0; j < LENGTH(cmdkeysym); j++) { -+ if(cmdkeysym[j] == commands[i].keysym[j] -+ && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) -+ ismatch = True; -+ else if(cmdkeysym[j] == 0 -+ && cmdmod[j] == 0) { -+ ismatch = False; -+ maybematch = True; -+ break; -+ } else { -+ ismatch = False; -+ break; -+ } -+ } -+ if(ismatch) { -+ if(commands[i].func) -+ commands[i].func(&(commands[i].arg)); -+ clearcmd(&a); -+ break; -+ } -+ -+ } -+ if(!maybematch) -+ clearcmd(&a); -+ } -+ } -+ } -+} -+ -+void -+onlyclient(const Arg *arg) { -+ Client *c; -+ XEvent ev; -+ -+ if(!selmon->sel) -+ return; -+ for(c = selmon->clients; c; c = c->next) -+ if(c != selmon->sel && ISVISIBLE(c)) { -+ if(isprotodel(c)) { -+ ev.type = ClientMessage; -+ ev.xclient.window = c->win; -+ ev.xclient.message_type = wmatom[WMProtocols]; -+ ev.xclient.format = 32; -+ ev.xclient.data.l[0] = wmatom[WMDelete]; -+ ev.xclient.data.l[1] = CurrentTime; -+ XSendEvent(dpy, c->win, False, NoEventMask, &ev); -+ } -+ else { -+ XGrabServer(dpy); -+ XSetErrorHandler(xerrordummy); -+ XSetCloseDownMode(dpy, DestroyAll); -+ XKillClient(dpy, c->win); -+ XSync(dpy, False); -+ XSetErrorHandler(xerror); -+ XUngrabServer(dpy); -+ } -+ } -+} -+ -+void -+setkeymode(const Arg *arg) { -+ Arg a = {0}; -+ -+ if(!arg) -+ return; -+ keymode = arg->ui; -+ clearcmd(&a); -+ grabkeys(); -+} -diff -up ../dwm-5.8.2-0/keymodes.pre.h ./keymodes.pre.h ---- ../dwm-5.8.2-0/keymodes.pre.h 2010-06-11 00:21:38.000000000 +0200 -+++ ./keymodes.pre.h 2010-06-11 00:18:55.121759000 +0200 -@@ -0,0 +1,24 @@ -+/* See LICENSE file for copyright and license details. */ -+/* © 2010 joten <joten@freenet.de> */ -+ -+#define COMMANDMODE 1 -+#define INSERTMODE 2 -+ -+typedef struct { -+ unsigned int mod[4]; -+ KeySym keysym[4]; -+ void (*func)(const Arg *); -+ const Arg arg; -+} Command; -+ -+/* function declarations */ -+static void clearcmd(const Arg *arg); -+static void defkeypress(XEvent *e); -+static void grabdefkeys(void); -+static void onlyclient(const Arg *arg); -+static void setkeymode(const Arg *arg); -+ -+/* variables */ -+static unsigned int cmdmod[4]; -+static unsigned int keymode = COMMANDMODE; -+static KeySym cmdkeysym[4]; diff --git a/dwm.suckless.org/patches/keymodes.md b/dwm.suckless.org/patches/keymodes.md @@ -1,55 +0,0 @@ -# keymodes # - -## Description ## - -This patch provides key modes (like in Vim). There are two key modes: - - 1. `COMMANDMODE`: In this mode any key is grabbed and only the registered command keys have any effect. - 2. `INSERTMODE`: This is the normal key mode, in which the original key bindings of dwm and applications are effective and text can be entered. - -With key modes you can use any key binding for window management without risking conflicts with existing key bindings in applications or have a Vim-style dwm. - -There are two different patches: - - * keymodes: the minimal patch - * vim-keymodes: This patch tries to emulate the key bindings of Vim. Therefor it includes additional functions, which depend on the [flextile patch](flextile). - - -## Configuration ## - - (1) Download the favoured patch and apply it according to the [general instructions](.). If you choose vim-keymodes you will have to apply the [flextile patch](./flextile) first. - - (2) Transfer the changes made by the patch in `config.def.h` to your `config.h`, if needed; please see the patch file for details. - - (3) Verify the following lines in the aforementioned arrays; the key bindings are set in reference to a german keyboard layout. The entries in the `cmdkeys` array are defined like those in the original `keys` array of dwm and take precedence over the key bindings defined in the `commands` array. The modifier and keysym definitions in the `commands` array are themselves arrays with four entries, whereas the first entry in the modifier array corresponds to the first entry in the keysym array and so forth. You can find an example configuration [here][3]. - - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, - - static Key cmdkeys[] = { - /* modifier keys function argument */ - { 0, XK_Escape, clearcmd, {0} }, - { ControlMask, XK_c, clearcmd, {0} }, - { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, - }; - static Command commands[] = { - /* modifier (4 keys) keysyms (4 keys) function argument */ - ... - }; - - -## Usage ## - -With this patch dwm starts in `COMMANDMODE` and you can use the key bindings as defined in the `commands` array in `config.h`. Press `Escape` or `CTRL+c` to abort a command input and press `i` (in the default configuration) to enter `INSERTMODE` and use dwm normally with the key bindings defined in the `keys` array, navigate in applications and insert text. To get from `INSERTMODE` to `COMMANDMODE` press `ALT+Escape` (in the default configuration). - - -## Download ## - - * [keymodes-5.8.2.diff][1] (8.4k, +152 SLOC) (20100611, joten (at) freenet (dot) de) - * [keymodes-5.8.2-vim.diff][2] (22k, +446 SLOC) (20100611, joten (at) freenet (dot) de) - - -[1]: //dwm.suckless.org/patches/keymodes-5.8.2.diff -[2]: //dwm.suckless.org/patches/keymodes-5.8.2-vim.diff -[3]: //dwm.suckless.org/patches/keymodes-5.8.2-vim-config.h diff --git a/dwm.suckless.org/patches/keymodes/dwm-keymodes-5.8.2.diff b/dwm.suckless.org/patches/keymodes/dwm-keymodes-5.8.2.diff @@ -0,0 +1,239 @@ +diff -up ../dwm-5.8.2-0/config.def.h ./config.def.h +--- ../dwm-5.8.2-0/config.def.h 2010-06-10 22:47:51.660949000 +0200 ++++ ./config.def.h 2010-06-11 00:18:55.082073000 +0200 +@@ -16,6 +16,9 @@ static const Bool topbar = Tr + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + ++/* include(s) defining functions */ ++#include "keymodes.pre.h" ++ + static const Rule rules[] = { + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, True, -1 }, +@@ -47,9 +50,11 @@ static const Layout layouts[] = { + /* commands */ + static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; + static const char *termcmd[] = { "uxterm", NULL }; ++static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; + + static Key keys[] = { + /* modifier key function argument */ ++ { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, +@@ -83,6 +88,30 @@ static Key keys[] = { + { MODKEY|ShiftMask, XK_q, quit, {0} }, + }; + ++static Key cmdkeys[] = { ++ /* modifier keys function argument */ ++ { 0, XK_Escape, clearcmd, {0} }, ++ { ControlMask, XK_c, clearcmd, {0} }, ++ { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, ++}; ++static Command commands[] = { ++ /* modifier (4 keys) keysyms (4 keys) function argument */ ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setlayout, {.v = &layouts[0]} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[2]} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, setlayout, {.v = &layouts[0]} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = -0.05} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = +0.05} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, ++ { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, ++}; ++ + /* button definitions */ + /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ + static Button buttons[] = { +@@ -100,3 +129,5 @@ static Button buttons[] = { + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + }; + ++/* include(s) depending on the configuration variables */ ++#include "keymodes.post.h" +diff -up ../dwm-5.8.2-0/dwm.c ./dwm.c +--- ../dwm-5.8.2-0/dwm.c 2010-06-10 22:47:51.669677000 +0200 ++++ ./dwm.c 2010-06-11 00:18:55.106090000 +0200 +@@ -970,7 +970,7 @@ grabbuttons(Client *c, Bool focused) { + } + + void +-grabkeys(void) { ++grabdefkeys(void) { + updatenumlockmask(); + { + unsigned int i, j; +@@ -1052,7 +1052,7 @@ isuniquegeom(XineramaScreenInfo *unique, + #endif /* XINERAMA */ + + void +-keypress(XEvent *e) { ++defkeypress(XEvent *e) { + unsigned int i; + KeySym keysym; + XKeyEvent *ev; +diff -up ../dwm-5.8.2-0/keymodes.post.h ./keymodes.post.h +--- ../dwm-5.8.2-0/keymodes.post.h 2010-06-11 00:21:46.000000000 +0200 ++++ ./keymodes.post.h 2010-06-11 00:18:55.119222000 +0200 +@@ -0,0 +1,124 @@ ++/* See LICENSE file for copyright and license details. */ ++/* © 2010 joten <joten@freenet.de> */ ++ ++/* function implementations */ ++void ++clearcmd(const Arg *arg) { ++ unsigned int i; ++ ++ for(i = 0; i < LENGTH(cmdkeysym); i++) { ++ cmdkeysym[i] = 0; ++ cmdmod[i] = 0; ++ } ++} ++ ++void ++grabkeys(void) { ++ if(keymode == INSERTMODE) { ++ grabdefkeys(); ++ } else if(keymode == COMMANDMODE) { ++ XUngrabKey(dpy, AnyKey, AnyModifier, root); ++ XGrabKey(dpy, AnyKey, AnyModifier, root, ++ True, GrabModeAsync, GrabModeAsync); ++ } ++} ++ ++void ++keypress(XEvent *e) { ++ unsigned int i, j; ++ Arg a = {0}; ++ Bool ismatch = False, maybematch = False; ++ KeySym keysym; ++ XKeyEvent *ev; ++ ++ if(keymode == INSERTMODE) ++ defkeypress(e); ++ else if(keymode == COMMANDMODE) { ++ ev = &e->xkey; ++ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); ++ if(keysym < XK_Shift_L || keysym > XK_Hyper_R) { ++ for(i = 0; i < LENGTH(cmdkeys); i++) ++ if(keysym == cmdkeys[i].keysym ++ && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) ++ && cmdkeys[i].func) { ++ cmdkeys[i].func(&(cmdkeys[i].arg)); ++ ismatch = True; ++ break; ++ } ++ if(!ismatch) { ++ for(j = 0; j < LENGTH(cmdkeysym); j++) ++ if(cmdkeysym[j] == 0) { ++ cmdkeysym[j] = keysym; ++ cmdmod[j] = ev->state; ++ break; ++ } ++ for(i = 0; i < LENGTH(commands); i++) { ++ for(j = 0; j < LENGTH(cmdkeysym); j++) { ++ if(cmdkeysym[j] == commands[i].keysym[j] ++ && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) ++ ismatch = True; ++ else if(cmdkeysym[j] == 0 ++ && cmdmod[j] == 0) { ++ ismatch = False; ++ maybematch = True; ++ break; ++ } else { ++ ismatch = False; ++ break; ++ } ++ } ++ if(ismatch) { ++ if(commands[i].func) ++ commands[i].func(&(commands[i].arg)); ++ clearcmd(&a); ++ break; ++ } ++ ++ } ++ if(!maybematch) ++ clearcmd(&a); ++ } ++ } ++ } ++} ++ ++void ++onlyclient(const Arg *arg) { ++ Client *c; ++ XEvent ev; ++ ++ if(!selmon->sel) ++ return; ++ for(c = selmon->clients; c; c = c->next) ++ if(c != selmon->sel && ISVISIBLE(c)) { ++ if(isprotodel(c)) { ++ ev.type = ClientMessage; ++ ev.xclient.window = c->win; ++ ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.format = 32; ++ ev.xclient.data.l[0] = wmatom[WMDelete]; ++ ev.xclient.data.l[1] = CurrentTime; ++ XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ } ++ else { ++ XGrabServer(dpy); ++ XSetErrorHandler(xerrordummy); ++ XSetCloseDownMode(dpy, DestroyAll); ++ XKillClient(dpy, c->win); ++ XSync(dpy, False); ++ XSetErrorHandler(xerror); ++ XUngrabServer(dpy); ++ } ++ } ++} ++ ++void ++setkeymode(const Arg *arg) { ++ Arg a = {0}; ++ ++ if(!arg) ++ return; ++ keymode = arg->ui; ++ clearcmd(&a); ++ grabkeys(); ++} +diff -up ../dwm-5.8.2-0/keymodes.pre.h ./keymodes.pre.h +--- ../dwm-5.8.2-0/keymodes.pre.h 2010-06-11 00:21:38.000000000 +0200 ++++ ./keymodes.pre.h 2010-06-11 00:18:55.121759000 +0200 +@@ -0,0 +1,24 @@ ++/* See LICENSE file for copyright and license details. */ ++/* © 2010 joten <joten@freenet.de> */ ++ ++#define COMMANDMODE 1 ++#define INSERTMODE 2 ++ ++typedef struct { ++ unsigned int mod[4]; ++ KeySym keysym[4]; ++ void (*func)(const Arg *); ++ const Arg arg; ++} Command; ++ ++/* function declarations */ ++static void clearcmd(const Arg *arg); ++static void defkeypress(XEvent *e); ++static void grabdefkeys(void); ++static void onlyclient(const Arg *arg); ++static void setkeymode(const Arg *arg); ++ ++/* variables */ ++static unsigned int cmdmod[4]; ++static unsigned int keymode = COMMANDMODE; ++static KeySym cmdkeysym[4]; diff --git a/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-5.8.2.diff b/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-5.8.2.diff @@ -0,0 +1,583 @@ +diff -up ../dwm-5.8.2-1/config.def.h ./config.def.h +--- ../dwm-5.8.2-1/config.def.h 2010-06-11 01:10:05.465026000 +0200 ++++ ./config.def.h 2010-06-11 01:13:49.211525000 +0200 +@@ -19,6 +19,9 @@ static const char *tags[] = { "1", "2", + /* include(s) depending on the tags array */ + #include "flextile.h" + ++/* include(s) defining functions */ ++#include "keymodes.pre.h" ++ + static const Rule rules[] = { + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, True, -1 }, +@@ -36,9 +39,9 @@ static const int layoutaxis[] = { + + static const Layout layouts[] = { + /* symbol arrange function */ +- { "[]=", tile }, /* first entry is default */ ++ { "[M]", monocle }, /* first entry is default */ ++ { "[]=", tile }, + { "><>", NULL }, /* no layout function means floating behavior */ +- { "[M]", monocle }, + }; + + /* key definitions */ +@@ -55,9 +58,11 @@ static const Layout layouts[] = { + /* commands */ + static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; + static const char *termcmd[] = { "uxterm", NULL }; ++static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; + + static Key keys[] = { + /* modifier key function argument */ ++ { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, +@@ -68,9 +73,9 @@ static Key keys[] = { + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, +- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, +- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, +- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, XK_m, setlayout, {.v = &layouts[0]} }, ++ { MODKEY, XK_t, setlayout, {.v = &layouts[1]} }, ++ { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, +@@ -97,6 +102,54 @@ static Key keys[] = { + { MODKEY|ControlMask, XK_l, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ + }; + ++static const int h_master[] = {+1, 2, 2}; ++static const int j_master[] = {-2, 1, 1}; ++static const int k_master[] = {+2, 1, 1}; ++static const int l_master[] = {-1, 2, 2}; ++ ++static Key cmdkeys[] = { ++ /* modifier keys function argument */ ++ { 0, XK_Escape, clearcmd, {0} }, ++ { ControlMask, XK_c, clearcmd, {0} }, ++ { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, ++}; ++static Command commands[] = { ++ /* modifier (4 keys) keysyms (4 keys) function argument */ ++ { {0, 0, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = +1} }, ++ { {0, ShiftMask, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = -1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_c, 0, 0}, closewindow, {0} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_h, 0, 0}, focustiled, {.i = -1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_j, 0, 0}, focustiled, {.i = +2} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_k, 0, 0}, focustiled, {.i = -2} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_l, 0, 0}, focustiled, {.i = +1} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setmaster, {.v = h_master} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_j, 0, 0}, setmaster, {.v = j_master} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_k, 0, 0}, setmaster, {.v = k_master} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_l, 0, 0}, setmaster, {.v = l_master} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[0]} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_s, 0, 0}, split, {.ui = 2} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = +1} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = -1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, split, {.ui = 1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = +1} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = -1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = +1} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = -1} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = -10.05} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = +10.05} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_minus, 0, 0}, resizemaster, {.f = -20.05} }, ++ { {ControlMask, 0, 0, 0}, {XK_w, XK_plus, 0, 0}, resizemaster, {.f = +20.05} }, ++ { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, ++ { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, ++ { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, ++}; ++ + /* button definitions */ + /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ + static Button buttons[] = { +@@ -114,3 +167,5 @@ static Button buttons[] = { + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + }; + ++/* include(s) depending on the configuration variables */ ++#include "keymodes.post.h" +diff -up ../dwm-5.8.2-1/dwm.c ./dwm.c +--- ../dwm-5.8.2-1/dwm.c 2010-06-11 01:10:05.473958000 +0200 ++++ ./dwm.c 2010-06-11 01:13:49.226865000 +0200 +@@ -954,7 +954,7 @@ grabbuttons(Client *c, Bool focused) { + } + + void +-grabkeys(void) { ++grabdefkeys(void) { + updatenumlockmask(); + { + unsigned int i, j; +@@ -1036,7 +1036,7 @@ isuniquegeom(XineramaScreenInfo *unique, + #endif /* XINERAMA */ + + void +-keypress(XEvent *e) { ++defkeypress(XEvent *e) { + unsigned int i; + KeySym keysym; + XKeyEvent *ev; +diff -up ../dwm-5.8.2-1/keymodes.post.h ./keymodes.post.h +--- ../dwm-5.8.2-1/keymodes.post.h 2010-06-11 01:12:53.000000000 +0200 ++++ ./keymodes.post.h 2010-06-11 01:13:49.287434000 +0200 +@@ -0,0 +1,409 @@ ++/* See LICENSE file for copyright and license details. */ ++/* © 2010 joten <joten@freenet.de> */ ++ ++/* function implementations */ ++void ++adjacenttag(const Arg *arg) { ++ int nexttag = selmon->curtag + arg->i; ++ Arg a; ++ ++ if(nexttag > LENGTH(tags)) ++ nexttag = 1; ++ else if(nexttag < 1) ++ nexttag = LENGTH(tags); ++ a.ui = 1 << (nexttag - 1); ++ tag(&a); ++} ++ ++void ++adjacentview(const Arg *arg) { ++ int nexttag = selmon->curtag + arg->i; ++ Arg a; ++ ++ if(nexttag > LENGTH(tags)) ++ nexttag = 1; ++ else if(nexttag < 1) ++ nexttag = LENGTH(tags); ++ a.ui = 1 << (nexttag - 1); ++ view(&a); ++} ++ ++void ++clearcmd(const Arg *arg) { ++ unsigned int i; ++ ++ for(i = 0; i < LENGTH(cmdkeysym); i++) { ++ cmdkeysym[i] = 0; ++ cmdmod[i] = 0; ++ } ++} ++ ++void ++closewindow(const Arg *arg) { ++ unsigned int j, n; ++ Client *i; ++ ++ if(!selmon->sel || selmon->sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) ++ return; ++ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) ++ if(i == selmon->sel) ++ j = n + 1; ++ if(j == 0 || n < 2) ++ return; ++ if(j <= selmon->msplit) { ++ if(selmon->ltaxis[1] == 3 || selmon->msplit == 1) { ++ selmon->msplits[selmon->curtag] = selmon->msplit = n; ++ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = selmon->ltaxis[2]; ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; ++ } else if(j == selmon->msplit && (selmon->ltaxis[2] == 3 || selmon->msplit == n - 1)) { ++ selmon->msplits[selmon->curtag] = selmon->msplit -= 1; ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; ++ } else ++ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; ++ } else { ++ if(selmon->ltaxis[2] == 3 || selmon->msplit == n - 1) ++ selmon->msplits[selmon->curtag] = selmon->msplit = n; ++ else if(j == selmon->msplit + 1 && (selmon->ltaxis[1] == 3 || selmon->msplit == 1)) { ++ selmon->msplits[selmon->curtag] = selmon->msplit += 1; ++ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; ++ } else ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; ++ } ++ arrange(selmon); ++} ++ ++void ++exchangewindow(const Arg *arg) { ++ int j = 0, n; ++ Client *c, *i, *sel = selmon->sel; ++ ++ if(!sel || sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) ++ return; ++ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) ++ if(i == selmon->sel) ++ j = n + 1; ++ if(j == 0 || n < 2 ++ || (j <= selmon->msplit && selmon->ltaxis[1] == 3 && selmon->msplit > 1 && !(j == 1 && arg->i < 0) && !(j == selmon->msplit && arg->i > 0)) ++ || (j > selmon->msplit && selmon->ltaxis[2] == 3 && n - selmon->msplit > 1 && !(j == selmon->msplit + 1 && arg->i < 0) && !(j == n && arg->i > 0))) ++ return; ++ if(arg->i < 0) { ++ 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; ++ } ++ } else { ++ 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); ++} ++ ++void ++focustiled(const Arg *arg) { ++ float f; ++ unsigned int j = 0, k, n; ++ Client *c = NULL, *i; ++ ++ if(!selmon->sel || selmon->sel->isfloating || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) ++ return; ++ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) ++ if(i == selmon->sel) ++ j = n + 1; ++ if(n < 2) ++ return; ++ if(arg->i < 0 ++ && ((j > 1 && j <= selmon->msplit && selmon->ltaxis[1] == -(arg->i)) || (j > (selmon->msplit + 1) && j <= n && selmon->ltaxis[2] == -(arg->i)))) { ++ c = prevtiled(selmon->sel); ++ } else if(arg->i > 0 ++ && ((j > 0 && j < selmon->msplit && selmon->ltaxis[1] == arg->i) || (j > selmon->msplit && j < n && selmon->ltaxis[2] == arg->i))) { ++ c = nexttiled(selmon->sel->next); ++ } else if(arg->i < 0 ++ && n > selmon->msplit ++ && j > selmon->msplit && j <= n ++ && (selmon->ltaxis[2] - arg->i) == 3) ++ f = (float)(j - selmon->msplit) / (n - selmon->msplit) * selmon->msplit; ++ else if(arg->i > 0 ++ && n > selmon->msplit ++ && j > 0 && j <= selmon->msplit ++ && (selmon->ltaxis[1] + arg->i) == 3) ++ f = selmon->msplit + (float)j / selmon->msplit * (n - selmon->msplit); ++ if(f > 0) { ++ k = (unsigned int)f; ++ if(f - k > 0) ++ k++; ++ for(j = 1, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), j++) ++ if(j == k) ++ c = i; ++ } ++ if(c) { ++ focus(c); ++ restack(selmon); ++ } ++} ++ ++void ++focuswindow(const Arg *arg) { ++ unsigned int j = 0, k = 0, n; ++ Client *c = NULL, *i; ++ ++ if(!selmon->sel || selmon->sel->isfloating || selmon->lt[selmon->sellt]->arrange != tile) ++ return; ++ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) ++ if(i == selmon->sel) ++ j = n + 1; ++ if(j == 0 || n < 2 || (selmon->msplit == n && selmon->ltaxis[1] == 3)) ++ return; ++ if(arg->i < 0) { ++ if((j > 1 && j <= selmon->msplit && selmon->ltaxis[1] == 3) || j == 1) { ++ k = n; ++ } else if(j > selmon->msplit + 1 && j <= n && selmon->ltaxis[2] == 3) { ++ k = selmon->msplit; ++ } else ++ c = prevtiled(selmon->sel); ++ } else { ++ if(j < selmon->msplit && selmon->ltaxis[1] == 3) { ++ k = selmon->msplit + 1; ++ } else if((j > selmon->msplit && j < n && selmon->ltaxis[2] == 3) || j == n) { ++ k = 1; ++ } else ++ c = nexttiled(selmon->sel->next); ++ } ++ if(!c && k) ++ for(j = 1, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), j++) ++ if(j == k) ++ c = i; ++ if(c) { ++ focus(c); ++ restack(selmon); ++ } ++} ++ ++void ++grabkeys(void) { ++ if(keymode == INSERTMODE) { ++ grabdefkeys(); ++ } else if(keymode == COMMANDMODE) { ++ XUngrabKey(dpy, AnyKey, AnyModifier, root); ++ XGrabKey(dpy, AnyKey, AnyModifier, root, ++ True, GrabModeAsync, GrabModeAsync); ++ } ++} ++ ++void ++keypress(XEvent *e) { ++ unsigned int i, j; ++ Arg a = {0}; ++ Bool ismatch = False, maybematch = False; ++ KeySym keysym; ++ XKeyEvent *ev; ++ ++ if(keymode == INSERTMODE) ++ defkeypress(e); ++ else if(keymode == COMMANDMODE) { ++ ev = &e->xkey; ++ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); ++ if(keysym < XK_Shift_L || keysym > XK_Hyper_R) { ++ for(i = 0; i < LENGTH(cmdkeys); i++) ++ if(keysym == cmdkeys[i].keysym ++ && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) ++ && cmdkeys[i].func) { ++ cmdkeys[i].func(&(cmdkeys[i].arg)); ++ ismatch = True; ++ break; ++ } ++ if(!ismatch) { ++ for(j = 0; j < LENGTH(cmdkeysym); j++) ++ if(cmdkeysym[j] == 0) { ++ cmdkeysym[j] = keysym; ++ cmdmod[j] = ev->state; ++ break; ++ } ++ for(i = 0; i < LENGTH(commands); i++) { ++ for(j = 0; j < LENGTH(cmdkeysym); j++) { ++ if(cmdkeysym[j] == commands[i].keysym[j] ++ && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) ++ ismatch = True; ++ else if(cmdkeysym[j] == 0 ++ && cmdmod[j] == 0) { ++ ismatch = False; ++ maybematch = True; ++ break; ++ } else { ++ ismatch = False; ++ break; ++ } ++ } ++ if(ismatch) { ++ if(commands[i].func) ++ commands[i].func(&(commands[i].arg)); ++ clearcmd(&a); ++ break; ++ } ++ ++ } ++ if(!maybematch) ++ clearcmd(&a); ++ } ++ } ++ } ++} ++ ++void ++onlyclient(const Arg *arg) { ++ Client *c; ++ XEvent ev; ++ ++ if(!selmon->sel) ++ return; ++ for(c = selmon->clients; c; c = c->next) ++ if(c != selmon->sel && ISVISIBLE(c)) { ++ if(isprotodel(c)) { ++ ev.type = ClientMessage; ++ ev.xclient.window = c->win; ++ ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.format = 32; ++ ev.xclient.data.l[0] = wmatom[WMDelete]; ++ ev.xclient.data.l[1] = CurrentTime; ++ XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ } ++ else { ++ XGrabServer(dpy); ++ XSetErrorHandler(xerrordummy); ++ XSetCloseDownMode(dpy, DestroyAll); ++ XKillClient(dpy, c->win); ++ XSync(dpy, False); ++ XSetErrorHandler(xerror); ++ XUngrabServer(dpy); ++ } ++ } ++} ++ ++Client * ++prevtiled(Client *c) { ++ Client *i, *p; ++ ++ for(i = selmon->clients, p = NULL; i && i != c; i = i->next) ++ if(!i->isfloating && ISVISIBLE(i)) ++ p = i; ++ return p; ++} ++ ++void ++resizemaster(const Arg *arg) { ++ float f; ++ Arg a; ++ ++ if(!arg || selmon->lt[selmon->sellt]->arrange != tile) ++ return; ++ f = (arg->f < 0 ? -arg->f : arg->f) - selmon->ltaxis[0] * 10; ++ if(f < 0 || f > 1.9) ++ return; ++ a.f = arg->f / abs(arg->f) * f; ++ setmfact(&a); ++} ++ ++void ++setkeymode(const Arg *arg) { ++ Arg a = {0}; ++ ++ if(!arg) ++ return; ++ keymode = arg->ui; ++ clearcmd(&a); ++ grabkeys(); ++} ++ ++void ++setmaster(const Arg *arg) { ++ unsigned int i; ++ Arg a; ++ ++ if(!arg || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) ++ return; ++ for(i = 0; i < 3; i++) ++ selmon->ltaxes[selmon->curtag][i] = selmon->ltaxis[i] = ((int *)arg->i)[i]; ++ selmon->msplits[selmon->curtag] = selmon->msplit = 1; ++ if(selmon->sel && !selmon->sel->isfloating && selmon->sel != nexttiled(selmon->clients)) { ++ detach(selmon->sel); ++ attach(selmon->sel); ++ focus(selmon->sel); ++ } ++ if(selmon->lt[selmon->sellt]->arrange == monocle) { ++ for(i = 0; i < LENGTH(layouts) && (&layouts[i])->arrange != tile; i++); ++ a.v = &layouts[i]; ++ setlayout(&a); ++ if(!selmon->sel) ++ arrange(selmon); ++ } else ++ arrange(selmon); ++} ++ ++void ++split(const Arg *arg) { ++ unsigned int j = 0, k, n; ++ Arg a; ++ Client *i; ++ ++ if(!arg || !selmon->sel || selmon->sel->isfloating || (selmon->lt[selmon->sellt]->arrange != monocle && selmon->lt[selmon->sellt]->arrange != tile)) ++ return; ++ for(n = 0, i = nexttiled(selmon->clients); i; i = nexttiled(i->next), n++) ++ if(i == selmon->sel) ++ j = n + 1; ++ if(j == 0 || n < 2) ++ return; ++ if(selmon->lt[selmon->sellt]->arrange == monocle) { ++ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0] = arg->i; ++ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = 3; ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; ++ for(k = 0; k < LENGTH(layouts) && (&layouts[k])->arrange != tile; k++); ++ a.v = &layouts[k]; ++ setlayout(&a); ++ } else if(j <= selmon->msplit) { ++ if(selmon->ltaxis[1] == 3 || selmon->msplit == 1) { ++ selmon->ltaxes[selmon->curtag][1] = selmon->ltaxis[1] = arg->i; ++ if(selmon->ltaxis[2] == 3 || selmon->msplit == 1) ++ selmon->msplits[selmon->curtag] = selmon->msplit = 2; ++ arrange(selmon); ++ } else if(selmon->ltaxis[1] == arg->i && selmon->msplit < n) { ++ selmon->msplits[selmon->curtag] = selmon->msplit += 1; ++ arrange(selmon); ++ } else if(selmon->ltaxis[1] + arg->i == 3 && selmon->msplit == n) { ++ selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0] = arg->i; ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = 3; ++ selmon->msplits[selmon->curtag] = selmon->msplit = n - 1; ++ arrange(selmon); ++ } ++ } else if(n > 2) { ++ if(selmon->ltaxis[2] == 3 || selmon->msplit == n - 1) { ++ selmon->ltaxes[selmon->curtag][2] = selmon->ltaxis[2] = arg->i; ++ if(selmon->ltaxis[1] == 3 || selmon->msplit == n - 1) ++ selmon->msplits[selmon->curtag] = selmon->msplit = n - 2; ++ arrange(selmon); ++ } else if(selmon->ltaxis[2] == arg->i && selmon->msplit > 1) { ++ selmon->msplits[selmon->curtag] = selmon->msplit -= 1; ++ arrange(selmon); ++ } ++ } ++} +diff -up ../dwm-5.8.2-1/keymodes.pre.h ./keymodes.pre.h +--- ../dwm-5.8.2-1/keymodes.pre.h 2010-06-11 01:12:49.000000000 +0200 ++++ ./keymodes.pre.h 2010-06-11 01:13:50.660576000 +0200 +@@ -0,0 +1,34 @@ ++/* See LICENSE file for copyright and license details. */ ++/* © 2010 joten <joten@freenet.de> */ ++ ++#define COMMANDMODE 1 ++#define INSERTMODE 2 ++ ++typedef struct { ++ unsigned int mod[4]; ++ KeySym keysym[4]; ++ void (*func)(const Arg *); ++ const Arg arg; ++} Command; ++ ++/* function declarations */ ++static void adjacenttag(const Arg *arg); ++static void adjacentview(const Arg *arg); ++static void clearcmd(const Arg *arg); ++static void closewindow(const Arg *arg); ++static void defkeypress(XEvent *e); ++static void exchangewindow(const Arg *arg); ++static void focustiled(const Arg *arg); ++static void focuswindow(const Arg *arg); ++static void grabdefkeys(void); ++static void onlyclient(const Arg *arg); ++static Client *prevtiled(Client *c); ++static void resizemaster(const Arg *arg); ++static void setkeymode(const Arg *arg); ++static void setmaster(const Arg *arg); ++static void split(const Arg *arg); ++ ++/* variables */ ++static unsigned int cmdmod[4]; ++static unsigned int keymode = COMMANDMODE; ++static KeySym cmdkeysym[4]; diff --git a/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-config.h b/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-config.h @@ -0,0 +1,163 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; +static const char normbordercolor[] = "#1f1f1f"; +static const char normbgcolor[] = "#1f1f1f"; +static const char normfgcolor[] = "#c0c0c0"; +static const char selbordercolor[] = "#ff8000"; +static const char selbgcolor[] = "#1f1f1f"; +static const char selfgcolor[] = "#ff8000"; +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 */ + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5" }; + +/* include(s) depending on the tags array */ +#include "flextile.h" + +/* include(s) defining functions */ +#include "keymodes.pre.h" + +static const Rule rules[] = { + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, True, -1 }, + { "Firefox", NULL, NULL, 1 << 4, False, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.6; /* factor of master area size [0.05..0.95] */ +static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ +static const int layoutaxis[] = { + 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ + 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ + 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ +}; + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[M]", monocle }, /* first entry is default */ + { "[]=", tile }, + { "><>", NULL }, /* no layout function means floating behavior */ +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; +static const char *haltcmd[] = { "sudo", "halt", NULL }; +static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; +static const char *sleepcmd[] = { "sudo", "pm-suspend", NULL }; +static const char *termcmd[] = { "uxterm", NULL }; +static const char *audio1cmd[] = { "amixer", "--quiet", "sset", "Master", "1+", NULL }; +static const char *audio2cmd[] = { "amixer", "--quiet", "sset", "Master", "1-", NULL }; +static const char *audio3cmd[] = { "amixer", "--quiet", "sset", "Master", "toggle", NULL }; + +#include <X11/XF86keysym.h> +static Key keys[] = { + /* modifier key function argument */ + { 0, XK_Super_L, setkeymode, {.ui = COMMANDMODE} }, + { 0, XF86XK_AudioRaiseVolume, spawn, {.v = audio1cmd} }, + { 0, XF86XK_AudioLowerVolume, spawn, {.v = audio2cmd} }, + { MODKEY|ShiftMask, XK_m, spawn, {.v = audio3cmd} }, + { MODKEY, XK_Down, focusstack, {.i = +1 } }, + { MODKEY, XK_Up, focusstack, {.i = -1 } }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) +}; + +static const int h_master[] = {+1, 2, 2}; +static const int j_master[] = {-2, 1, 1}; +static const int k_master[] = {+2, 1, 1}; +static const int l_master[] = {-1, 2, 2}; + +static Key cmdkeys[] = { + /* modifier keys function argument */ + { 0, XK_Escape, clearcmd, {0} }, + { ControlMask, XK_c, clearcmd, {0} }, + { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, + { 0, XF86XK_Standby, spawn, {.v = sleepcmd} }, +}; +static Command commands[] = { + /* modifier (4 keys) keysyms (4 keys) function argument */ + { {0, 0, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = +1} }, + { {0, ShiftMask, 0, 0}, {XK_g, XK_t, 0, 0}, adjacentview, {.i = -1} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_c, 0, 0}, closewindow, {0} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_h, 0, 0}, focustiled, {.i = -1} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_j, 0, 0}, focustiled, {.i = +2} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_k, 0, 0}, focustiled, {.i = -2} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_l, 0, 0}, focustiled, {.i = +1} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setmaster, {.v = h_master} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_j, 0, 0}, setmaster, {.v = j_master} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_k, 0, 0}, setmaster, {.v = k_master} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_l, 0, 0}, setmaster, {.v = l_master} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[0]} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_s, 0, 0}, split, {.ui = 2} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = +1} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_t, 0, 0}, adjacenttag, {.i = -1} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, split, {.ui = 1} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = +1} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_x, 0, 0}, exchangewindow, {.i = -1} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = +1} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_w, 0, 0}, focuswindow, {.i = -1} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = -10.05} }, + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, resizemaster, {.f = +10.05} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_minus, 0, 0}, resizemaster, {.f = -20.05} }, + { {ControlMask, 0, 0, 0}, {XK_w, XK_plus, 0, 0}, resizemaster, {.f = +20.05} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, + { {ShiftMask, ShiftMask, 0, 0}, {XK_period, XK_1, 0, 0}, spawn, {.v = termcmd} }, + { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_1, XK_t, 0}, tag, {.ui = 1 << 0} }, + { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_2, XK_t, 0}, tag, {.ui = 1 << 1} }, + { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_3, XK_t, 0}, tag, {.ui = 1 << 2} }, + { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_4, XK_t, 0}, tag, {.ui = 1 << 3} }, + { {ControlMask, 0, ShiftMask, 0}, {XK_w, XK_5, XK_t, 0}, tag, {.ui = 1 << 4} }, + { {0, 0, 0, 0}, {XK_1, XK_g, XK_t, 0}, view, {.ui = 1 << 0} }, + { {0, 0, 0, 0}, {XK_2, XK_g, XK_t, 0}, view, {.ui = 1 << 1} }, + { {0, 0, 0, 0}, {XK_3, XK_g, XK_t, 0}, view, {.ui = 1 << 2} }, + { {0, 0, 0, 0}, {XK_4, XK_g, XK_t, 0}, view, {.ui = 1 << 3} }, + { {0, 0, 0, 0}, {XK_5, XK_g, XK_t, 0}, view, {.ui = 1 << 4} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, + { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, + { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_q, XK_1, XK_Return}, spawn, {.v = haltcmd} }, + { {ShiftMask, 0, 0, 0}, {XK_period, XK_g, XK_o, XK_Return}, togglebar, {0} }, +}; + +/* button definitions */ +/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ +}; + +/* include(s) depending on the configuration variables */ +#include "keymodes.post.h" diff --git a/dwm.suckless.org/patches/keymodes/index.md b/dwm.suckless.org/patches/keymodes/index.md @@ -0,0 +1,50 @@ +# keymodes # + +## Description ## + +This patch provides key modes (like in Vim). There are two key modes: + + 1. `COMMANDMODE`: In this mode any key is grabbed and only the registered command keys have any effect. + 2. `INSERTMODE`: This is the normal key mode, in which the original key bindings of dwm and applications are effective and text can be entered. + +With key modes you can use any key binding for window management without risking conflicts with existing key bindings in applications or have a Vim-style dwm. + +There are two different patches: + + * keymodes: the minimal patch + * vim-keymodes: This patch tries to emulate the key bindings of Vim. Therefor it includes additional functions, which depend on the [flextile patch](flextile). + + +## Configuration ## + + (1) Download the favoured patch and apply it according to the [general instructions](.). If you choose vim-keymodes you will have to apply the [flextile patch](./flextile) first. + + (2) Transfer the changes made by the patch in `config.def.h` to your `config.h`, if needed; please see the patch file for details. + + (3) Verify the following lines in the aforementioned arrays; the key bindings are set in reference to a german keyboard layout. The entries in the `cmdkeys` array are defined like those in the original `keys` array of dwm and take precedence over the key bindings defined in the `commands` array. The modifier and keysym definitions in the `commands` array are themselves arrays with four entries, whereas the first entry in the modifier array corresponds to the first entry in the keysym array and so forth. You can find an example configuration [here][dwm-keymodes-vim-config.h]. + + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, + + static Key cmdkeys[] = { + /* modifier keys function argument */ + { 0, XK_Escape, clearcmd, {0} }, + { ControlMask, XK_c, clearcmd, {0} }, + { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, + }; + static Command commands[] = { + /* modifier (4 keys) keysyms (4 keys) function argument */ + ... + }; + + +## Usage ## + +With this patch dwm starts in `COMMANDMODE` and you can use the key bindings as defined in the `commands` array in `config.h`. Press `Escape` or `CTRL+c` to abort a command input and press `i` (in the default configuration) to enter `INSERTMODE` and use dwm normally with the key bindings defined in the `keys` array, navigate in applications and insert text. To get from `INSERTMODE` to `COMMANDMODE` press `ALT+Escape` (in the default configuration). + + +## Download ## + + * [dwm-keymodes-5.8.2.diff][dwm-keymodes-5.8.2] (20100611, joten (at) freenet (dot) de) + * [dwm-keymodes-vim-5.8.2.diff][dwm-keymodes-vim-5.8.2 (20100611, joten (at) freenet (dot) de) diff --git a/dwm.suckless.org/patches/keypressrelease.md b/dwm.suckless.org/patches/keypressrelease.md @@ -1,37 +0,0 @@ -keypressrelease -=== - -Description ---- - -This patch lets you specify whether a key binding should be executed at the _KeyPress_ or _KeyRelease_ event. -Executing on _KeyRelease_ fixes bugs such as `scrot -s` failing to execute from a key binding due to keys not being released in time[1][2]. - -Note that the new parameter must be added to all non-standard key bindings manually after patching. - -Usage ---- -A working `scrot -s` key binding: - - static const char *scrot[] = { "scrot", "-s", NULL }; - ... - { KeyRelease, 0, XK_Print, spawn, {.v = scrot } }, - -Or to only display the bar while the toggle key is held down (requires that it is hidden to start with), add: - - { KeyRelease, MODKEY, XK_b, togglebar, {0} }, - -Download ---- - - * [dwm-keypressrelease-6.0.diff](dwm-keypressrelease-6.0.diff) - * [dwm-keypressrelease-6.0.diff on GitHub](https://github.com/Ceryn/patches/blob/master/dwm/dwm-6.0-keypressrelease.diff) - -Author ------- - * Niklas Høj - `<niklas at hoej dot me>` - ---- - -[1] Error produced: "giblib error: couldn't grab keyboard: Resource temporarily unavailable" -[2] Old discussion thread: [//lists.suckless.org/dev/1108/9185.html](//lists.suckless.org/dev/1108/9185.html) diff --git a/dwm.suckless.org/patches/dwm-keypressrelease-6.0.diff b/dwm.suckless.org/patches/keypressrelease/dwm-keypressrelease-6.0.diff diff --git a/dwm.suckless.org/patches/keypressrelease/index.md b/dwm.suckless.org/patches/keypressrelease/index.md @@ -0,0 +1,36 @@ +keypressrelease +=== + +Description +--- + +This patch lets you specify whether a key binding should be executed at the _KeyPress_ or _KeyRelease_ event. +Executing on _KeyRelease_ fixes bugs such as `scrot -s` failing to execute from a key binding due to keys not being released in time[1][2]. + +Note that the new parameter must be added to all non-standard key bindings manually after patching. + +Usage +--- +A working `scrot -s` key binding: + + static const char *scrot[] = { "scrot", "-s", NULL }; + ... + { KeyRelease, 0, XK_Print, spawn, {.v = scrot } }, + +Or to only display the bar while the toggle key is held down (requires that it is hidden to start with), add: + + { KeyRelease, MODKEY, XK_b, togglebar, {0} }, + +Download +--- + + * [dwm-keypressrelease-6.0.diff](dwm-keypressrelease-6.0.diff) + +Author +------ + * Niklas Høj - `<niklas at hoej dot me>` + +--- + +[1] Error produced: "giblib error: couldn't grab keyboard: Resource temporarily unavailable" +[2] Old discussion thread: [//lists.suckless.org/dev/1108/9185.html](//lists.suckless.org/dev/1108/9185.html) diff --git a/dwm.suckless.org/patches/killunsel.md b/dwm.suckless.org/patches/killunsel.md @@ -1,23 +0,0 @@ -killunsel -========= - -Description ------------ - -Kills all visible clients that are unselected. That is, after running -`killunsel`, only the selected client will remain. The rest will not only be -not visible, but they will have been killed. - -This is essentially equivalent in idea to :tabonly (albeit per-client, not -per-"tab") in vim. - -Download --------- - -* [dwm-killunsel-ceac8c91ff.diff](dwm-killunsel-ceac8c91ff.diff) (1.7k) - (20170728) - -Author ------- - -* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> diff --git a/dwm.suckless.org/patches/dwm-killunsel-ceac8c91ff.diff b/dwm.suckless.org/patches/killunsel/dwm-killunsel-ceac8c91ff.diff diff --git a/dwm.suckless.org/patches/killunsel/index.md b/dwm.suckless.org/patches/killunsel/index.md @@ -0,0 +1,23 @@ +killunsel +========= + +Description +----------- + +Kills all visible clients that are unselected. That is, after running +`killunsel`, only the selected client will remain. The rest will not only be +not visible, but they will have been killed. + +This is essentially equivalent in idea to :tabonly (albeit per-client, not +per-"tab") in vim. + +Download +-------- + +* [dwm-killunsel-ceac8c91ff.diff](dwm-killunsel-ceac8c91ff.diff) (1.7k) + (20170728) + +Author +------ + +* [Chris Down](https://chrisdown.name) (cdown) <chris@chrisdown.name> diff --git a/dwm.suckless.org/patches/mark.md b/dwm.suckless.org/patches/mark.md @@ -1,51 +0,0 @@ -# mark # - -## Description ## - -This patch provides an mechanism to easily jump between any 2 clients, or to -swap any 2 clients through shortcuts by introcuding mark. The mark is global, -and only one mark is allowed at the same time. The marked client is -distinguished from other clients by having a different border color. - -This patch adds 3 functions to dwm: - - * togglemark - mark/unmark current focused client. - * swapclient - swap focused client with marked client - * swapfocus - swap focus with mark. - -## Configuration ## - - static const char normmarkcolor[] = "#775500"; /*border color for marked client*/ - static const char selmarkcolor[] = "#775577"; /*border color for marked client on focus*/ - - /*basic key mappings*/ - { MODKEY, XK_semicolon,togglemark, {0} }, - { MODKEY, XK_o, swapfocus, {0} }, - { MODKEY, XK_u, swapclient, {0} }, - -Some ideas for combinations of key mappings: - - * togglemark x2 -clear the mark - * swapclient, swapfocus -shift the client to another client frame without losing focus - * swapclient, togglemark x2 -swap 2 clients and clear the mark - * swapfocus, togglemark x2 -jump to mark and clear the mark - -## Download ## -this patch has been revised, it's recommended to use dwm-6.1-mark-new.diff -old behaviours of the patch(dwm-mark-6.1.diff): - - 1. crashes when using mark features while the marked client has been killed. - 2. swapclient clears the mark. - 3. swapclient falls back to zoom() if the mark is not set. - 4. swapfocus does not activate tags for the marked client - 5. swapfocus does not focus monitors correctly - -* [dwm-mark-new-6.1.diff](dwm-mark-new-6.1.diff) -* [dwm-mark-6.1.diff](dwm-mark-6.1.diff) - -## Author ## -* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/dwm-mark-6.1.diff b/dwm.suckless.org/patches/mark/dwm-mark-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-mark-new-6.1.diff b/dwm.suckless.org/patches/mark/dwm-mark-new-6.1.diff diff --git a/dwm.suckless.org/patches/mark/index.md b/dwm.suckless.org/patches/mark/index.md @@ -0,0 +1,51 @@ +# mark # + +## Description ## + +This patch provides an mechanism to easily jump between any 2 clients, or to +swap any 2 clients through shortcuts by introcuding mark. The mark is global, +and only one mark is allowed at the same time. The marked client is +distinguished from other clients by having a different border color. + +This patch adds 3 functions to dwm: + + * togglemark - mark/unmark current focused client. + * swapclient - swap focused client with marked client + * swapfocus - swap focus with mark. + +## Configuration ## + + static const char normmarkcolor[] = "#775500"; /*border color for marked client*/ + static const char selmarkcolor[] = "#775577"; /*border color for marked client on focus*/ + + /*basic key mappings*/ + { MODKEY, XK_semicolon,togglemark, {0} }, + { MODKEY, XK_o, swapfocus, {0} }, + { MODKEY, XK_u, swapclient, {0} }, + +Some ideas for combinations of key mappings: + + * togglemark x2 +clear the mark + * swapclient, swapfocus +shift the client to another client frame without losing focus + * swapclient, togglemark x2 +swap 2 clients and clear the mark + * swapfocus, togglemark x2 +jump to mark and clear the mark + +## Download ## +this patch has been revised, it's recommended to use dwm-6.1-mark-new.diff +old behaviours of the patch(dwm-mark-6.1.diff): + + 1. crashes when using mark features while the marked client has been killed. + 2. swapclient clears the mark. + 3. swapclient falls back to zoom() if the mark is not set. + 4. swapfocus does not activate tags for the marked client + 5. swapfocus does not focus monitors correctly + +* [dwm-mark-new-6.1.diff](dwm-mark-new-6.1.diff) +* [dwm-mark-6.1.diff](dwm-mark-6.1.diff) + +## Author ## +* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/maximize.md b/dwm.suckless.org/patches/maximize.md @@ -1,27 +0,0 @@ -maximize -======== - -Description ------------ -These patch provide helper functions for maximizing, horizontally and -vertically, floating windows using keybindings. - -Usage ------ -Insert the bindings into the keys list. Here is an example: - - { MODKEY|ControlMask|ShiftMask, XK_h, togglehorizontalmax, NULL }, - { MODKEY|ControlMask|ShiftMask, XK_l, togglehorizontalmax, NULL }, - { MODKEY|ControlMask|ShiftMask, XK_j, toggleverticalmax, NULL }, - { MODKEY|ControlMask|ShiftMask, XK_k, toggleverticalmax, NULL }, - { MODKEY|ControlMask, XK_m, togglemaximize, {0} }, - -Download --------- -* [dwm-maximize_vert_horz-20160731-56a31dc.diff](dwm-maximize_vert_horz-20160731-56a31dc.diff) -* [dwm-maximize_vert_horz-6.1.diff](dwm-maximize_vert_horz-6.1.diff) (Unclean patch) -* [dwm-maximize_vert_horz-6.0.diff](dwm-maximize_vert_horz-6.0.diff) - -Author ------- - * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-maximize_vert_horz-20160731-56a31dc.diff b/dwm.suckless.org/patches/maximize/dwm-maximize_vert_horz-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-maximize_vert_horz-6.0.diff b/dwm.suckless.org/patches/maximize/dwm-maximize_vert_horz-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-maximize_vert_horz-6.1.diff b/dwm.suckless.org/patches/maximize/dwm-maximize_vert_horz-6.1.diff diff --git a/dwm.suckless.org/patches/maximize/index.md b/dwm.suckless.org/patches/maximize/index.md @@ -0,0 +1,27 @@ +maximize +======== + +Description +----------- +These patch provide helper functions for maximizing, horizontally and +vertically, floating windows using keybindings. + +Usage +----- +Insert the bindings into the keys list. Here is an example: + + { MODKEY|ControlMask|ShiftMask, XK_h, togglehorizontalmax, NULL }, + { MODKEY|ControlMask|ShiftMask, XK_l, togglehorizontalmax, NULL }, + { MODKEY|ControlMask|ShiftMask, XK_j, toggleverticalmax, NULL }, + { MODKEY|ControlMask|ShiftMask, XK_k, toggleverticalmax, NULL }, + { MODKEY|ControlMask, XK_m, togglemaximize, {0} }, + +Download +-------- +* [dwm-maximize_vert_horz-20160731-56a31dc.diff](dwm-maximize_vert_horz-20160731-56a31dc.diff) +* [dwm-maximize_vert_horz-6.1.diff](dwm-maximize_vert_horz-6.1.diff) (Unclean patch) +* [dwm-maximize_vert_horz-6.0.diff](dwm-maximize_vert_horz-6.0.diff) + +Author +------ + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/monocle_count.md b/dwm.suckless.org/patches/monocle_count.md @@ -1,16 +0,0 @@ -monocle count -============= - -Description ------------ -`monocle_count` prints the total number of clients and the number of the -currently activated client beside the symbol of the monocle layout, while the -current release prints only the number of total clients within the symbol. - -Download --------- -* [dwm-monocle_count-5.8.2.diff](dwm-monocle_count-5.8.2.diff) - -Author ------- -* v4hn - `v4hn.de` diff --git a/dwm.suckless.org/patches/dwm-monocle_count-5.8.2.diff b/dwm.suckless.org/patches/monocle_count/dwm-monocle_count-5.8.2.diff diff --git a/dwm.suckless.org/patches/monocle_count/index.md b/dwm.suckless.org/patches/monocle_count/index.md @@ -0,0 +1,16 @@ +monocle count +============= + +Description +----------- +`monocle_count` prints the total number of clients and the number of the +currently activated client beside the symbol of the monocle layout, while the +current release prints only the number of total clients within the symbol. + +Download +-------- +* [dwm-monocle_count-5.8.2.diff](dwm-monocle_count-5.8.2.diff) + +Author +------ +* v4hn - `v4hn.de` diff --git a/dwm.suckless.org/patches/moveontagmon.md b/dwm.suckless.org/patches/moveontagmon.md @@ -1,13 +0,0 @@ -# move on tagmon() # - -## Description ## - -This patch moves floating windows if their monitor gets changed. - -## Download ## - * [dwm-r1437-moveontagmon.diff][1] - -## Author ## - * Apo - a-p@0au.de - -[1]: //dwm.suckless.org/patches/dwm-r1437-moveontagmon.diff diff --git a/dwm.suckless.org/patches/dwm-r1437-moveontagmon.diff b/dwm.suckless.org/patches/moveontagmon/dwm-r1437-moveontagmon.diff diff --git a/dwm.suckless.org/patches/moveontagmon/index.md b/dwm.suckless.org/patches/moveontagmon/index.md @@ -0,0 +1,13 @@ +# move on tagmon() # + +## Description ## + +This patch moves floating windows if their monitor gets changed. + +## Download ## + * [dwm-r1437-moveontagmon.diff][1] + +## Author ## + * Apo - a-p@0au.de + +[1]: //dwm.suckless.org/patches/dwm-r1437-moveontagmon.diff diff --git a/dwm.suckless.org/patches/moveresize.md b/dwm.suckless.org/patches/moveresize.md @@ -1,72 +0,0 @@ -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: - - static void - moveresize(const Arg *arg) - { - - XEvent ev; - Monitor *m = selmon; - - if(!(m->sel && arg && arg->v && m->sel->isfloating)) - return; - - resize(m->sel, m->sel->x + ((int *)arg->v)[0], - m->sel->y + ((int *)arg->v)[1], - m->sel->w + ((int *)arg->v)[2], - m->sel->h + ((int *)arg->v)[3], - True); - - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - } - - 2. Insert the bindings into the keys list. Here is an example which uses the - arrow keys to move (mod+arrow) or resize (mod+shift+arrow) the selected - client: - - { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h"}}, - { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h"}}, - { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h"}}, - { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h"}}, - { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h"}}, - { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h"}}, - { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h"}}, - { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h"}}, - -If you want to automatically toggle the client floating when move/resize, -replace the `if()` statement above with this code: - - if(!(m->sel && arg && arg->v)) - return; - if(m->lt[m->sellt]->arrange && !m->sel->isfloating) - togglefloating(NULL); - -Multi-head ----------- -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://github.com/jceb/dwm-clean-patches). - - * [dwm-moveresize-20160731-56a31dc.diff](dwm-moveresize-20160731-56a31dc.diff) - * [dwm-moveresize-6.1.diff](dwm-moveresize-6.1.diff) (2095b) (20140209) - * [dwm-10e232f9ace7-moveresize.diff](dwm-10e232f9ace7-moveresize.diff) (2025b) (20120406) - * [dwm-moveresize-6.0.diff](dwm-moveresize-6.0.diff) (2025b) (20120406) - -Authors -------- - * Claudio M. Alessi - <smoppy@gmail.com> - * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff b/dwm.suckless.org/patches/moveresize/dwm-10e232f9ace7-moveresize.diff diff --git a/dwm.suckless.org/patches/dwm-moveresize-20160731-56a31dc.diff b/dwm.suckless.org/patches/moveresize/dwm-moveresize-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-moveresize-6.0.diff b/dwm.suckless.org/patches/moveresize/dwm-moveresize-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-moveresize-6.1.diff b/dwm.suckless.org/patches/moveresize/dwm-moveresize-6.1.diff diff --git a/dwm.suckless.org/patches/moveresize/index.md b/dwm.suckless.org/patches/moveresize/index.md @@ -0,0 +1,72 @@ +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: + + static void + moveresize(const Arg *arg) + { + + XEvent ev; + Monitor *m = selmon; + + if(!(m->sel && arg && arg->v && m->sel->isfloating)) + return; + + resize(m->sel, m->sel->x + ((int *)arg->v)[0], + m->sel->y + ((int *)arg->v)[1], + m->sel->w + ((int *)arg->v)[2], + m->sel->h + ((int *)arg->v)[3], + True); + + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + } + + 2. Insert the bindings into the keys list. Here is an example which uses the + arrow keys to move (mod+arrow) or resize (mod+shift+arrow) the selected + client: + + { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h"}}, + { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h"}}, + { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h"}}, + { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h"}}, + { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h"}}, + { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h"}}, + { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h"}}, + { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h"}}, + +If you want to automatically toggle the client floating when move/resize, +replace the `if()` statement above with this code: + + if(!(m->sel && arg && arg->v)) + return; + if(m->lt[m->sellt]->arrange && !m->sel->isfloating) + togglefloating(NULL); + +Multi-head +---------- +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://github.com/jceb/dwm-clean-patches). + + * [dwm-moveresize-20160731-56a31dc.diff](dwm-moveresize-20160731-56a31dc.diff) + * [dwm-moveresize-6.1.diff](dwm-moveresize-6.1.diff) (2095b) (20140209) + * [dwm-10e232f9ace7-moveresize.diff](dwm-10e232f9ace7-moveresize.diff) (2025b) (20120406) + * [dwm-moveresize-6.0.diff](dwm-moveresize-6.0.diff) (2025b) (20120406) + +Authors +------- + * Claudio M. Alessi - <smoppy@gmail.com> + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/movestack.md b/dwm.suckless.org/patches/movestack.md @@ -1,39 +0,0 @@ -# movestack - -## Description - -This plugin allows you to move clients around in the stack and swap them with -the master. It emulates the behavior off mod+shift+j and mod+shift+k in Xmonad. -movestack(+1) will swap the client with the current focus with the next client. -movestack(-1) will swap the client with the current focus with the previous client. - -## Usage - - 1. Download the patch and apply according to the [general instructions](.). - 2. Include the `movestack.c` source file and add keys that call movestack. - Example from `config.default.h`: - - #include "movestack.c" - static Key keys[] = { - /* modifier key function argument */ - ... - { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, - ... - -## Download - - * [dwm-movestack-6.1.diff](dwm-movestack-6.1.diff) - * [dwm-movestack-5.8.2.diff](historical/dwm-movestack-5.8.2.diff) - -## Author - - * Niki Yoshiuchi - `<`aplusbi@gmail.com`>` - -## Contributors - - * Moritz Wilhelmy (fix to work with dwm 5.8) - `<`moritz plus suckless at wzff dot de`>` - -## Note - -This patch seems to be equivalent to the [push](push) patch. diff --git a/dwm.suckless.org/patches/movestack/dwm-movestack-5.8.2.diff b/dwm.suckless.org/patches/movestack/dwm-movestack-5.8.2.diff @@ -0,0 +1,73 @@ +diff -r 050d521d66d8 config.def.h +--- a/config.def.h Tue Aug 24 13:13:20 2010 +0100 ++++ b/config.def.h Sun Sep 05 18:43:07 2010 +0200 +@@ -48,6 +48,7 @@ + static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; + static const char *termcmd[] = { "uxterm", NULL }; + ++#include "movestack.c" + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, +@@ -57,6 +58,8 @@ + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, ++ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, ++ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, +diff -r 050d521d66d8 movestack.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/movestack.c Sun Sep 05 18:43:07 2010 +0200 +@@ -0,0 +1,49 @@ ++void ++movestack(const Arg *arg) { ++ Client *c = NULL, *p = NULL, *pc = NULL, *i; ++ ++ if(arg->i > 0) { ++ /* find the client after selmon->sel */ ++ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); ++ if(!c) ++ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); ++ ++ } ++ else { ++ /* find the client before selmon->sel */ ++ for(i = selmon->clients; i != selmon->sel; i = i->next) ++ if(ISVISIBLE(i) && !i->isfloating) ++ c = i; ++ if(!c) ++ for(; i; i = i->next) ++ if(ISVISIBLE(i) && !i->isfloating) ++ c = i; ++ } ++ /* find the client before selmon->sel and c */ ++ for(i = selmon->clients; i && (!p || !pc); i = i->next) { ++ if(i->next == selmon->sel) ++ p = i; ++ if(i->next == c) ++ pc = i; ++ } ++ ++ /* swap c and selmon->sel selmon->clients in the selmon->clients list */ ++ if(c && c != selmon->sel) { ++ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; ++ selmon->sel->next = c->next==selmon->sel?c:c->next; ++ c->next = temp; ++ ++ if(p && p != c) ++ p->next = c; ++ if(pc && pc != selmon->sel) ++ pc->next = selmon->sel; ++ ++ if(selmon->sel == selmon->clients) ++ selmon->clients = c; ++ else if(c == selmon->clients) ++ selmon->clients = selmon->sel; ++ ++ arrange(selmon); ++ } ++} ++ diff --git a/dwm.suckless.org/patches/dwm-movestack-6.1.diff b/dwm.suckless.org/patches/movestack/dwm-movestack-6.1.diff diff --git a/dwm.suckless.org/patches/movestack/index.md b/dwm.suckless.org/patches/movestack/index.md @@ -0,0 +1,39 @@ +# movestack + +## Description + +This plugin allows you to move clients around in the stack and swap them with +the master. It emulates the behavior off mod+shift+j and mod+shift+k in Xmonad. +movestack(+1) will swap the client with the current focus with the next client. +movestack(-1) will swap the client with the current focus with the previous client. + +## Usage + + 1. Download the patch and apply according to the [general instructions](.). + 2. Include the `movestack.c` source file and add keys that call movestack. + Example from `config.default.h`: + + #include "movestack.c" + static Key keys[] = { + /* modifier key function argument */ + ... + { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, + ... + +## Download + + * [dwm-movestack-6.1.diff](dwm-movestack-6.1.diff) + * [dwm-movestack-5.8.2.diff](dwm-movestack-5.8.2.diff) + +## Author + + * Niki Yoshiuchi - `<`aplusbi@gmail.com`>` + +## Contributors + + * Moritz Wilhelmy (fix to work with dwm 5.8) - `<`moritz plus suckless at wzff dot de`>` + +## Note + +This patch seems to be equivalent to the [push](push) patch. diff --git a/dwm.suckless.org/patches/mpdcontrol.md b/dwm.suckless.org/patches/mpdcontrol.md @@ -1,24 +0,0 @@ -mpdcontrol -======= - -Description ------------ -Control Music Player Daemon via keybinds. - -By default `MODKEY + Escape` stops/pauses the current song or plays it depending -on the state of the player. -If the song is a file on disk it pauses it, if it's a stream it stops it since -pause on a stream doesn't make sense. - -`MODKEY + F1` goes to previous song. -`MODKEY + F2` goes to next song. - -`libmpdclient` is needed for this patch to work. - -Download --------- - * [dwm-r1615-mpdcontrol.diff](dwm-r1615-mpdcontrol.diff) - -Author ------- - * Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-r1615-mpdcontrol.diff b/dwm.suckless.org/patches/mpdcontrol/dwm-r1615-mpdcontrol.diff diff --git a/dwm.suckless.org/patches/mpdcontrol/index.md b/dwm.suckless.org/patches/mpdcontrol/index.md @@ -0,0 +1,24 @@ +mpdcontrol +======= + +Description +----------- +Control Music Player Daemon via keybinds. + +By default `MODKEY + Escape` stops/pauses the current song or plays it depending +on the state of the player. +If the song is a file on disk it pauses it, if it's a stream it stops it since +pause on a stream doesn't make sense. + +`MODKEY + F1` goes to previous song. +`MODKEY + F2` goes to next song. + +`libmpdclient` is needed for this patch to work. + +Download +-------- + * [dwm-r1615-mpdcontrol.diff](dwm-r1615-mpdcontrol.diff) + +Author +------ + * Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com> diff --git a/dwm.suckless.org/patches/nametag.md b/dwm.suckless.org/patches/nametag.md @@ -1,22 +0,0 @@ -nametag -======= - -Description ------------ - -This patch allows you to change the names of dwm's tags while it's running. By default there is a 16 byte limit on tag names, and it uses dmenu to prompt for tag names. The 6.1 patch is for the current tip (cdec9782a1789bd5c3a84772fd59abb9da288597). It works with 6.0 but you should add -D_POSIX_C_SOURCE=2 to CPPFLAGS or you will get implicit delcaration warnings for popen and pclose. - -The `prepend` version prepends the tag name with a short string which is used as a format string for `sprintf` which gets the tag number as the argument. By default a tag name "foo" given to tag 5 will become tag "5:foo". - -Download --------- - -* [dwm-nametag-6.1.diff](dwm-nametag-6.1.diff) -* [dwm-nametag-prepend-6.1.diff](dwm-nametag-prepend-6.1.diff) -* [dwm-nametag-5.7.2.diff](dwm-nametag-5.7.2.diff) - -Author ------- - -* Evan Gates (emg) <[evan.gates@gmail.com](mailto:evan.gates@gmail.com)> -* prepend version by [Ondřej Grover](mailto:ondrej.grover@gmail.com) diff --git a/dwm.suckless.org/patches/dwm-nametag-5.7.2.diff b/dwm.suckless.org/patches/nametag/dwm-nametag-5.7.2.diff diff --git a/dwm.suckless.org/patches/dwm-nametag-6.1.diff b/dwm.suckless.org/patches/nametag/dwm-nametag-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-nametag-prepend-6.1.diff b/dwm.suckless.org/patches/nametag/dwm-nametag-prepend-6.1.diff diff --git a/dwm.suckless.org/patches/nametag/index.md b/dwm.suckless.org/patches/nametag/index.md @@ -0,0 +1,22 @@ +nametag +======= + +Description +----------- + +This patch allows you to change the names of dwm's tags while it's running. By default there is a 16 byte limit on tag names, and it uses dmenu to prompt for tag names. The 6.1 patch is for the current tip (cdec9782a1789bd5c3a84772fd59abb9da288597). It works with 6.0 but you should add -D_POSIX_C_SOURCE=2 to CPPFLAGS or you will get implicit delcaration warnings for popen and pclose. + +The `prepend` version prepends the tag name with a short string which is used as a format string for `sprintf` which gets the tag number as the argument. By default a tag name "foo" given to tag 5 will become tag "5:foo". + +Download +-------- + +* [dwm-nametag-6.1.diff](dwm-nametag-6.1.diff) +* [dwm-nametag-prepend-6.1.diff](dwm-nametag-prepend-6.1.diff) +* [dwm-nametag-5.7.2.diff](dwm-nametag-5.7.2.diff) + +Author +------ + +* Evan Gates (emg) <[evan.gates@gmail.com](mailto:evan.gates@gmail.com)> +* prepend version by [Ondřej Grover](mailto:ondrej.grover@gmail.com) diff --git a/dwm.suckless.org/patches/nextprev.md b/dwm.suckless.org/patches/nextprev.md @@ -1,33 +0,0 @@ -# next prev tag - -## Description - - * Increment or decrement the selected tag - * [shiftview][].c is a better implementation of this, allowing you to rotate the selected tags - -## Download - - * [nextprevtag.c](nextprevtag.c) - -## Example Usage - - static Key keys[] = { - /* ... */ - { MODKEY, XK_i, view_adjacent, { .i = +1 } }, - { MODKEY, XK_u, view_adjacent, { .i = -1 } }, - /* ... */ - }; - - static Button buttons[] = { - /* ... */ - { ClkTagBar, 0, Button4, view_adjacent, { .i = -1 } }, - { ClkTagBar, 0, Button5, view_adjacent, { .i = +1 } }, - /* ... */ - }; - - -## Author - - * Rob Pilling - robpilling gmail com - -[shiftview]: //lists.suckless.org/dev/1104/7590.html diff --git a/dwm.suckless.org/patches/nextprev/index.md b/dwm.suckless.org/patches/nextprev/index.md @@ -0,0 +1,33 @@ +# next prev tag + +## Description + + * Increment or decrement the selected tag + * [shiftview][].c is a better implementation of this, allowing you to rotate the selected tags + +## Download + + * [nextprevtag.c](nextprevtag.c) + +## Example Usage + + static Key keys[] = { + /* ... */ + { MODKEY, XK_i, view_adjacent, { .i = +1 } }, + { MODKEY, XK_u, view_adjacent, { .i = -1 } }, + /* ... */ + }; + + static Button buttons[] = { + /* ... */ + { ClkTagBar, 0, Button4, view_adjacent, { .i = -1 } }, + { ClkTagBar, 0, Button5, view_adjacent, { .i = +1 } }, + /* ... */ + }; + + +## Author + + * Rob Pilling - robpilling gmail com + +[shiftview]: //lists.suckless.org/dev/1104/7590.html diff --git a/dwm.suckless.org/patches/nextprev/nextprevtag.c b/dwm.suckless.org/patches/nextprev/nextprevtag.c @@ -0,0 +1,21 @@ +void +view_adjacent(const Arg *arg) +{ + int i, curtags; + int seltag = 0; + Arg a; + + curtags = selmon->tagset[selmon->seltags]; + for(i = 0; i < LENGTH(tags); i++) + if(curtags & (1 << i)){ + seltag = i; + break; + } + + seltag = (seltag + arg->i) % (int)LENGTH(tags); + if(seltag < 0) + seltag += LENGTH(tags); + + a.i = (1 << seltag); + view(&a); +} diff --git a/dwm.suckless.org/patches/nextprevtag.c b/dwm.suckless.org/patches/nextprevtag.c @@ -1,21 +0,0 @@ -void -view_adjacent(const Arg *arg) -{ - int i, curtags; - int seltag = 0; - Arg a; - - curtags = selmon->tagset[selmon->seltags]; - for(i = 0; i < LENGTH(tags); i++) - if(curtags & (1 << i)){ - seltag = i; - break; - } - - seltag = (seltag + arg->i) % (int)LENGTH(tags); - if(seltag < 0) - seltag += LENGTH(tags); - - a.i = (1 << seltag); - view(&a); -} diff --git a/dwm.suckless.org/patches/nmaster-ncol.c b/dwm.suckless.org/patches/nmaster-ncol.c @@ -1,163 +0,0 @@ -enum {MaxMon = 8}; -static int nmasters[MaxMon]; -static int initnm = 0; - -static void -initnmaster(void) { - int i; - - if(initnm) - return; - for(i = 0; i < MaxMon; i++) - nmasters[i] = nmaster; - initnm = 1; -} - -static void -incnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] += arg->i; - if(nmasters[selmon->num] < 0) - nmasters[selmon->num] = 0; - arrange(NULL); -} - -static void -setnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; - arrange(NULL); -} - -static void -ntile(Monitor *m) { - int x, y, h, w, mw, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mw = m->mfact * m->ww; - h = m->wh / nm; - if(h < bh) - h = m->wh; - y = m->wy; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, - ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } - n -= nm; - } else - mw = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx + mw; - y = m->wy; - w = m->ww - mw; - h = m->wh / n; - if(h < bh) - h = m->wh; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, - ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } -} - -static void -ncol(Monitor *m) { - int x, y, h, w, mw, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mw = (n == nm) ? m->ww : m->mfact * m->ww; - w = mw / nm; - x = m->wx; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, x, m->wy, w - 2 * c->bw, m->wh - 2 * c->bw, False); - x = c->x + WIDTH(c); - } - n -= nm; - } else - mw = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx + mw; - y = m->wy; - w = m->ww - mw; - h = m->wh / n; - if(h < bh) - h = m->wh; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, - ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } -} - -static void -nbstack(Monitor *m) { - int x, y, h, w, mh, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mh = m->mfact * m->wh; - w = m->ww / nm; - if(w < bh) - w = m->ww; - x = m->wx; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, - (n == nm ? m->wh : mh) - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } - n -= nm; - } else - mh = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx; - y = m->wy + mh; - w = m->ww / n; - h = m->wh - mh; - if(w < bh) - w = m->ww; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, - h - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } -} diff --git a/dwm.suckless.org/patches/nmaster-sym.c b/dwm.suckless.org/patches/nmaster-sym.c @@ -1,126 +0,0 @@ -enum {MaxMon = 8}; -static int nmasters[MaxMon]; -static int initnm = 0; - -static void -initnmaster(void) { - int i; - - if(initnm) - return; - for(i = 0; i < MaxMon; i++) - nmasters[i] = nmaster; - initnm = 1; -} - -static void -incnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] += arg->i; - if(nmasters[selmon->num] < 0) - nmasters[selmon->num] = 0; - arrange(selmon); -} - -static void -setnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; - arrange(selmon); -} - -static void -ntile(Monitor *m) { - int x, y, h, w, mw, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d]=", nmasters[m->num]); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mw = m->mfact * m->ww; - h = m->wh / nm; - if(h < bh) - h = m->wh; - y = m->wy; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, - ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } - n -= nm; - } else - mw = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx + mw; - y = m->wy; - w = m->ww - mw; - h = m->wh / n; - if(h < bh) - h = m->wh; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, - ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } -} - -static void -nbstack(Monitor *m) { - int x, y, h, w, mh, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "T%dT", nmasters[m->num]); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mh = m->mfact * m->wh; - w = m->ww / nm; - if(w < bh) - w = m->ww; - x = m->wx; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, - (n == nm ? m->wh : mh) - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } - n -= nm; - } else - mh = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx; - y = m->wy + mh; - w = m->ww / n; - h = m->wh - mh; - if(w < bh) - w = m->ww; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, - h - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } -} diff --git a/dwm.suckless.org/patches/nmaster.c b/dwm.suckless.org/patches/nmaster.c @@ -1,122 +0,0 @@ -enum {MaxMon = 8}; -static int nmasters[MaxMon]; -static int initnm = 0; - -static void -initnmaster(void) { - int i; - - if(initnm) - return; - for(i = 0; i < MaxMon; i++) - nmasters[i] = nmaster; - initnm = 1; -} - -static void -incnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] += arg->i; - if(nmasters[selmon->num] < 0) - nmasters[selmon->num] = 0; - arrange(); -} - -static void -setnmaster(const Arg *arg) { - if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) - return; - nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; - arrange(); -} - -static void -ntile(Monitor *m) { - int x, y, h, w, mw, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mw = m->mfact * m->ww; - h = m->wh / nm; - if(h < bh) - h = m->wh; - y = m->wy; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, - ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } - n -= nm; - } else - mw = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx + mw; - y = m->wy; - w = m->ww - mw; - h = m->wh / n; - if(h < bh) - h = m->wh; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, - ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); - if(h != m->wh) - y = c->y + HEIGHT(c); - } -} - -static void -nbstack(Monitor *m) { - int x, y, h, w, mh, nm; - unsigned int i, n; - Client *c; - - initnmaster(); - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - c = nexttiled(m->clients); - nm = m->num < MaxMon ? nmasters[m->num] : nmaster; - if(nm > n) - nm = n; - /* master */ - if(nm > 0) { - mh = m->mfact * m->wh; - w = m->ww / nm; - if(w < bh) - w = m->ww; - x = m->wx; - for(i = 0; i < nm; i++, c = nexttiled(c->next)) { - resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, - (n == nm ? m->wh : mh) - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } - n -= nm; - } else - mh = 0; - if(n == 0) - return; - /* tile stack */ - x = m->wx; - y = m->wy + mh; - w = m->ww / n; - h = m->wh - mh; - if(w < bh) - w = m->ww; - for(i = 0; c; c = nexttiled(c->next), i++) { - resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, - h - 2 * c->bw, False); - if(w != m->ww) - x = c->x + WIDTH(c); - } -} diff --git a/dwm.suckless.org/patches/nmaster.md b/dwm.suckless.org/patches/nmaster.md @@ -1,66 +0,0 @@ -# nmaster patch - -## History - -This patch restores the ability to have multiple clients in the master -area of the tiled layout. This feature was dropped from vanilla dwm in -version 4.4. The ntile mode from below is included in dwm as of version -6.0. - -## Description - -The figures show how tiling will work when the patch is applied. - - ntile (-|=) - +----------+------+ - | | | - | +------+ - |----------| | - | +------+ - | | | - +----------+------+ - - nbstack (-|-) - +--------+--------+ - | | | - | | | - |-----+--+--+-----+ - | | | | - | | | | - +-----+-----+-----+ - -## Usage - -* Download `nmaster.c` into the source directory of dwm. -* Add `nmaster` default value to your `config.h`. -* Include `nmaster.c` in `config.h` after the definition of `nmaster`. -* Add `ntile` and/or `nbstack` to your layouts. -* Add keybindings to `incnmaster` and/or `setnmaster` to your `config.h`. - -## Example - - static const int nmaster = 2; /* default number of clients in the master area */ - - #include "nmaster.c" - - static const Layout layouts[] = { - /* symbol arrange function */ - { "-|=", ntile }, - { "-|-", nbstack }, - ... - - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_a, incnmaster, {.i = +1 } }, - { MODKEY, XK_z, incnmaster, {.i = -1 } }, - { MODKEY, XK_x, setnmaster, {.i = 2 } }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0] } }, - { MODKEY, XK_b, setlayout, {.v = &layouts[1] } }, - ... - -## Download - -* [nmaster-ncol.c](nmaster-ncol.c) (dwm 5.9) (20101210) - additional ncol layout (multiple masters side by side) -* [nmaster-sym.c](nmaster-sym.c) (dwm 5.7.1) (20090927) - layout symbol shows the number of masters: `n]=`, `TnT` -* [nmaster.c](nmaster.c) (dwm 5.6.1) (20090908) -* see older versions in [historical patches](historical) diff --git a/dwm.suckless.org/patches/nmaster/index.md b/dwm.suckless.org/patches/nmaster/index.md @@ -0,0 +1,66 @@ +# nmaster + +## History + +This patch restores the ability to have multiple clients in the master +area of the tiled layout. This feature was dropped from vanilla dwm in +version 4.4. The ntile mode from below is included in dwm as of version +6.0. + +## Description + +The figures show how tiling will work when the patch is applied. + + ntile (-|=) + +----------+------+ + | | | + | +------+ + |----------| | + | +------+ + | | | + +----------+------+ + + nbstack (-|-) + +--------+--------+ + | | | + | | | + |-----+--+--+-----+ + | | | | + | | | | + +-----+-----+-----+ + +## Usage + +* Download `nmaster.c` into the source directory of dwm. +* Add `nmaster` default value to your `config.h`. +* Include `nmaster.c` in `config.h` after the definition of `nmaster`. +* Add `ntile` and/or `nbstack` to your layouts. +* Add keybindings to `incnmaster` and/or `setnmaster` to your `config.h`. + +## Example + + static const int nmaster = 2; /* default number of clients in the master area */ + + #include "nmaster.c" + + static const Layout layouts[] = { + /* symbol arrange function */ + { "-|=", ntile }, + { "-|-", nbstack }, + ... + + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_a, incnmaster, {.i = +1 } }, + { MODKEY, XK_z, incnmaster, {.i = -1 } }, + { MODKEY, XK_x, setnmaster, {.i = 2 } }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0] } }, + { MODKEY, XK_b, setlayout, {.v = &layouts[1] } }, + ... + +## Download + +* [nmaster-ncol.c](nmaster-ncol.c) (dwm 5.9) (20101210) - additional ncol layout (multiple masters side by side) +* [nmaster-sym.c](nmaster-sym.c) (dwm 5.7.1) (20090927) - layout symbol shows the number of masters: `n]=`, `TnT` +* [nmaster.c](nmaster.c) (dwm 5.6.1) (20090908) +* see older versions in [historical patches](historical) diff --git a/dwm.suckless.org/patches/nmaster/nmaster-ncol.c b/dwm.suckless.org/patches/nmaster/nmaster-ncol.c @@ -0,0 +1,163 @@ +enum {MaxMon = 8}; +static int nmasters[MaxMon]; +static int initnm = 0; + +static void +initnmaster(void) { + int i; + + if(initnm) + return; + for(i = 0; i < MaxMon; i++) + nmasters[i] = nmaster; + initnm = 1; +} + +static void +incnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] += arg->i; + if(nmasters[selmon->num] < 0) + nmasters[selmon->num] = 0; + arrange(NULL); +} + +static void +setnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; + arrange(NULL); +} + +static void +ntile(Monitor *m) { + int x, y, h, w, mw, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mw = m->mfact * m->ww; + h = m->wh / nm; + if(h < bh) + h = m->wh; + y = m->wy; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, + ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } + n -= nm; + } else + mw = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx + mw; + y = m->wy; + w = m->ww - mw; + h = m->wh / n; + if(h < bh) + h = m->wh; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, w - 2 * c->bw, + ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } +} + +static void +ncol(Monitor *m) { + int x, y, h, w, mw, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mw = (n == nm) ? m->ww : m->mfact * m->ww; + w = mw / nm; + x = m->wx; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, x, m->wy, w - 2 * c->bw, m->wh - 2 * c->bw, False); + x = c->x + WIDTH(c); + } + n -= nm; + } else + mw = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx + mw; + y = m->wy; + w = m->ww - mw; + h = m->wh / n; + if(h < bh) + h = m->wh; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, w - 2 * c->bw, + ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } +} + +static void +nbstack(Monitor *m) { + int x, y, h, w, mh, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mh = m->mfact * m->wh; + w = m->ww / nm; + if(w < bh) + w = m->ww; + x = m->wx; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, + (n == nm ? m->wh : mh) - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } + n -= nm; + } else + mh = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx; + y = m->wy + mh; + w = m->ww / n; + h = m->wh - mh; + if(w < bh) + w = m->ww; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, + h - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } +} diff --git a/dwm.suckless.org/patches/nmaster/nmaster-sym.c b/dwm.suckless.org/patches/nmaster/nmaster-sym.c @@ -0,0 +1,126 @@ +enum {MaxMon = 8}; +static int nmasters[MaxMon]; +static int initnm = 0; + +static void +initnmaster(void) { + int i; + + if(initnm) + return; + for(i = 0; i < MaxMon; i++) + nmasters[i] = nmaster; + initnm = 1; +} + +static void +incnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] += arg->i; + if(nmasters[selmon->num] < 0) + nmasters[selmon->num] = 0; + arrange(selmon); +} + +static void +setnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; + arrange(selmon); +} + +static void +ntile(Monitor *m) { + int x, y, h, w, mw, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d]=", nmasters[m->num]); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mw = m->mfact * m->ww; + h = m->wh / nm; + if(h < bh) + h = m->wh; + y = m->wy; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, + ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } + n -= nm; + } else + mw = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx + mw; + y = m->wy; + w = m->ww - mw; + h = m->wh / n; + if(h < bh) + h = m->wh; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, w - 2 * c->bw, + ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } +} + +static void +nbstack(Monitor *m) { + int x, y, h, w, mh, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "T%dT", nmasters[m->num]); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mh = m->mfact * m->wh; + w = m->ww / nm; + if(w < bh) + w = m->ww; + x = m->wx; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, + (n == nm ? m->wh : mh) - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } + n -= nm; + } else + mh = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx; + y = m->wy + mh; + w = m->ww / n; + h = m->wh - mh; + if(w < bh) + w = m->ww; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, + h - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } +} diff --git a/dwm.suckless.org/patches/nmaster/nmaster.c b/dwm.suckless.org/patches/nmaster/nmaster.c @@ -0,0 +1,122 @@ +enum {MaxMon = 8}; +static int nmasters[MaxMon]; +static int initnm = 0; + +static void +initnmaster(void) { + int i; + + if(initnm) + return; + for(i = 0; i < MaxMon; i++) + nmasters[i] = nmaster; + initnm = 1; +} + +static void +incnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] += arg->i; + if(nmasters[selmon->num] < 0) + nmasters[selmon->num] = 0; + arrange(); +} + +static void +setnmaster(const Arg *arg) { + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon) + return; + nmasters[selmon->num] = arg->i > 0 ? arg->i : 0; + arrange(); +} + +static void +ntile(Monitor *m) { + int x, y, h, w, mw, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mw = m->mfact * m->ww; + h = m->wh / nm; + if(h < bh) + h = m->wh; + y = m->wy; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw, + ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } + n -= nm; + } else + mw = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx + mw; + y = m->wy; + w = m->ww - mw; + h = m->wh / n; + if(h < bh) + h = m->wh; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, w - 2 * c->bw, + ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False); + if(h != m->wh) + y = c->y + HEIGHT(c); + } +} + +static void +nbstack(Monitor *m) { + int x, y, h, w, mh, nm; + unsigned int i, n; + Client *c; + + initnmaster(); + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + c = nexttiled(m->clients); + nm = m->num < MaxMon ? nmasters[m->num] : nmaster; + if(nm > n) + nm = n; + /* master */ + if(nm > 0) { + mh = m->mfact * m->wh; + w = m->ww / nm; + if(w < bh) + w = m->ww; + x = m->wx; + for(i = 0; i < nm; i++, c = nexttiled(c->next)) { + resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw, + (n == nm ? m->wh : mh) - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } + n -= nm; + } else + mh = 0; + if(n == 0) + return; + /* tile stack */ + x = m->wx; + y = m->wy + mh; + w = m->ww / n; + h = m->wh - mh; + if(w < bh) + w = m->ww; + for(i = 0; c; c = nexttiled(c->next), i++) { + resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw, + h - 2 * c->bw, False); + if(w != m->ww) + x = c->x + WIDTH(c); + } +} diff --git a/dwm.suckless.org/patches/noborder.md b/dwm.suckless.org/patches/noborder.md @@ -1,21 +0,0 @@ -noborder -======== - -Description ------------ - -Remove the border when there is only one window visible. - -Download --------- - - * [dwm-noborder-20170207-bb3bd6f.diff](dwm-noborder-20170207-bb3bd6f.diff) - * [dwm-noborder-6.1.diff](dwm-noborder-6.1.diff) - * [dwm-noborder-20160718-56a31dc.diff](dwm-noborder-20160718-56a31dc.diff) - -Authors -------- - - * Eric Pruitt - <eric.pruitt@gmail.com> - * Laslo Hunhold - <dev@frign.de> (6.1, git port) - * Markus Teich - markus(DOT)teich(AT)stusta(DOT)de (simplification) diff --git a/dwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff b/dwm.suckless.org/patches/noborder/dwm-noborder-20160718-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-noborder-20170207-bb3bd6f.diff b/dwm.suckless.org/patches/noborder/dwm-noborder-20170207-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/dwm-noborder-6.1.diff b/dwm.suckless.org/patches/noborder/dwm-noborder-6.1.diff diff --git a/dwm.suckless.org/patches/noborder/index.md b/dwm.suckless.org/patches/noborder/index.md @@ -0,0 +1,21 @@ +noborder +======== + +Description +----------- + +Remove the border when there is only one window visible. + +Download +-------- + + * [dwm-noborder-20170207-bb3bd6f.diff](dwm-noborder-20170207-bb3bd6f.diff) + * [dwm-noborder-6.1.diff](dwm-noborder-6.1.diff) + * [dwm-noborder-20160718-56a31dc.diff](dwm-noborder-20160718-56a31dc.diff) + +Authors +------- + + * Eric Pruitt - <eric.pruitt@gmail.com> + * Laslo Hunhold - <dev@frign.de> (6.1, git port) + * Markus Teich - markus(DOT)teich(AT)stusta(DOT)de (simplification) diff --git a/dwm.suckless.org/patches/pango.md b/dwm.suckless.org/patches/pango.md @@ -1,40 +0,0 @@ -Pango -===== - -Description ------------ - -This relatively simple patch adds pango support for the status bar. This not only adds -TrueType font support but also opens a couple of interesting possibilities that are -not possible under barebone xft: - -* **Simple markup** for status messages (optional, enable/disable it in your config.h) - using [pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html). - So you can format your status messages specifying fg/bg colors, sizes, sub/superscripts, - underline, emphasis, bold, etc. You can do dynamic font switching, also! To play safe - with the rest of the status bar, markup support is restricted to the status message area - over which you have direct control. - -* **Fallback fonts**, so you can use -for example- some set of iconic fonts as your second - family: "DejaVu Sans, Icons 8" [1]. There are tons of monochromatic nice looking TTF - icons around the web these days as webfonts are becoming more and more popular. Notice - that you can also use the more powerful font switching enabled by pango markup to - achieve the same goal. Also don't be mislead by the fact that fontconfig understands - descriptors like "DejaVu Sans, Icons-8" or even font sequences defined as alias in your - fonts.conf. xft will pick one font once and for all, not on a char-by-char basis. - -[1] The [Icons family](https://aur.archlinux.org/packages/ttf-font-icons/) is a - non-overlapping merge of Awesome and Ionicons fonts I've made for my statusbar. In case - you want to take a look at it, there is a - [cheatsheet](https://www.dropbox.com/s/9iysh2i0gadi4ic/icons.pdf) listing the icons and - their unicode points. - -Download --------- - -* [dwm-pango-6.0.diff](dwm-pango-6.0.diff) - -Author ------- - -* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-pango-6.0.diff b/dwm.suckless.org/patches/pango/dwm-pango-6.0.diff diff --git a/dwm.suckless.org/patches/pango/index.md b/dwm.suckless.org/patches/pango/index.md @@ -0,0 +1,40 @@ +Pango +===== + +Description +----------- + +This relatively simple patch adds pango support for the status bar. This not only adds +TrueType font support but also opens a couple of interesting possibilities that are +not possible under barebone xft: + +* **Simple markup** for status messages (optional, enable/disable it in your config.h) + using [pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html). + So you can format your status messages specifying fg/bg colors, sizes, sub/superscripts, + underline, emphasis, bold, etc. You can do dynamic font switching, also! To play safe + with the rest of the status bar, markup support is restricted to the status message area + over which you have direct control. + +* **Fallback fonts**, so you can use -for example- some set of iconic fonts as your second + family: "DejaVu Sans, Icons 8" [1]. There are tons of monochromatic nice looking TTF + icons around the web these days as webfonts are becoming more and more popular. Notice + that you can also use the more powerful font switching enabled by pango markup to + achieve the same goal. Also don't be mislead by the fact that fontconfig understands + descriptors like "DejaVu Sans, Icons-8" or even font sequences defined as alias in your + fonts.conf. xft will pick one font once and for all, not on a char-by-char basis. + +[1] The [Icons family](https://aur.archlinux.org/packages/ttf-font-icons/) is a + non-overlapping merge of Awesome and Ionicons fonts I've made for my statusbar. In case + you want to take a look at it, there is a + [cheatsheet](https://www.dropbox.com/s/9iysh2i0gadi4ic/icons.pdf) listing the icons and + their unicode points. + +Download +-------- + +* [dwm-pango-6.0.diff](dwm-pango-6.0.diff) + +Author +------ + +* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/pertag.md b/dwm.suckless.org/patches/pertag.md @@ -1,51 +0,0 @@ -pertag -====== - -Description ------------ -More general approach to [taglayouts patch][1]. This patch keeps layout, -mwfact, barpos and nmaster per tag. - -Download --------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-pertag-20170513-ceac8c9.diff](dwm-pertag-20170513-ceac8c9.diff) - * [dwm-pertag-6.1.diff](dwm-pertag-6.1.diff) (6.4K) (20151109) - * [dwm-git-20120406-pertag.diff](dwm-git-20120406-pertag.diff) (5955b) - * [dwm-pertag-6.0.diff](dwm-pertag-6.0.diff) (5955b) (20120406) - * [dwm-r1578-pertag.diff][9] (nmaster included in mainline) - * [dwm-pertag-5.8.2.diff][7] - * [dwm-pertag-5.7.2.diff][6] - * [dwm-pertag-5.6.1.diff][5] - * [dwm-pertag-5.4.diff][4] - * [dwm-pertag-5.2.diff][3] - * [dwm-pertag-5.1.diff][2] - - * Using pertag but with the same barpos - * [dwm-6.1-pertag_without_bar.diff](dwm-6.1-pertag_without_bar.diff) (5.2K) (20151109) - * [dwm-6.0-pertag_without_bar.diff](dwm-6.0-pertag_without_bar.diff) (5578b) (20140530) - * [dwm-5.8.2-pertag\_without\_bar.diff][8] - -Authors -------- - * 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>` - * Updated by Ivan Tham - `pickfire at riseup dot net` - * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (Updated to current git) - * Lucas Gabriel Vuotto - <lvuotto92@gmail.com> (git ports) - -[1]: historical/taglayouts -[2]: historical/dwm-pertag-5.1.diff -[3]: historical/dwm-pertag-5.2.diff -[4]: historical/dwm-pertag-5.4.diff -[5]: historical/dwm-pertag-5.6.1.diff -[6]: historical/dwm-pertag-5.7.2.diff -[7]: historical/dwm-pertag-5.8.2.diff -[8]: historical/dwm-5.8.2-pertag_without_bar.diff -[9]: historical/dwm-r1578-pertag.diff diff --git a/dwm.suckless.org/patches/pertag/dwm-5.8.2-pertag_without_bar.diff b/dwm.suckless.org/patches/pertag/dwm-5.8.2-pertag_without_bar.diff @@ -0,0 +1,165 @@ +diff --git a/dwm.c b/dwm.c +--- a/dwm.c ++++ b/dwm.c +@@ -122,26 +122,6 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + +-struct Monitor { +- char ltsymbol[16]; +- float mfact; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +-}; +- + typedef struct { + const char *class; + const char *instance; +@@ -278,6 +258,30 @@ static Window root; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Monitor { ++ char ltsymbol[16]; ++ float mfact; ++ int num; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++ int curtag; ++ int prevtag; ++ const Layout *lts[LENGTH(tags) + 1]; ++ double mfacts[LENGTH(tags) + 1]; ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -609,6 +613,7 @@ configurerequest(XEvent *e) { + Monitor * + createmon(void) { + Monitor *m; ++ unsigned int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +@@ -619,6 +624,14 @@ createmon(void) { + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ ++ /* pertag init */ ++ m->curtag = m->prevtag = 1; ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ m->mfacts[i] = mfact; ++ m->lts[i] = &layouts[0]; ++ } ++ + return m; + } + +@@ -1486,7 +1499,7 @@ setlayout(const Arg *arg) { + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1504,7 +1517,7 @@ setmfact(const Arg *arg) { + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->mfacts[selmon->curtag] = f; + arrange(selmon); + } + +@@ -1547,7 +1560,6 @@ setup(void) { + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); +- /* init bars */ + updatebars(); + updatestatus(); + /* EWMH support per view */ +@@ -1678,12 +1690,25 @@ togglefloating(const Arg *arg) { + void + toggletag(const Arg *arg) { + unsigned int newtags; ++ unsigned int i; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { + selmon->sel->tags = newtags; ++ if(newtags == ~0) { ++ selmon->prevtag = selmon->curtag; ++ selmon->curtag = 0; ++ } ++ if(!(newtags & 1 << (selmon->curtag - 1))) { ++ selmon->prevtag = selmon->curtag; ++ for (i=0; !(newtags & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ selmon->sel->tags = newtags; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; + arrange(selmon); + } + } +@@ -1950,11 +1975,27 @@ updatewmhints(Client *c) { + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->prevtag = selmon->curtag; ++ if(arg->ui == ~0) ++ selmon->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ } else { ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ selmon->curtag^= selmon->prevtag; ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ } ++ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-6.0-pertag_without_bar.diff b/dwm.suckless.org/patches/pertag/dwm-6.0-pertag_without_bar.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-pertag_without_bar.diff b/dwm.suckless.org/patches/pertag/dwm-6.1-pertag_without_bar.diff diff --git a/dwm.suckless.org/patches/dwm-git-20120406-pertag.diff b/dwm.suckless.org/patches/pertag/dwm-git-20120406-pertag.diff diff --git a/dwm.suckless.org/patches/dwm-pertag-20170513-ceac8c9.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-20170513-ceac8c9.diff diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.1.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.1.diff @@ -0,0 +1,125 @@ +diff -NrU3 dwm-5.1/dwm.c dwm-5.1.playground-pertag/dwm.c +--- dwm-5.1/dwm.c 2008-07-29 20:18:32.000000000 +0200 ++++ dwm-5.1-pertag/dwm.c 2008-08-01 18:46:49.000000000 +0200 +@@ -238,6 +238,11 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++static int curtag = 1, prevtag = 1; ++static Layout *lts[LENGTH(tags) + 1]; ++static double mfacts[LENGTH(tags) + 1]; ++static Bool showbars[LENGTH(tags) + 1]; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; + +@@ -1307,7 +1312,7 @@ + if(!arg || !arg->v || arg->v != lt[sellt]) + sellt ^= 1; + if(arg && arg->v) +- lt[sellt] = (Layout *)arg->v; ++ lt[sellt] = lts[curtag] = (Layout *)arg->v; + if(sel) + arrange(); + else +@@ -1324,7 +1329,7 @@ + f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- mfact = f; ++ mfact = mfacts[curtag] = f; + arrange(); + } + +@@ -1373,12 +1378,27 @@ + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); + ++ /* init mfacts */ ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ mfacts[i] = mfact; ++ } ++ ++ /* init layouts */ ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ lts[i] = &layouts[0]; ++ } ++ ++ + /* init bar */ + for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { + w = TEXTW(layouts[i].symbol); + blw = MAX(blw, w); + } + ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ showbars[i] = showbar; ++ } ++ + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ButtonPressMask|ExposureMask; +@@ -1479,7 +1499,7 @@ + + void + togglebar(const Arg *arg) { +- showbar = !showbar; ++ showbar = showbars[curtag] = !showbar; + updategeom(); + updatebar(); + arrange(); +@@ -1508,9 +1528,23 @@ + void + toggleview(const Arg *arg) { + unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); ++ unsigned int i; + + if(mask) { ++ if(mask == ~0) { ++ prevtag = curtag; ++ curtag = 0; ++ } ++ if(!(mask & 1 << (curtag - 1))) { ++ prevtag = curtag; ++ for (i=0; !(mask & 1 << i); i++); ++ curtag = i + 1; ++ } + tagset[seltags] = mask; ++ lt[sellt] = lts[curtag]; ++ mfact = mfacts[curtag]; ++ if (showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } +@@ -1663,11 +1697,29 @@ + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if(arg && (arg->i & TAGMASK) == tagset[seltags]) + return; + seltags ^= 1; /* toggle sel tagset */ +- if(arg && (arg->ui & TAGMASK)) ++ if(arg && (arg->ui & TAGMASK)) { + tagset[seltags] = arg->i & TAGMASK; ++ prevtag = curtag; ++ if(arg->ui == ~0) ++ curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ curtag = i + 1; ++ } ++ } else { ++ prevtag= curtag ^ prevtag; ++ curtag^= prevtag; ++ prevtag= curtag ^ prevtag; ++ } ++ lt[sellt]= lts[curtag]; ++ mfact = mfacts[curtag]; ++ if(showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.2.diff @@ -0,0 +1,123 @@ +--- dwm-5.2/dwm.c 2008-09-09 21:46:17.000000000 +0200 ++++ dwm-5.2-pertag/dwm.c 2008-10-12 23:53:30.000000000 +0200 +@@ -240,6 +240,11 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++static int curtag = 1, prevtag = 1; ++static Layout *lts[LENGTH(tags) + 1]; ++static double mfacts[LENGTH(tags) + 1]; ++static Bool showbars[LENGTH(tags) + 1]; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; + +@@ -1272,7 +1277,7 @@ + if(!arg || !arg->v || arg->v != lt[sellt]) + sellt ^= 1; + if(arg && arg->v) +- lt[sellt] = (Layout *)arg->v; ++ lt[sellt] = lts[curtag] = (Layout *)arg->v; + if(sel) + arrange(); + else +@@ -1289,7 +1294,7 @@ + f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- mfact = f; ++ mfact = mfacts[curtag] = f; + arrange(); + } + +@@ -1337,12 +1342,27 @@ + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); + ++ /* init mfacts */ ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ mfacts[i] = mfact; ++ } ++ ++ /* init layouts */ ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ lts[i] = &layouts[0]; ++ } ++ ++ + /* init bar */ + for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { + w = TEXTW(layouts[i].symbol); + blw = MAX(blw, w); + } + ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ showbars[i] = showbar; ++ } ++ + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ButtonPressMask|ExposureMask; +@@ -1457,7 +1477,7 @@ + + void + togglebar(const Arg *arg) { +- showbar = !showbar; ++ showbar = showbars[curtag] = !showbar; + updategeom(); + updatebar(); + arrange(); +@@ -1490,9 +1510,23 @@ + void + toggleview(const Arg *arg) { + unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); ++ unsigned int i; + + if(mask) { ++ if(mask == ~0) { ++ prevtag = curtag; ++ curtag = 0; ++ } ++ if(!(mask & 1 << (curtag - 1))) { ++ prevtag = curtag; ++ for (i=0; !(mask & 1 << i); i++); ++ curtag = i + 1; ++ } + tagset[seltags] = mask; ++ lt[sellt] = lts[curtag]; ++ mfact = mfacts[curtag]; ++ if (showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } +@@ -1661,11 +1695,28 @@ + + void + view(const Arg *arg) { ++ unsigned int i; + if((arg->ui & TAGMASK) == tagset[seltags]) + return; + seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + tagset[seltags] = arg->ui & TAGMASK; ++ prevtag = curtag; ++ if(arg->ui == ~0) ++ curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ curtag = i + 1; ++ } ++ } else { ++ prevtag= curtag ^ prevtag; ++ curtag^= prevtag; ++ prevtag= curtag ^ prevtag; ++ } ++ lt[sellt]= lts[curtag]; ++ mfact = mfacts[curtag]; ++ if(showbar != showbars[curtag]) ++ togglebar(NULL); + clearurgent(); + arrange(); + } diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.4.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.4.diff @@ -0,0 +1,123 @@ +diff -r add6eb26ebaa dwm.c +--- a/dwm.c Sat Dec 20 12:02:14 2008 +0000 ++++ b/dwm.c Sun Dec 21 18:39:14 2008 +0100 +@@ -240,6 +240,11 @@ static Window root, barwin; + static Window root, barwin; + /* configuration, allows nested code to access above variables */ + #include "config.h" ++ ++static int curtag = 1, prevtag = 1; ++static Layout *lts[LENGTH(tags) + 1]; ++static double mfacts[LENGTH(tags) + 1]; ++static Bool showbars[LENGTH(tags) + 1]; + + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; }; +@@ -1244,7 +1249,7 @@ setlayout(const Arg *arg) { + if(!arg || !arg->v || arg->v != lt[sellt]) + sellt ^= 1; + if(arg && arg->v) +- lt[sellt] = (Layout *)arg->v; ++ lt[sellt] = lts[curtag] = (Layout *)arg->v; + if(sel) + arrange(); + else +@@ -1261,7 +1266,7 @@ setmfact(const Arg *arg) { + f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- mfact = f; ++ mfact = mfacts[curtag] = f; + arrange(); + } + +@@ -1309,11 +1314,26 @@ setup(void) { + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); + ++ /* init mfacts */ ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ mfacts[i] = mfact; ++ } ++ ++ /* init layouts */ ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ lts[i] = &layouts[0]; ++ } ++ ++ + /* init bar */ + for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { + w = TEXTW(layouts[i].symbol); + blw = MAX(blw, w); + } ++ ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ showbars[i] = showbar; ++ } + + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; +@@ -1434,7 +1454,7 @@ tile(void) { + + void + togglebar(const Arg *arg) { +- showbar = !showbar; ++ showbar = showbars[curtag] = !showbar; + updategeom(); + updatebar(); + arrange(); +@@ -1467,9 +1487,23 @@ void + void + toggleview(const Arg *arg) { + unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK); ++ unsigned int i; + + if(mask) { ++ if(mask == ~0) { ++ prevtag = curtag; ++ curtag = 0; ++ } ++ if(!(mask & 1 << (curtag - 1))) { ++ prevtag = curtag; ++ for (i=0; !(mask & 1 << i); i++); ++ curtag = i + 1; ++ } + tagset[seltags] = mask; ++ lt[sellt] = lts[curtag]; ++ mfact = mfacts[curtag]; ++ if (showbar != showbars[curtag]) ++ togglebar(NULL); + arrange(); + } + } +@@ -1644,11 +1678,28 @@ updatewmhints(Client *c) { + + void + view(const Arg *arg) { ++ unsigned int i; + if((arg->ui & TAGMASK) == tagset[seltags]) + return; + seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + tagset[seltags] = arg->ui & TAGMASK; ++ prevtag = curtag; ++ if(arg->ui == ~0) ++ curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ curtag = i + 1; ++ } ++ } else { ++ prevtag= curtag ^ prevtag; ++ curtag^= prevtag; ++ prevtag= curtag ^ prevtag; ++ } ++ lt[sellt]= lts[curtag]; ++ mfact = mfacts[curtag]; ++ if(showbar != showbars[curtag]) ++ togglebar(NULL); + arrange(); + } + diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.6.1.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.6.1.diff @@ -0,0 +1,184 @@ +--- dwm.c 2009-09-18 18:12:50.000000000 +0200 ++++ dwm.c.working 2009-09-18 18:14:04.000000000 +0200 +@@ -131,6 +131,25 @@ + void (*arrange) (Monitor *); + } Layout; + ++struct Monitor { ++ float mfact; ++ int num; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++}; ++ + typedef struct { + const char *class; + const char *instance; +@@ -263,30 +282,6 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + +-struct Monitor { +- float mfact; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +- int curtag; +- int prevtag; +- const Layout *lts[LENGTH(tags) + 1]; +- double mfacts[LENGTH(tags) + 1]; +- Bool showbars[LENGTH(tags) + 1]; +-}; +- + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { + char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; +@@ -1484,7 +1479,7 @@ + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) +- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *) arg->v; ++ selmon->lt[selmon->sellt] = (Layout *) arg->v; + if (selmon->sel) + arrange(); + else +@@ -1502,7 +1497,7 @@ + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.1 || f > 0.9) + return; +- selmon->mfact = selmon->mfacts[selmon->curtag] = f; ++ selmon->mfact = f; + arrange(); + } + +@@ -1512,7 +1507,6 @@ + unsigned int i; + int w; + XSetWindowAttributes wa; +- Monitor *m; + + /* clean up any zombies immediately */ + sigchld(0); +@@ -1547,31 +1541,11 @@ + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if (!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); +- /* init tags */ +- for (m = mons; m; m = m->next) +- m->curtag = m->prevtag = 1; +- /* init mfacts */ +- for (m = mons; m; m = m->next) { +- for (i = 0; i < LENGTH(tags) + 1; i++) { +- m->mfacts[i] = m->mfact; +- } +- } +- /* init layouts */ +- for (m = mons; m; m = m->next) { +- for (i = 0; i < LENGTH(tags) + 1; i++) { +- m->lts[i] = &layouts[0]; +- } +- } + /* init bars */ + for (blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { + w = TEXTW(layouts[i].symbol); + blw = MAX(blw, w); + } +- for (m = mons; m; m = m->next) { +- for (i = 0; i < LENGTH(tags) + 1; i++) { +- m->showbars[i] = m->showbar; +- } +- } + updatebars(); + updatestatus(); + /* EWMH support per view */ +@@ -1689,7 +1663,7 @@ + void + togglebar(const Arg * arg) + { +- selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; ++ selmon->showbar = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(); +@@ -1710,27 +1684,13 @@ + void + toggletag(const Arg * arg) + { +- unsigned int i; + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { +- if (newtags == ~0) { +- selmon->prevtag = selmon->curtag; +- selmon->curtag = 0; +- } +- if (!(newtags & 1 << (selmon->curtag - 1))) { +- selmon->prevtag = selmon->curtag; +- for (i = 0; !(newtags & 1 << i); i++); +- selmon->curtag = i + 1; +- } + selmon->sel->tags = newtags; +- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; +- selmon->mfact = selmon->mfacts[selmon->curtag]; +- if (selmon->showbar != selmon->showbars[selmon->curtag]) +- togglebar(NULL); + arrange(); + } + } +@@ -1993,28 +1953,11 @@ + void + view(const Arg * arg) + { +- unsigned int i; + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if (arg->ui & TAGMASK) { ++ if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; +- selmon->prevtag = selmon->curtag; +- if (arg->ui == ~0) +- selmon->curtag = 0; +- else { +- for (i = 0; !(arg->ui & 1 << i); i++); +- selmon->curtag = i + 1; +- } +- } else { +- selmon->prevtag = selmon->curtag ^ selmon->prevtag; +- selmon->curtag ^= selmon->prevtag; +- selmon->prevtag = selmon->curtag ^ selmon->prevtag; +- } +- selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; +- selmon->mfact = selmon->mfacts[selmon->curtag]; +- if (selmon->showbar != selmon->showbars[selmon->curtag]) +- togglebar(NULL); + arrange(); + } + diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.7.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.7.2.diff @@ -0,0 +1,184 @@ +diff -r 2bcd25cce4ab dwm.c +--- a/dwm.c Sun Sep 27 20:20:14 2009 +0100 ++++ b/dwm.c Tue Oct 20 18:27:52 2009 -0300 +@@ -120,26 +120,6 @@ + void (*arrange)(Monitor *); + } Layout; + +-struct Monitor { +- char ltsymbol[16]; +- float mfact; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +-}; +- + typedef struct { + const char *class; + const char *instance; +@@ -273,6 +253,31 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Monitor { ++ char ltsymbol[16]; ++ float mfact; ++ int num; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++ int curtag; ++ int prevtag; ++ const Layout *lts[LENGTH(tags) + 1]; ++ double mfacts[LENGTH(tags) + 1]; ++ Bool showbars[LENGTH(tags) + 1]; ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -1450,7 +1455,7 @@ + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1468,13 +1473,15 @@ + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->mfacts[selmon->curtag] = f; + arrange(selmon); + } + + void + setup(void) { + XSetWindowAttributes wa; ++ Monitor *m; ++ unsigned int i; + + /* clean up any zombies immediately */ + sigchld(0); +@@ -1509,7 +1516,27 @@ + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); ++ /* init tags */ ++ for(m = mons; m; m = m->next) ++ m->curtag = m->prevtag = 1; ++ /* init mfacts */ ++ for(m = mons; m; m = m->next) { ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ m->mfacts[i] = m->mfact; ++ } ++ } ++ /* init layouts */ ++ for(m = mons; m; m = m->next) { ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ m->lts[i] = &layouts[0]; ++ } ++ } + /* init bars */ ++ for(m = mons; m; m = m->next) { ++ for(i=0; i < LENGTH(tags) + 1; i++) { ++ m->showbars[i] = m->showbar; ++ } ++ } + updatebars(); + updatestatus(); + /* EWMH support per view */ +@@ -1620,7 +1647,7 @@ + + void + togglebar(const Arg *arg) { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1640,12 +1667,27 @@ + void + toggletag(const Arg *arg) { + unsigned int newtags; ++ unsigned int i; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { + selmon->sel->tags = newtags; ++ if(newtags == ~0) { ++ selmon->prevtag = selmon->curtag; ++ selmon->curtag = 0; ++ } ++ if(!(newtags & 1 << (selmon->curtag - 1))) { ++ selmon->prevtag = selmon->curtag; ++ for (i=0; !(newtags & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ selmon->sel->tags = newtags; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if (selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + arrange(selmon); + } + } +@@ -1912,11 +1954,29 @@ + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->prevtag = selmon->curtag; ++ if(arg->ui == ~0) ++ selmon->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ } else { ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ selmon->curtag^= selmon->prevtag; ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ } ++ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if(selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/pertag/dwm-pertag-5.8.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.8.2.diff @@ -0,0 +1,180 @@ +diff --git a/dwm.c b/dwm.c +--- a/dwm.c ++++ b/dwm.c +@@ -122,26 +122,6 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + +-struct Monitor { +- char ltsymbol[16]; +- float mfact; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +-}; +- + typedef struct { + const char *class; + const char *instance; +@@ -278,6 +258,31 @@ static Window root; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Monitor { ++ char ltsymbol[16]; ++ float mfact; ++ int num; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++ int curtag; ++ int prevtag; ++ const Layout *lts[LENGTH(tags) + 1]; ++ double mfacts[LENGTH(tags) + 1]; ++ Bool showbars[LENGTH(tags) + 1]; ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -609,6 +614,7 @@ configurerequest(XEvent *e) { + Monitor * + createmon(void) { + Monitor *m; ++ unsigned int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +@@ -619,6 +625,15 @@ createmon(void) { + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ ++ /* pertag init */ ++ m->curtag = m->prevtag = 1; ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ m->mfacts[i] = mfact; ++ m->lts[i] = &layouts[0]; ++ m->showbars[i] = m->showbar; ++ } ++ + return m; + } + +@@ -1486,7 +1501,7 @@ setlayout(const Arg *arg) { + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1504,7 +1519,7 @@ setmfact(const Arg *arg) { + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->mfacts[selmon->curtag] = f; + arrange(selmon); + } + +@@ -1547,7 +1562,6 @@ setup(void) { + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); +- /* init bars */ + updatebars(); + updatestatus(); + /* EWMH support per view */ +@@ -1658,7 +1672,7 @@ tile(Monitor *m) { + + void + togglebar(const Arg *arg) { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1678,12 +1692,27 @@ togglefloating(const Arg *arg) { + void + toggletag(const Arg *arg) { + unsigned int newtags; ++ unsigned int i; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { + selmon->sel->tags = newtags; ++ if(newtags == ~0) { ++ selmon->prevtag = selmon->curtag; ++ selmon->curtag = 0; ++ } ++ if(!(newtags & 1 << (selmon->curtag - 1))) { ++ selmon->prevtag = selmon->curtag; ++ for (i=0; !(newtags & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ selmon->sel->tags = newtags; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if (selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + arrange(selmon); + } + } +@@ -1950,11 +1979,29 @@ updatewmhints(Client *c) { + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->prevtag = selmon->curtag; ++ if(arg->ui == ~0) ++ selmon->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ } else { ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ selmon->curtag^= selmon->prevtag; ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ } ++ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ if(selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + arrange(selmon); + } + diff --git a/dwm.suckless.org/patches/dwm-pertag-6.0.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-pertag-6.1.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-6.1.diff diff --git a/dwm.suckless.org/patches/pertag/dwm-r1578-pertag.diff b/dwm.suckless.org/patches/pertag/dwm-r1578-pertag.diff @@ -0,0 +1,189 @@ +diff --git a/dwm.c b/dwm.c +--- a/dwm.c ++++ b/dwm.c +@@ -122,27 +122,6 @@ + void (*arrange)(Monitor *); + } Layout; + +-struct Monitor { +- char ltsymbol[16]; +- float mfact; +- int nmaster; +- int num; +- int by; /* bar geometry */ +- int mx, my, mw, mh; /* screen size */ +- int wx, wy, ww, wh; /* window area */ +- unsigned int seltags; +- unsigned int sellt; +- unsigned int tagset[2]; +- Bool showbar; +- Bool topbar; +- Client *clients; +- Client *sel; +- Client *stack; +- Monitor *next; +- Window barwin; +- const Layout *lt[2]; +-}; +- + typedef struct { + const char *class; + const char *instance; +@@ -281,6 +260,33 @@ + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++struct Monitor { ++ char ltsymbol[16]; ++ float mfact; ++ int nmaster; ++ int num; ++ int by; /* bar geometry */ ++ int mx, my, mw, mh; /* screen size */ ++ int wx, wy, ww, wh; /* window area */ ++ unsigned int seltags; ++ unsigned int sellt; ++ unsigned int tagset[2]; ++ Bool showbar; ++ Bool topbar; ++ Client *clients; ++ Client *sel; ++ Client *stack; ++ Monitor *next; ++ Window barwin; ++ const Layout *lt[2]; ++ int curtag; ++ int prevtag; ++ const Layout *lts[LENGTH(tags) + 1]; ++ float mfacts[LENGTH(tags) + 1]; ++ int nmasters[LENGTH(tags) + 1]; ++ Bool showbars[LENGTH(tags) + 1]; ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -661,6 +667,7 @@ + Monitor * + createmon(void) { + Monitor *m; ++ unsigned int i; + + if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); +@@ -672,6 +679,16 @@ + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ ++ /* pertag init */ ++ m->curtag = m->prevtag = 1; ++ for(i=0; i < LENGTH(tags) + 1 ; i++) { ++ m->mfacts[i] = mfact; ++ m->nmasters[i] = nmaster; ++ m->lts[i] = &layouts[0]; ++ m->showbars[i] = m->showbar; ++ } ++ + return m; + } + +@@ -1028,7 +1045,8 @@ + + void + incnmaster(const Arg *arg) { +- selmon->nmaster = MAX(selmon->nmaster + arg->i, 1); ++ selmon->nmasters[selmon->curtag] = MAX(selmon->nmaster + arg->i, 1); ++ selmon->nmaster = selmon->nmasters[selmon->curtag]; + arrange(selmon); + } + +@@ -1515,7 +1533,7 @@ + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if(arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if(selmon->sel) + arrange(selmon); +@@ -1533,7 +1551,7 @@ + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if(f < 0.1 || f > 0.9) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->mfacts[selmon->curtag] = f; + arrange(selmon); + } + +@@ -1680,7 +1698,7 @@ + + void + togglebar(const Arg *arg) { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1699,13 +1717,28 @@ + + void + toggletag(const Arg *arg) { +- unsigned int newtags; ++ unsigned int i, newtags; + + if(!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if(newtags) { + selmon->sel->tags = newtags; ++ if(newtags == ~0) { ++ selmon->prevtag = selmon->curtag; ++ selmon->curtag = 0; ++ } ++ if(!(newtags & 1 << (selmon->curtag - 1))) { ++ selmon->prevtag = selmon->curtag; ++ for (i=0; !(newtags & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ selmon->sel->tags = newtags; ++ selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ selmon->nmaster = selmon->nmasters[selmon->curtag]; ++ if (selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } +@@ -1982,11 +2015,30 @@ + + void + view(const Arg *arg) { ++ unsigned int i; ++ + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ +- if(arg->ui & TAGMASK) ++ if(arg->ui & TAGMASK) { + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->prevtag = selmon->curtag; ++ if(arg->ui == ~0) ++ selmon->curtag = 0; ++ else { ++ for (i=0; !(arg->ui & 1 << i); i++); ++ selmon->curtag = i + 1; ++ } ++ } else { ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ selmon->curtag^= selmon->prevtag; ++ selmon->prevtag= selmon->curtag ^ selmon->prevtag; ++ } ++ selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag]; ++ selmon->mfact = selmon->mfacts[selmon->curtag]; ++ selmon->nmaster = selmon->nmasters[selmon->curtag]; ++ if(selmon->showbar != selmon->showbars[selmon->curtag]) ++ togglebar(NULL); + focus(NULL); + arrange(selmon); + } diff --git a/dwm.suckless.org/patches/pertag/index.md b/dwm.suckless.org/patches/pertag/index.md @@ -0,0 +1,51 @@ +pertag +====== + +Description +----------- +More general approach to [taglayouts patch][1]. This patch keeps layout, +mwfact, barpos and nmaster per tag. + +Download +-------- +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-pertag-20170513-ceac8c9.diff](dwm-pertag-20170513-ceac8c9.diff) + * [dwm-pertag-6.1.diff](dwm-pertag-6.1.diff) (6.4K) (20151109) + * [dwm-git-20120406-pertag.diff](dwm-git-20120406-pertag.diff) (5955b) + * [dwm-pertag-6.0.diff](dwm-pertag-6.0.diff) (5955b) (20120406) + * [dwm-r1578-pertag.diff][9] (nmaster included in mainline) + * [dwm-pertag-5.8.2.diff][7] + * [dwm-pertag-5.7.2.diff][6] + * [dwm-pertag-5.6.1.diff][5] + * [dwm-pertag-5.4.diff][4] + * [dwm-pertag-5.2.diff][3] + * [dwm-pertag-5.1.diff][2] + + * Using pertag but with the same barpos + * [dwm-6.1-pertag_without_bar.diff](dwm-6.1-pertag_without_bar.diff) (5.2K) (20151109) + * [dwm-6.0-pertag_without_bar.diff](dwm-6.0-pertag_without_bar.diff) (5578b) (20140530) + * [dwm-5.8.2-pertag\_without\_bar.diff][8] + +Authors +------- + * 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>` + * Updated by Ivan Tham - `pickfire at riseup dot net` + * [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (Updated to current git) + * Lucas Gabriel Vuotto - <lvuotto92@gmail.com> (git ports) + +[1]: ../historical/taglayouts +[2]: dwm-pertag-5.1.diff +[3]: dwm-pertag-5.2.diff +[4]: dwm-pertag-5.4.diff +[5]: dwm-pertag-5.6.1.diff +[6]: dwm-pertag-5.7.2.diff +[7]: dwm-pertag-5.8.2.diff +[8]: dwm-5.8.2-pertag_without_bar.diff +[9]: dwm-r1578-pertag.diff diff --git a/dwm.suckless.org/patches/push.md b/dwm.suckless.org/patches/push.md @@ -1,32 +0,0 @@ -# push up/down - -## Description - -`pushup` and `pushdown` provide a way to move clients inside the clients list. - - #include "push.c" - - static Key keys[] = { - ... - { MODKEY|ControlMask, XK_j, pushdown, {0} }, - { MODKEY|ControlMask, XK_k, pushup, {0} }, - -`push_no_master` is the same as the regular `push` patch, but it does not push up nor push down into the master area. We have zoom() for that. - -## Download -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-push-20160731-56a31dc.diff](dwm-push-20160731-56a31dc.diff) - * [dwm-push-6.0.diff](dwm-push-6.0.diff) (1332b) - 2012/4/6 - * [dwm-6.0-push_no_master.diff](dwm-6.0-push_no_master.diff) - * [dwm-push-6.1.diff](dwm-push-6.1.diff) (1402b) - 2014/2/9 - * [dwm-6.1-push_no_master.diff](dwm-6.1-push_no_master.diff) - 2015/11/21 - -## Note -This patch seems to be equivalent to the [movestack](movestack) patch. - -## Author - * Unknown? - * Updated by Jan Christoph Ebersbach <jceb@e-jc.de> - * push_no_master by Jente Hidskes <jthidskes@outlook.com> diff --git a/dwm.suckless.org/patches/dwm-6.0-push_no_master.diff b/dwm.suckless.org/patches/push/dwm-6.0-push_no_master.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-push_no_master.diff b/dwm.suckless.org/patches/push/dwm-6.1-push_no_master.diff diff --git a/dwm.suckless.org/patches/dwm-push-20160731-56a31dc.diff b/dwm.suckless.org/patches/push/dwm-push-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-push-6.0.diff b/dwm.suckless.org/patches/push/dwm-push-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-push-6.1.diff b/dwm.suckless.org/patches/push/dwm-push-6.1.diff diff --git a/dwm.suckless.org/patches/push/index.md b/dwm.suckless.org/patches/push/index.md @@ -0,0 +1,32 @@ +# push up/down + +## Description + +`pushup` and `pushdown` provide a way to move clients inside the clients list. + + #include "push.c" + + static Key keys[] = { + ... + { MODKEY|ControlMask, XK_j, pushdown, {0} }, + { MODKEY|ControlMask, XK_k, pushup, {0} }, + +`push_no_master` is the same as the regular `push` patch, but it does not push up nor push down into the master area. We have zoom() for that. + +## Download +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-push-20160731-56a31dc.diff](dwm-push-20160731-56a31dc.diff) + * [dwm-push-6.0.diff](dwm-push-6.0.diff) (1332b) - 2012/4/6 + * [dwm-6.0-push_no_master.diff](dwm-6.0-push_no_master.diff) + * [dwm-push-6.1.diff](dwm-push-6.1.diff) (1402b) - 2014/2/9 + * [dwm-6.1-push_no_master.diff](dwm-6.1-push_no_master.diff) - 2015/11/21 + +## Note +This patch seems to be equivalent to the [movestack](movestack) patch. + +## Author + * Unknown? + * Updated by Jan Christoph Ebersbach <jceb@e-jc.de> + * push_no_master by Jente Hidskes <jthidskes@outlook.com> diff --git a/dwm.suckless.org/patches/pwkl.md b/dwm.suckless.org/patches/pwkl.md @@ -1,23 +0,0 @@ -Per-window keyboard layout -========================== - -Description ------------ -Basically, this patch implements per-window keyboard layout support in dwm. -It makes dwm remember current keyboard layout when a window is unfocused, -and restore it back when that window is focused again. - -Notes ------------ -Andreas Amann pointed out that "you cannot switch between tags per mouse -if an alternate layout is activated". He kindly created a patch that fixes -this: [see ml](//lists.suckless.org/dev/1010/6195.html). - -Download --------- -* [dwm-pwkl-5.9.diff](dwm-pwkl-5.9.diff) (1.4K) (20101013) -* [dwm-pwkl-6.1.diff](dwm-pwkl-6.1.diff) (1.5K) (20170128) - -Author ------- -* Evgeny Grablyk - <evgeny.grablyk@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-pwkl-5.9.diff b/dwm.suckless.org/patches/pwkl/dwm-pwkl-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-pwkl-6.1.diff b/dwm.suckless.org/patches/pwkl/dwm-pwkl-6.1.diff diff --git a/dwm.suckless.org/patches/pwkl/index.md b/dwm.suckless.org/patches/pwkl/index.md @@ -0,0 +1,23 @@ +Per-window keyboard layout +========================== + +Description +----------- +Basically, this patch implements per-window keyboard layout support in dwm. +It makes dwm remember current keyboard layout when a window is unfocused, +and restore it back when that window is focused again. + +Notes +----------- +Andreas Amann pointed out that "you cannot switch between tags per mouse +if an alternate layout is activated". He kindly created a patch that fixes +this: [see ml](//lists.suckless.org/dev/1010/6195.html). + +Download +-------- +* [dwm-pwkl-5.9.diff](dwm-pwkl-5.9.diff) (1.4K) (20101013) +* [dwm-pwkl-6.1.diff](dwm-pwkl-6.1.diff) (1.5K) (20170128) + +Author +------ +* Evgeny Grablyk - <evgeny.grablyk@gmail.com> diff --git a/dwm.suckless.org/patches/resizecorners.md b/dwm.suckless.org/patches/resizecorners.md @@ -1,15 +0,0 @@ -# resizecorners - -## Description - -By default, windows only from the bottom right corner. With this Patch, the mouse is warped to the nearest corner and you resize from there. - -## Download - - * [dwm-resizecorners-6.1.diff](dwm-resizecorners-6.1.diff) (17.02.2016) - * [dwm-resizecorners-6.0.diff](dwm-resizecorners-6.0.diff) (12.05.2015) - -## Author - - * dusty - <dusty@teknik.io> - * Klemens Nanni <[kl3@posteo.org](mailto:kl3@posteo.org)> (6.1 version) diff --git a/dwm.suckless.org/patches/dwm-resizecorners-6.0.diff b/dwm.suckless.org/patches/resizecorners/dwm-resizecorners-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-resizecorners-6.1.diff b/dwm.suckless.org/patches/resizecorners/dwm-resizecorners-6.1.diff diff --git a/dwm.suckless.org/patches/resizecorners/index.md b/dwm.suckless.org/patches/resizecorners/index.md @@ -0,0 +1,15 @@ +# resizecorners + +## Description + +By default, windows only from the bottom right corner. With this Patch, the mouse is warped to the nearest corner and you resize from there. + +## Download + + * [dwm-resizecorners-6.1.diff](dwm-resizecorners-6.1.diff) (17.02.2016) + * [dwm-resizecorners-6.0.diff](dwm-resizecorners-6.0.diff) (12.05.2015) + +## Author + + * dusty - <dusty@teknik.io> + * Klemens Nanni <[kl3@posteo.org](mailto:kl3@posteo.org)> (6.1 version) diff --git a/dwm.suckless.org/patches/rmaster.md b/dwm.suckless.org/patches/rmaster.md @@ -1,21 +0,0 @@ -# rmaster - -## Description - -Toggling between left-master (original behaviour) and right-master for the -current monitor. - -This patch only modifies the deafult layout 'tile', similar modifications can be -made to other custom layouts, like 'deck'. - -## Configuration - - /*config.h*/ - { MODKEY, XK_i, togglermaster, {0} }, - -## Download - -* [dwm-rmaster-6.1.diff](dwm-rmaster-6.1.diff) (1836b) (20170213) - -## Author -* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/dwm-rmaster-6.1.diff b/dwm.suckless.org/patches/rmaster/dwm-rmaster-6.1.diff diff --git a/dwm.suckless.org/patches/rmaster/index.md b/dwm.suckless.org/patches/rmaster/index.md @@ -0,0 +1,21 @@ +# rmaster + +## Description + +Toggling between left-master (original behaviour) and right-master for the +current monitor. + +This patch only modifies the deafult layout 'tile', similar modifications can be +made to other custom layouts, like 'deck'. + +## Configuration + + /*config.h*/ + { MODKEY, XK_i, togglermaster, {0} }, + +## Download + +* [dwm-rmaster-6.1.diff](dwm-rmaster-6.1.diff) (1836b) (20170213) + +## Author +* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/rotatestack.md b/dwm.suckless.org/patches/rotatestack.md @@ -1,24 +0,0 @@ - -Rotate stack -============ - -Description ------------ - -Stack rotation moves a client from the bottom to the top of the stack -(or the other way round). This effectively rotates the clients by one -position clockwise (or CCW, respectively). - -It should play well with arbitrary stack layouts and nmaster values. - -One may think of it as moving the zoom through the list of clients, very -much in the same way as scrolling moves the view port around a pane. - - -Download --------- -* [dwm-rotatestack-20161021-ab9571b.diff](dwm-rotatestack-20161021-ab9571b.diff) - -Author ------- -* ssd@mailless.org diff --git a/dwm.suckless.org/patches/dwm-rotatestack-20161021-ab9571b.diff b/dwm.suckless.org/patches/rotatestack/dwm-rotatestack-20161021-ab9571b.diff diff --git a/dwm.suckless.org/patches/rotatestack/index.md b/dwm.suckless.org/patches/rotatestack/index.md @@ -0,0 +1,24 @@ + +Rotate stack +============ + +Description +----------- + +Stack rotation moves a client from the bottom to the top of the stack +(or the other way round). This effectively rotates the clients by one +position clockwise (or CCW, respectively). + +It should play well with arbitrary stack layouts and nmaster values. + +One may think of it as moving the zoom through the list of clients, very +much in the same way as scrolling moves the view port around a pane. + + +Download +-------- +* [dwm-rotatestack-20161021-ab9571b.diff](dwm-rotatestack-20161021-ab9571b.diff) + +Author +------ +* ssd@mailless.org diff --git a/dwm.suckless.org/patches/runorraise.md b/dwm.suckless.org/patches/runorraise.md @@ -1,35 +0,0 @@ -runorraise -========== - -Description ------------ -This patch adds a equivalent to stumpwm's [run-or-raise] action for DWM. - -The idea is to have each frequently-used application one key combination away at all times, irrespective of which workspace it is on, -or how recently it has been used, or even whether it’s running or not. - -Usage ------ - -1 In your config.h: - - static const char *emacs[] = { "emacsclient", "-c", NULL, NULL, "Emacs" }; - static const char *browser[] = { "firefox", NULL, NULL, NULL, "Firefox" }; - -2 In your keybindings add something like: - - { Modkey, XK_e, runorraise, {.v = emacs } }, - { Modkey, XK_f, runorraise, {.v = firefox } }, - -Download --------- - -* [dwm-6.1-runorraise.diff](dwm-6.1-runorraise.diff) - -Authors -------- -* Quentin Stievenart (acieroid) - `<quentin.stievenart at gmail dot com>` - -Contributors ------------- -* Ivaylo Kuzev (ivoarch) - `<ivkuzev at gmail dot com>` diff --git a/dwm.suckless.org/patches/dwm-6.1-runorraise.diff b/dwm.suckless.org/patches/runorraise/dwm-6.1-runorraise.diff diff --git a/dwm.suckless.org/patches/runorraise/index.md b/dwm.suckless.org/patches/runorraise/index.md @@ -0,0 +1,35 @@ +runorraise +========== + +Description +----------- +This patch adds a equivalent to stumpwm's [run-or-raise] action for DWM. + +The idea is to have each frequently-used application one key combination away at all times, irrespective of which workspace it is on, +or how recently it has been used, or even whether it’s running or not. + +Usage +----- + +1 In your config.h: + + static const char *emacs[] = { "emacsclient", "-c", NULL, NULL, "Emacs" }; + static const char *browser[] = { "firefox", NULL, NULL, NULL, "Firefox" }; + +2 In your keybindings add something like: + + { Modkey, XK_e, runorraise, {.v = emacs } }, + { Modkey, XK_f, runorraise, {.v = firefox } }, + +Download +-------- + +* [dwm-6.1-runorraise.diff](dwm-6.1-runorraise.diff) + +Authors +------- +* Quentin Stievenart (acieroid) - `<quentin.stievenart at gmail dot com>` + +Contributors +------------ +* Ivaylo Kuzev (ivoarch) - `<ivkuzev at gmail dot com>` diff --git a/dwm.suckless.org/patches/save_floats.md b/dwm.suckless.org/patches/save_floats.md @@ -1,20 +0,0 @@ -# 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. - -## Download ## -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-savefloats-20160723-56a31dc.diff](dwm-savefloats-20160723-56a31dc.diff) (1452b) - * [dwm-6.1-save_floats.diff](dwm-6.1-save_floats.diff) (1605b) (20140209) - * [dwm-10e232f9ace7-save_floats.diff](dwm-10e232f9ace7-save_floats.diff) (1604b) (20120406) - * [dwm-save_floats-6.0.diff](dwm-save_floats-6.0.diff) (1528b) (20120406) - -## Author ## - * http://nymu.net/patches - * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> - * Ivan Tham <pickfire@riseup.net> (git port) diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff b/dwm.suckless.org/patches/save_floats/dwm-10e232f9ace7-save_floats.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-save_floats.diff b/dwm.suckless.org/patches/save_floats/dwm-6.1-save_floats.diff diff --git a/dwm.suckless.org/patches/dwm-save_floats-6.0.diff b/dwm.suckless.org/patches/save_floats/dwm-save_floats-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-savefloats-20160723-56a31dc.diff b/dwm.suckless.org/patches/save_floats/dwm-savefloats-20160723-56a31dc.diff diff --git a/dwm.suckless.org/patches/save_floats/index.md b/dwm.suckless.org/patches/save_floats/index.md @@ -0,0 +1,20 @@ +# 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. + +## Download ## +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-savefloats-20160723-56a31dc.diff](dwm-savefloats-20160723-56a31dc.diff) (1452b) + * [dwm-6.1-save_floats.diff](dwm-6.1-save_floats.diff) (1605b) (20140209) + * [dwm-10e232f9ace7-save_floats.diff](dwm-10e232f9ace7-save_floats.diff) (1604b) (20120406) + * [dwm-save_floats-6.0.diff](dwm-save_floats-6.0.diff) (1528b) (20120406) + +## Author ## + * http://nymu.net/patches + * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> + * Ivan Tham <pickfire@riseup.net> (git port) diff --git a/dwm.suckless.org/patches/schemeSwitch.md b/dwm.suckless.org/patches/schemeSwitch.md @@ -1,31 +0,0 @@ -schemeSwitch -===== - -Description ------------ - -[Solarized](http://ethanschoonover.com/solarized) is a color scheme by Ethan -Schoonover which exists in a dark and a light variant. - -This patch allows you defining more then one color-Scheme in the colors array in -config.def.h (or config.h) and cycle through the schemes by schemeCycle() function -(bound to Mod+Shift+z) and toggle between corresponding light and dark schemes -with schemeToggle() function (bound to Mod+Shift+t). - -In the example config.def.h there are first defined the colors for the dark variant of -solarized theme, after that the colors for the light variant, and then the original dwm -colorscheme, wich has no corresponding light scheme. If the last one is selected -shemeToggle() will do nothing, but one can cycle to the dark scheme (or the light one) -and then toggle between light and dark. If there where colors defined after the original -scheme, then schemeToggle() would toggle between original and the consecutive. - - -Download --------- - * [dwm-schemeSwitch-20170804-ceac8c9.diff](dwm-schemeSwitch-20170804-ceac8c9.diff) - - -Authors -------- - - * Aaron Strahlberger - <aaron.strahlberger@posteo.de> diff --git a/dwm.suckless.org/patches/dwm-schemeSwitch-20170804-ceac8c9.diff b/dwm.suckless.org/patches/scheme_switch/dwm-scheme_switch-20170804-ceac8c9.diff diff --git a/dwm.suckless.org/patches/scheme_switch/index.md b/dwm.suckless.org/patches/scheme_switch/index.md @@ -0,0 +1,31 @@ +schemeSwitch +===== + +Description +----------- + +[Solarized](http://ethanschoonover.com/solarized) is a color scheme by Ethan +Schoonover which exists in a dark and a light variant. + +This patch allows you defining more then one color-Scheme in the colors array in +config.def.h (or config.h) and cycle through the schemes by schemeCycle() function +(bound to Mod+Shift+z) and toggle between corresponding light and dark schemes +with schemeToggle() function (bound to Mod+Shift+t). + +In the example config.def.h there are first defined the colors for the dark variant of +solarized theme, after that the colors for the light variant, and then the original dwm +colorscheme, wich has no corresponding light scheme. If the last one is selected +shemeToggle() will do nothing, but one can cycle to the dark scheme (or the light one) +and then toggle between light and dark. If there where colors defined after the original +scheme, then schemeToggle() would toggle between original and the consecutive. + + +Download +-------- + * [dwm-scheme_switch-20170804-ceac8c9.diff](dwm-scheme_switch-20170804-ceac8c9.diff) + + +Authors +------- + + * Aaron Strahlberger - <aaron.strahlberger@posteo.de> diff --git a/dwm.suckless.org/patches/scratchpad.md b/dwm.suckless.org/patches/scratchpad.md @@ -1,24 +0,0 @@ -scratchpad -========== - -Description ------------ - -The scratchpad patch allows you to spawn or restore a floating terminal -window. It is usually useful to have one to do some short typing. - -A tool like detach (http://detach.sourceforge.net) turns it into a -launchpad for X applications. - -By default your terminal (st) is used, and the default key binding is -`MODKEY+XK_grave`. A `config.def.h` change is included in the patch. - -Download --------- - -* [dwm-scratchpad-20170207-bb3bd6f.diff](dwm-scratchpad-20170207-bb3bd6f.diff) - -Author ------- - -* Ivan J. <parazyd@dyne.org> diff --git a/dwm.suckless.org/patches/dwm-scratchpad-20170207-bb3bd6f.diff b/dwm.suckless.org/patches/scratchpad/dwm-scratchpad-20170207-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/scratchpad/index.md b/dwm.suckless.org/patches/scratchpad/index.md @@ -0,0 +1,24 @@ +scratchpad +========== + +Description +----------- + +The scratchpad patch allows you to spawn or restore a floating terminal +window. It is usually useful to have one to do some short typing. + +A tool like detach (http://detach.sourceforge.net) turns it into a +launchpad for X applications. + +By default your terminal (st) is used, and the default key binding is +`MODKEY+XK_grave`. A `config.def.h` change is included in the patch. + +Download +-------- + +* [dwm-scratchpad-20170207-bb3bd6f.diff](dwm-scratchpad-20170207-bb3bd6f.diff) + +Author +------ + +* Ivan J. <parazyd@dyne.org> diff --git a/dwm.suckless.org/patches/selfrestart.md b/dwm.suckless.org/patches/selfrestart.md @@ -1,15 +0,0 @@ -selfrestart -=========== - -Description ------------ -Restart dwm without the unnecessary dependency of an external script. - -Download --------- - * [dwm-r1615-selfrestart.diff](dwm-r1615-selfrestart.diff) - -Implementation & idea ---------------------- - * Idea belongs to: [Yu-Jie Lin](https://sites.google.com/site/yjlnotes/notes/dwm) - * The simplified implementation: Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-r1615-selfrestart.diff b/dwm.suckless.org/patches/selfrestart/dwm-r1615-selfrestart.diff diff --git a/dwm.suckless.org/patches/selfrestart/index.md b/dwm.suckless.org/patches/selfrestart/index.md @@ -0,0 +1,15 @@ +selfrestart +=========== + +Description +----------- +Restart dwm without the unnecessary dependency of an external script. + +Download +-------- + * [dwm-r1615-selfrestart.diff](dwm-r1615-selfrestart.diff) + +Implementation & idea +--------------------- + * Idea belongs to: [Yu-Jie Lin](https://sites.google.com/site/yjlnotes/notes/dwm) + * The simplified implementation: Barbu Paul - Gheorghe <barbu.paul.gheorghe@gmail.com> diff --git a/dwm.suckless.org/patches/single_tagset.md b/dwm.suckless.org/patches/single_tagset.md @@ -1,53 +0,0 @@ -single tagset -============= - -Description ------------ - -This patch addresses the multi-monitor setup. Instead of having separate tags -for every monitor there is just one list of tags for all monitors. Instead of -moving windows from one monitor to the other, the desired tag from the -other monitor can just be selected and all windows will be drawn on the -current monitor. - -Several deep changes needed to be made: -1. Macro ISVISIBLE expects a second parameter, the monitor -2. Monitor->clients and Monitor->stack were moved to the global variable - Clientlist cl. All monitors refer to this one list. -3. A new method attachclients was added. When changing between tags this - function ensures that all clients are pointing to the right monitor. - -Download --------- -Please be aware that this patch probably breaks any other patch! - -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-single_tagset-20160731-56a31dc.diff](dwm-single_tagset-20160731-56a31dc.diff) - * [dwm-6.1-single_tagset.diff](dwm-6.1-single_tagset.diff) (16634b) (20140209) - * [dwm-10e232f9ace7-single_tagset.diff](dwm-10e232f9ace7-single_tagset.diff) (14748b) (20120406) - * [dwm-single_tagset-6.0.diff](dwm-single_tagset-6.0.diff) (14417b) (20120406) - -Special Version ---------------- -This is a special version of the patch that was created with following patches being applied: - - * [attachabove](attachabove) - * [float_border_color](float_border_color) - * [focusmaster](https://raw.github.com/jceb/dwm-patches/master/patches/focusmaster.patch) - * [moveresize](moveresize) - * [noborder](noborder) - * [pertag](pertag) - * [push](push) - * [save_floats](save_floats) - * [statusallmons](statusallmons) - * [swapfocus](swapfocus) - * [tagall](tagall) - * [zoomswap](zoomswap) - -[dwm-6.1-single_tagset_all.diff](https://raw.github.com/jceb/dwm-patches/master/patches/single_tagset_all.patch) - -Authors -------- - * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff b/dwm.suckless.org/patches/single_tagset/dwm-10e232f9ace7-single_tagset.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-single_tagset.diff b/dwm.suckless.org/patches/single_tagset/dwm-6.1-single_tagset.diff diff --git a/dwm.suckless.org/patches/dwm-single_tagset-20160731-56a31dc.diff b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-single_tagset-6.0.diff b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.0.diff diff --git a/dwm.suckless.org/patches/single_tagset/index.md b/dwm.suckless.org/patches/single_tagset/index.md @@ -0,0 +1,34 @@ +single tagset +============= + +Description +----------- + +This patch addresses the multi-monitor setup. Instead of having separate tags +for every monitor there is just one list of tags for all monitors. Instead of +moving windows from one monitor to the other, the desired tag from the +other monitor can just be selected and all windows will be drawn on the +current monitor. + +Several deep changes needed to be made: +1. Macro ISVISIBLE expects a second parameter, the monitor +2. Monitor->clients and Monitor->stack were moved to the global variable + Clientlist cl. All monitors refer to this one list. +3. A new method attachclients was added. When changing between tags this + function ensures that all clients are pointing to the right monitor. + +Download +-------- +Please be aware that this patch probably breaks any other patch! + +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-single_tagset-20160731-56a31dc.diff](dwm-single_tagset-20160731-56a31dc.diff) + * [dwm-6.1-single_tagset.diff](dwm-6.1-single_tagset.diff) (16634b) (20140209) + * [dwm-10e232f9ace7-single_tagset.diff](dwm-10e232f9ace7-single_tagset.diff) (14748b) (20120406) + * [dwm-single_tagset-6.0.diff](dwm-single_tagset-6.0.diff) (14417b) (20120406) + +Authors +------- + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/singularborders.md b/dwm.suckless.org/patches/singularborders.md @@ -1,43 +0,0 @@ -\singular borders -=========== - -Description ------------ -`singular borders` changes the way DWM handles the borders. Firsty, borders against the left, bottom and right screen edges are removed (they are placed off-screen) and secondly, borders between clients now overlap eachother. - - - Original behaviour : - +-----------------+--------+ - | || | - | || S1 | - | || | - | M |+=======| - | || | - | || S2 | - | || | - +-----------------+--------+ - - - New Behaviour : - +-----------------+--------+ - | - | S1 - | - M +--------+ - | - | S2 - | - + + + - -Issues ------- -* In a multi-monitor setup, you will see monitor one's borders on monitor two and vice-versa. This is because the borders on screen edges are simply placed off-screen. - -Download --------- -* [dwm-6.0-singularborders.diff](dwm-6.0-singularborders.diff) -* [dwm-6.0-singularborders_bstack.diff](dwm-6.0-singularborders_bstack.diff) - -Author ------- -* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/dwm-6.0-singularborders.diff b/dwm.suckless.org/patches/singularborders/dwm-6.0-singularborders.diff diff --git a/dwm.suckless.org/patches/dwm-6.0-singularborders_bstack.diff b/dwm.suckless.org/patches/singularborders/dwm-6.0-singularborders_bstack.diff diff --git a/dwm.suckless.org/patches/singularborders/index.md b/dwm.suckless.org/patches/singularborders/index.md @@ -0,0 +1,43 @@ +singular borders +================ + +Description +----------- +`singular borders` changes the way DWM handles the borders. Firsty, borders against the left, bottom and right screen edges are removed (they are placed off-screen) and secondly, borders between clients now overlap eachother. + + + Original behaviour : + +-----------------+--------+ + | || | + | || S1 | + | || | + | M |+=======| + | || | + | || S2 | + | || | + +-----------------+--------+ + + + New Behaviour : + +-----------------+--------+ + | + | S1 + | + M +--------+ + | + | S2 + | + + + + + +Issues +------ +* In a multi-monitor setup, you will see monitor one's borders on monitor two and vice-versa. This is because the borders on screen edges are simply placed off-screen. + +Download +-------- +* [dwm-6.0-singularborders.diff](dwm-6.0-singularborders.diff) +* [dwm-6.0-singularborders_bstack.diff](dwm-6.0-singularborders_bstack.diff) + +Author +------ +* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/sizehints.md b/dwm.suckless.org/patches/sizehints.md @@ -1,19 +0,0 @@ -# obey all sizehints - -## Description - -This patch makes dwm obey even "soft" sizehints for new clients. -Any window that requests a specific initial size will be floated and set to that size. -Unlike with "fixed size" windows, you are able to resize and/or unfloat these windows freely - only the initial state is affected. - -This patch is honestly of limited utility since there are many clients that will abuse it. - -There is no configuration for this patch. - -## Download - - * [dwm-sizehints-5.7.2.diff](dwm-sizehints-5.7.2.diff) (695B) (20091221) - -## Author - - * Ray Kohler - ataraxia937 gmail com diff --git a/dwm.suckless.org/patches/dwm-sizehints-5.7.2.diff b/dwm.suckless.org/patches/sizehints/dwm-sizehints-5.7.2.diff diff --git a/dwm.suckless.org/patches/sizehints/index.md b/dwm.suckless.org/patches/sizehints/index.md @@ -0,0 +1,19 @@ +# obey all sizehints + +## Description + +This patch makes dwm obey even "soft" sizehints for new clients. +Any window that requests a specific initial size will be floated and set to that size. +Unlike with "fixed size" windows, you are able to resize and/or unfloat these windows freely - only the initial state is affected. + +This patch is honestly of limited utility since there are many clients that will abuse it. + +There is no configuration for this patch. + +## Download + + * [dwm-sizehints-5.7.2.diff](dwm-sizehints-5.7.2.diff) (695B) (20091221) + +## Author + + * Ray Kohler - ataraxia937 gmail com diff --git a/dwm.suckless.org/patches/spawn_cwd.md b/dwm.suckless.org/patches/spawn_cwd.md @@ -1,16 +0,0 @@ -# spawn_cwd - -## Description - -Spawns programs from currently focused client's working directory. See this -[blog post](http://snk.tuxfamily.org/log/dwm-spawn-cwd-patch.html) and this -[announcement thread](http://thread.gmane.org/gmane.comp.misc.suckless/7959) -for more information. - -## Download - - * [spawn_cwd.diff](dwm-5.9.1-spawn_cwd.diff) spawn_cwd.diff (2011-11-25) - -## Author - - * Suraj N. Kurapati - <sunaku@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-5.9.1-spawn_cwd.diff b/dwm.suckless.org/patches/spawn_cwd/dwm-5.9.1-spawn_cwd.diff diff --git a/dwm.suckless.org/patches/spawn_cwd/index.md b/dwm.suckless.org/patches/spawn_cwd/index.md @@ -0,0 +1,16 @@ +# spawn_cwd + +## Description + +Spawns programs from currently focused client's working directory. See this +[blog post](http://snk.tuxfamily.org/log/dwm-spawn-cwd-patch.html) and this +[announcement thread](http://thread.gmane.org/gmane.comp.misc.suckless/7959) +for more information. + +## Download + + * [dwm-5.9.1-spawn_cwd.diff](dwm-5.9.1-spawn_cwd.diff) + +## Author + + * Suraj N. Kurapati - <sunaku@gmail.com> diff --git a/dwm.suckless.org/patches/stacker.md b/dwm.suckless.org/patches/stacker.md @@ -1,61 +0,0 @@ -Stacker -======= - -Description ------------ - -This patch provides comprehensive utilities for managing the client stack. It implements -two new commands: `focusstack` (which is a replacement for the original `focusstack` -command) and `pushstack`. The first one is for focusing clients while the second one moves -clients around the stack. Both commands take the same kind of argument: - -* Pass `PREVSEL` to focus/push the previously selected client in the current tagset. - -* Pass `INC(+/-inc)` to focus/push relatively to the selected client. This will wrap - around the stack limits. - -* Pass a positive number to focus/push relatively to the beginning of the stack. Out of - limit values will be truncated to the position of the last visible client and won't wrap - around. - -* Pass a negative number to focus/push relatively to the last visible client in the stack. - Here -1 means the last client, -2 the previous to last client, etc. Out of limit values - will be truncated to the position of the first visible client (0) and won't wrap - around. - -Default key bindings --------------------- - -There are two parallel sets of bindings: one for the `focus*` family and the other for the -`push*` family. The keys are the same for both sets but they do differ in the modifiers: -simply `MODKEY` for the `focus*` family and `MODKEY|ShiftMask` for the `push*` family. - - Key | Argument | Description -:------:|:-----------:|----------------------- - \` | `PREVSEL` | Previously selected - `j` | `INC(+1)` | Next to selected - `k` | `INC(-1)` | Previous to selected - `q` | `0` | First position - `a` | `1` | Second position - `z` | `2` | Third position - `x` | `-1` | Last position - -The `q`, `a`, `z` keys are aligned more or less vertically in the us keyboard layout. They -are intended to be used as quick positional shortcuts to specific applications. So if you -have 9 tags you get 9\*3=27 shortcuts in a two-level hierarchy of clients. The \` key is -above the `Tab` key and it's intended to complement the "move to previously selected -tag" function of dwm at the intra-tag level. Finally, the `x` key is like "I don't care so -much about you just right now but you can still live in this tag". - -Notice that `MODKEY|ShiftMask+q` collides with the default binding for quitting dwm, which -stacker changes to `MODKEY|ShiftMask+BackSpace`. - -Download --------- - -* [dwm-stacker-6.0.diff](dwm-stacker-6.0.diff) - -Author ------- - -* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-stacker-6.0.diff b/dwm.suckless.org/patches/stacker/dwm-stacker-6.0.diff diff --git a/dwm.suckless.org/patches/stacker/index.md b/dwm.suckless.org/patches/stacker/index.md @@ -0,0 +1,61 @@ +stacker +======= + +Description +----------- + +This patch provides comprehensive utilities for managing the client stack. It implements +two new commands: `focusstack` (which is a replacement for the original `focusstack` +command) and `pushstack`. The first one is for focusing clients while the second one moves +clients around the stack. Both commands take the same kind of argument: + +* Pass `PREVSEL` to focus/push the previously selected client in the current tagset. + +* Pass `INC(+/-inc)` to focus/push relatively to the selected client. This will wrap + around the stack limits. + +* Pass a positive number to focus/push relatively to the beginning of the stack. Out of + limit values will be truncated to the position of the last visible client and won't wrap + around. + +* Pass a negative number to focus/push relatively to the last visible client in the stack. + Here -1 means the last client, -2 the previous to last client, etc. Out of limit values + will be truncated to the position of the first visible client (0) and won't wrap + around. + +Default key bindings +-------------------- + +There are two parallel sets of bindings: one for the `focus*` family and the other for the +`push*` family. The keys are the same for both sets but they do differ in the modifiers: +simply `MODKEY` for the `focus*` family and `MODKEY|ShiftMask` for the `push*` family. + + Key | Argument | Description +:------:|:-----------:|----------------------- + \` | `PREVSEL` | Previously selected + `j` | `INC(+1)` | Next to selected + `k` | `INC(-1)` | Previous to selected + `q` | `0` | First position + `a` | `1` | Second position + `z` | `2` | Third position + `x` | `-1` | Last position + +The `q`, `a`, `z` keys are aligned more or less vertically in the us keyboard layout. They +are intended to be used as quick positional shortcuts to specific applications. So if you +have 9 tags you get 9\*3=27 shortcuts in a two-level hierarchy of clients. The \` key is +above the `Tab` key and it's intended to complement the "move to previously selected +tag" function of dwm at the intra-tag level. Finally, the `x` key is like "I don't care so +much about you just right now but you can still live in this tag". + +Notice that `MODKEY|ShiftMask+q` collides with the default binding for quitting dwm, which +stacker changes to `MODKEY|ShiftMask+BackSpace`. + +Download +-------- + +* [dwm-stacker-6.0.diff](dwm-stacker-6.0.diff) + +Author +------ + +* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/stackmfact.md b/dwm.suckless.org/patches/stackmfact.md @@ -1,38 +0,0 @@ -\stackmfact -=========== - -Description ------------ -`stackmfact` enables you to vertically resize clients in the stack, like the regular mfact enables you to horizontally resize the master client(s). - - - smfact 0.00 (original behaviour): - +-----------------+-------+ - | | | - | | S1 | - | | | - | M +=======| - | | | - | | S2 | - | | | - +-----------------+-------+ - - - smfact > 0.00 (new behaviour): - +-----------------+-------+ - | | S1 | - | +=======+ - | | | - | M | | - | | | - | | S2 | - | | | - +-----------------+-------+ - -Download --------- -* [dwm-6.0-smfact.diff](dwm-6.0-smfact.diff) - -Author ------- -* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/dwm-6.0-smfact.diff b/dwm.suckless.org/patches/stackmfact/dwm-6.0-smfact.diff diff --git a/dwm.suckless.org/patches/stackmfact/index.md b/dwm.suckless.org/patches/stackmfact/index.md @@ -0,0 +1,38 @@ +\stackmfact +=========== + +Description +----------- +`stackmfact` enables you to vertically resize clients in the stack, like the regular mfact enables you to horizontally resize the master client(s). + + + smfact 0.00 (original behaviour): + +-----------------+-------+ + | | | + | | S1 | + | | | + | M +=======| + | | | + | | S2 | + | | | + +-----------------+-------+ + + + smfact > 0.00 (new behaviour): + +-----------------+-------+ + | | S1 | + | +=======+ + | | | + | M | | + | | | + | | S2 | + | | | + +-----------------+-------+ + +Download +-------- +* [dwm-6.0-smfact.diff](dwm-6.0-smfact.diff) + +Author +------ +* Jente Hidskes - `<jthidskes at outlook dot com>` diff --git a/dwm.suckless.org/patches/status2d.md b/dwm.suckless.org/patches/status2d.md @@ -1,36 +0,0 @@ -Status2d -======== - -Description ------------ -Status2d allows colors and rectangle drawing in your DWM status bar. -See below an example of my status bar with multi-cpu and battery. - - - -Download --------- - - * [https://github.com/sipi/dwm-status2d](https://github.com/sipi/dwm-status2d) (last updated : march 2015) - * [dwm-status2d-20161231-bb3bd6f.diff](dwm-status2d-20161231-bb3bd6f.diff) - - -Usage ------ -* ^rx,y,w,h^ : draw a rectangle. - -* ^c#FF0000^ : set foreground color. - -* ^f11^ : forward the x draawing cursor, only needed for drawings, not text. - -* ^d^ : reset foreground color to SchemeNorm. - -Example -------- -xsetroot -name "dwmstatus ^c#FF0000^ in red with red rectangle ^r0,0,10,10^^f10^^c#FFFFFF^ and white text" - -Authors -------- - * [sipi](https://github.com/sipi) - * lhark - <lhark@ntymail.com> (bb3bd6f port) - diff --git a/dwm.suckless.org/patches/status2d.png b/dwm.suckless.org/patches/status2d.png Binary files differ. diff --git a/dwm.suckless.org/patches/dwm-status2d-20161231-bb3bd6f.diff b/dwm.suckless.org/patches/status2d/dwm-status2d-20161231-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/status2d/index.md b/dwm.suckless.org/patches/status2d/index.md @@ -0,0 +1,35 @@ +status2d +======== + +Description +----------- +Status2d allows colors and rectangle drawing in your DWM status bar. +See below an example of my status bar with multi-cpu and battery. + + + +Download +-------- + + * [dwm-status2d-20161231-bb3bd6f.diff](dwm-status2d-20161231-bb3bd6f.diff) + + +Usage +----- +* ^rx,y,w,h^ : draw a rectangle. + +* ^c#FF0000^ : set foreground color. + +* ^f11^ : forward the x draawing cursor, only needed for drawings, not text. + +* ^d^ : reset foreground color to SchemeNorm. + +Example +------- +xsetroot -name "dwmstatus ^c#FF0000^ in red with red rectangle ^r0,0,10,10^^f10^^c#FFFFFF^ and white text" + +Authors +------- + * [sipi](https://github.com/sipi) + * lhark - <lhark@ntymail.com> (bb3bd6f port) + diff --git a/dwm.suckless.org/patches/status2d/status2d.png b/dwm.suckless.org/patches/status2d/status2d.png Binary files differ. diff --git a/dwm.suckless.org/patches/statusallmons.md b/dwm.suckless.org/patches/statusallmons.md @@ -1,22 +0,0 @@ -statusbar on all monitors -========================= - -Description ------------ -This patch draws and updates the statusbar on all monitors. - -Download --------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-statusallmons-20160731-56a31dc.diff](dwm-statusallmons-20160731-56a31dc.diff) - * [dwm-6.1-statusallmons.diff](dwm-6.1-statusallmons.diff) (1026b) (20140209) - * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) - * [dwm-statusallmons-6.0.diff](dwm-statusallmons-6.0.diff) (982b) (20120406) - * [dwm-statusallmons-5.8.2.diff](dwm-statusallmons-5.8.2.diff) (4.0K) (20110318) - -Author ------- - * Pascal Wittmann - <mail@pascal-wittmann.de> - * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff b/dwm.suckless.org/patches/statusallmons/dwm-10e232f9ace7-statusallmons.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-statusallmons.diff b/dwm.suckless.org/patches/statusallmons/dwm-6.1-statusallmons.diff diff --git a/dwm.suckless.org/patches/dwm-statusallmons-20160731-56a31dc.diff b/dwm.suckless.org/patches/statusallmons/dwm-statusallmons-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-statusallmons-5.8.2.diff b/dwm.suckless.org/patches/statusallmons/dwm-statusallmons-5.8.2.diff diff --git a/dwm.suckless.org/patches/dwm-statusallmons-6.0.diff b/dwm.suckless.org/patches/statusallmons/dwm-statusallmons-6.0.diff diff --git a/dwm.suckless.org/patches/statusallmons/index.md b/dwm.suckless.org/patches/statusallmons/index.md @@ -0,0 +1,22 @@ +statusbar on all monitors +========================= + +Description +----------- +This patch draws and updates the statusbar on all monitors. + +Download +-------- +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-statusallmons-20160731-56a31dc.diff](dwm-statusallmons-20160731-56a31dc.diff) + * [dwm-6.1-statusallmons.diff](dwm-6.1-statusallmons.diff) (1026b) (20140209) + * [dwm-10e232f9ace7-statusallmons.diff](dwm-10e232f9ace7-statusallmons.diff) (982b) (20120406) + * [dwm-statusallmons-6.0.diff](dwm-statusallmons-6.0.diff) (982b) (20120406) + * [dwm-statusallmons-5.8.2.diff](dwm-statusallmons-5.8.2.diff) (4.0K) (20110318) + +Author +------ + * Pascal Wittmann - <mail@pascal-wittmann.de> + * Updated by Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/statuscolors.md b/dwm.suckless.org/patches/statuscolors.md @@ -1,62 +0,0 @@ -# colored status text # - -## Description ## - -This patch enables colored text in the status bar. It changes the way colors are defined in config.h, allowing the user to define multiple color combinations for use in their status script. - -## Configuration ## - -Download the patch and apply it according to the [general instructions](.). - -Modify the colors definition in 'config.h' to suit your needs. Make sure to define at least 3 colors as they will be used for 'normal', 'selected', and 'urgent' windows, respectively. - -## Usage ## - -Add code to your status script to output the raw characters '\x03' to switch to the 'urgent' color, or '\x04' to switch to the 4th defined color, etc. Note that the color indices in the status text are +1 from the definition in 'config.h' (because '\0' is the string terminator). To switch back to the normal text color use '\x01'. To enter the raw character '\x01' in vim, press ctrl+v followed by x, 0, and 1 in that order. '\x01' gives the first character, which appears as a bold "A" on the screen to distinguish it from the regular character A. - -### Example ### - -The following definition in 'config.h': - - #define NUMCOLORS 4 - static const char colors[NUMCOLORS][MAXCOLORS][8] = { - // border foreground background - { "#000033", "#dddddd", "#000033" }, // normal - { "#000088", "#ffffff", "#000088" }, // selected - { "#ff0000", "#000000", "#ffff00" }, // urgent/warning (black on yellow) - { "#ff0000", "#ffffff", "#ff0000" }, // error (white on red) - // add more here - }; - -Coupled with a matching status script produces the following: -  - -A really silly example: - - echo -e "normal \x01 selected \x03 warning/urgent \x04 error \x01 back to normal text" | dwm - -An example status script snippet to take advantage of the colors: - - status="" - if [$batperc -le 10]; then - # use "warning" color - status+="\x03 BAT: $batperc" - elif [$batperc -le 5]; then - # use "error" color - status+="\x04 BAT: $batperc" - else - # default is normal color - status+="BAT: $batperc" - fi - - # switch back to normal color for date - status+="\x01| "+$(date) - - echo -e $status - -## Download ## - - * [dwm-5.7.2-statuscolors.diff](historical/dwm-5.7.2-statuscolors.diff) - * [dwm-5.8.2-statuscolors.diff](historical/dwm-5.8.2-statuscolors.diff) - * [dwm-statuscolors-5.9.diff](dwm-statuscolors-5.9.diff) - * [dwm-statuscolors-6.1.diff](dwm-statuscolors-6.1.diff) diff --git a/dwm.suckless.org/patches/statuscolors/dwm-5.7.2-statuscolors.diff b/dwm.suckless.org/patches/statuscolors/dwm-5.7.2-statuscolors.diff @@ -0,0 +1,234 @@ +diff -r 2bcd25cce4ab config.def.h +--- a/config.def.h Sun Sep 27 20:20:14 2009 +0100 ++++ b/config.def.h Mon Oct 05 22:01:49 2009 -0300 +@@ -1,13 +1,16 @@ + /* See LICENSE file for copyright and license details. */ + + /* appearance */ ++#define NUMCOLORS 4 // need at least 3 ++static const char colors[NUMCOLORS][ColLast][8] = { ++ // border foreground background ++ { "#cccccc", "#000000", "#cccccc" }, // 0 = normal ++ { "#0066ff", "#ffffff", "#0066ff" }, // 1 = selected ++ { "#0066ff", "#0066ff", "#ffffff" }, // 2 = urgent/warning ++ { "#ff0000", "#ffffff", "#ff0000" }, // 3 = error ++ // add more here ++}; + static const char font[] = "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*"; +-static const char normbordercolor[] = "#cccccc"; +-static const char normbgcolor[] = "#cccccc"; +-static const char normfgcolor[] = "#000000"; +-static const char selbordercolor[] = "#0066ff"; +-static const char selbgcolor[] = "#0066ff"; +-static const char selfgcolor[] = "#ffffff"; + 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 */ +@@ -45,7 +48,7 @@ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + + /* commands */ +-static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; ++static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG], "-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL }; + static const char *termcmd[] = { "uxterm", NULL }; + + static Key keys[] = { +diff -r 2bcd25cce4ab dwm.c +--- a/dwm.c Sun Sep 27 20:20:14 2009 +0100 ++++ b/dwm.c Mon Oct 05 22:01:49 2009 -0300 +@@ -48,6 +48,7 @@ + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MAX(A, B) ((A) > (B) ? (A) : (B)) + #define MIN(A, B) ((A) < (B) ? (A) : (B)) ++#define MAXCOLORS 8 + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) + #define HEIGHT(X) ((X)->h + 2 * (X)->bw) +@@ -95,8 +96,7 @@ + + typedef struct { + int x, y, w, h; +- unsigned long norm[ColLast]; +- unsigned long sel[ColLast]; ++ unsigned long colors[MAXCOLORS][ColLast]; + Drawable drawable; + GC gc; + struct { +@@ -172,8 +172,9 @@ + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); +-static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); +-static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); ++static void drawcoloredtext(char *text); ++static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]); ++static void drawtext(const char *text, unsigned long col[ColLast], Bool pad); + static void enternotify(XEvent *e); + static void expose(XEvent *e); + static void focus(Client *c); +@@ -691,14 +692,13 @@ + dc.x = 0; + for(i = 0; i < LENGTH(tags); i++) { + dc.w = TEXTW(tags[i]); +- col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; +- drawtext(tags[i], col, urg & 1 << i); +- drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, +- occ & 1 << i, urg & 1 << i, col); ++ col = dc.colors[ (m->tagset[m->seltags] & 1 << i ? 1:(urg & 1 << i ? 2:0))]; ++ drawtext(tags[i], col, True); ++ drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, col); + dc.x += dc.w; + } + dc.w = blw = TEXTW(m->ltsymbol); +- drawtext(m->ltsymbol, dc.norm, False); ++ drawtext(m->ltsymbol, dc.colors[0], True); + dc.x += dc.w; + x = dc.x; + if(m == selmon) { /* status is only drawn on selected monitor */ +@@ -708,19 +708,19 @@ + dc.x = x; + dc.w = m->ww - x; + } +- drawtext(stext, dc.norm, False); ++ drawcoloredtext(stext); + } + else + dc.x = m->ww; + if((dc.w = dc.x - x) > bh) { + dc.x = x; + if(m->sel) { +- col = m == selmon ? dc.sel : dc.norm; +- drawtext(m->sel->name, col, False); +- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); ++ col = m == selmon ? dc.colors[1] : dc.colors[0]; ++ drawtext(m->sel->name, col, True); ++ drawsquare(m->sel->isfixed, m->sel->isfloating, col); + } + else +- drawtext(NULL, dc.norm, False); ++ drawtext(NULL, dc.colors[0], False); + } + XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); + XSync(dpy, False); +@@ -735,12 +735,42 @@ + } + + void +-drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { ++drawcoloredtext(char *text) { ++ Bool first=True; ++ char *buf = text, *ptr = buf, c = 1; ++ unsigned long *col = dc.colors[0]; ++ int i, ox = dc.x; ++ ++ while( *ptr ) { ++ for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++); ++ if( !*ptr ) break; ++ c=*ptr; ++ *ptr=0; ++ if( i ) { ++ dc.w = selmon->ww - dc.x; ++ drawtext(buf, col, first); ++ dc.x += textnw(buf, i) + textnw(&c,1); ++ if( first ) dc.x += ( dc.font.ascent + dc.font.descent ) / 2; ++ first = False; ++ } else if( first ) { ++ ox = dc.x += textnw(&c,1); ++ } ++ *ptr = c; ++ col = dc.colors[ c-1 ]; ++ buf = ++ptr; ++ } ++ if( !first ) dc.x-=(dc.font.ascent+dc.font.descent)/2; ++ drawtext(buf, col, True); ++ dc.x = ox; ++} ++ ++void ++drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) { + int x; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + +- gcv.foreground = col[invert ? ColBG : ColFG]; ++ gcv.foreground = col[ ColFG ]; + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + x = (dc.font.ascent + dc.font.descent + 2) / 4; + r.x = dc.x + 1; +@@ -756,18 +786,18 @@ + } + + void +-drawtext(const char *text, unsigned long col[ColLast], Bool invert) { ++drawtext(const char *text, unsigned long col[ColLast], Bool pad) { + char buf[256]; + int i, x, y, h, len, olen; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + +- XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); ++ XSetForeground(dpy, dc.gc, col[ ColBG ]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + olen = strlen(text); +- h = dc.font.ascent + dc.font.descent; +- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; ++ h = pad ? (dc.font.ascent + dc.font.descent) : 0; ++ y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2); + x = dc.x + (h / 2); + /* shorten text if necessary */ + for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); +@@ -776,7 +806,7 @@ + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); +- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); ++ XSetForeground(dpy, dc.gc, col[ ColFG ]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else +@@ -824,7 +854,7 @@ + detachstack(c); + attachstack(c); + grabbuttons(c, True); +- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); ++ XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + } + else +@@ -1132,7 +1162,7 @@ + } + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); +- XSetWindowBorder(dpy, w, dc.norm[ColBorder]); ++ XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]); + configure(c); /* propagates border_width, if size doesn't change */ + updatesizehints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); +@@ -1498,12 +1528,11 @@ + cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); + cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); + /* init appearance */ +- dc.norm[ColBorder] = getcolor(normbordercolor); +- dc.norm[ColBG] = getcolor(normbgcolor); +- dc.norm[ColFG] = getcolor(normfgcolor); +- dc.sel[ColBorder] = getcolor(selbordercolor); +- dc.sel[ColBG] = getcolor(selbgcolor); +- dc.sel[ColFG] = getcolor(selfgcolor); ++ for(int i=0; i<NUMCOLORS; i++) { ++ dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] ); ++ dc.colors[i][ColFG] = getcolor( colors[i][ColFG] ); ++ dc.colors[i][ColBG] = getcolor( colors[i][ColBG] ); ++ } + 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); +@@ -1665,7 +1694,7 @@ + if(!c) + return; + grabbuttons(c, False); +- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); ++ XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]); + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + } + diff --git a/dwm.suckless.org/patches/statuscolors/dwm-5.8.2-statuscolors.diff b/dwm.suckless.org/patches/statuscolors/dwm-5.8.2-statuscolors.diff @@ -0,0 +1,232 @@ +--- a/config.def.h 2010-10-16 15:49:03.000000000 +0200 ++++ b/config.def.h 2010-10-16 15:51:35.000000000 +0200 +@@ -1,13 +1,16 @@ + /* See LICENSE file for copyright and license details. */ + + /* appearance */ ++#define NUMCOLORS 4 // need at least 3 ++static const char colors[NUMCOLORS][ColLast][8] = { ++ // border foreground background ++ { "#cccccc", "#000000", "#cccccc" }, // 0 = normal ++ { "#0066ff", "#ffffff", "#0066ff" }, // 1 = selected ++ { "#0066ff", "#0066ff", "#ffffff" }, // 2 = urgent/warning ++ { "#ff0000", "#ffffff", "#ff0000" }, // 3 = error ++ // add more here ++}; + static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; +-static const char normbordercolor[] = "#cccccc"; +-static const char normbgcolor[] = "#cccccc"; +-static const char normfgcolor[] = "#000000"; +-static const char selbordercolor[] = "#0066ff"; +-static const char selbgcolor[] = "#0066ff"; +-static const char selfgcolor[] = "#ffffff"; + 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 */ +@@ -45,7 +48,7 @@ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + + /* commands */ +-static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; ++static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG],"-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL }; + static const char *termcmd[] = { "uxterm", NULL }; + + static Key keys[] = { +--- a//dwm.c 2010-06-04 12:39:15.000000000 +0200 ++++ b/dwm.c 2010-11-03 20:36:50.000000000 +0100 +@@ -48,6 +48,7 @@ + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MAX(A, B) ((A) > (B) ? (A) : (B)) + #define MIN(A, B) ((A) < (B) ? (A) : (B)) ++#define MAXCOLORS 8 + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) + #define HEIGHT(X) ((X)->h + 2 * (X)->bw) +@@ -97,8 +98,7 @@ + + typedef struct { + int x, y, w, h; +- unsigned long norm[ColLast]; +- unsigned long sel[ColLast]; ++ unsigned long colors[MAXCOLORS][ColLast]; + Drawable drawable; + GC gc; + struct { +@@ -175,8 +175,9 @@ + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); +-static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); +-static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); ++static void drawcoloredtext(char *text); ++static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]); ++static void drawtext(const char *text, unsigned long col[ColLast], Bool pad); + static void enternotify(XEvent *e); + static void expose(XEvent *e); + static void focus(Client *c); +@@ -696,14 +697,13 @@ + dc.x = 0; + for(i = 0; i < LENGTH(tags); i++) { + dc.w = TEXTW(tags[i]); +- col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; +- drawtext(tags[i], col, urg & 1 << i); +- drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, +- occ & 1 << i, urg & 1 << i, col); ++ col = dc.colors[ (m->tagset[m->seltags] & 1 << i ? 1:(urg & 1 << i ? 2:0))]; ++ drawtext(tags[i], col, True); ++ drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, col); + dc.x += dc.w; + } + dc.w = blw = TEXTW(m->ltsymbol); +- drawtext(m->ltsymbol, dc.norm, False); ++ drawtext(m->ltsymbol, dc.colors[0], True); + dc.x += dc.w; + x = dc.x; + if(m == selmon) { /* status is only drawn on selected monitor */ +@@ -713,19 +713,19 @@ + dc.x = x; + dc.w = m->ww - x; + } +- drawtext(stext, dc.norm, False); ++ drawcoloredtext(stext); + } + else + dc.x = m->ww; + if((dc.w = dc.x - x) > bh) { + dc.x = x; + if(m->sel) { +- col = m == selmon ? dc.sel : dc.norm; +- drawtext(m->sel->name, col, False); +- drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); ++ col = m == selmon ? dc.colors[1] : dc.colors[0]; ++ drawtext(m->sel->name, col, True); ++ drawsquare(m->sel->isfixed, m->sel->isfloating, col); + } + else +- drawtext(NULL, dc.norm, False); ++ drawtext(NULL, dc.colors[0], False); + } + XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); + XSync(dpy, False); +@@ -740,12 +740,42 @@ + } + + void +-drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { ++drawcoloredtext(char *text) { ++ Bool first=True; ++ char *buf = text, *ptr = buf, c = 1; ++ unsigned long *col = dc.colors[0]; ++ int i, ox = dc.x; ++ ++ while( *ptr ) { ++ for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++); ++ if( !*ptr ) break; ++ c=*ptr; ++ *ptr=0; ++ if( i ) { ++ dc.w = selmon->ww - dc.x; ++ drawtext(buf, col, first); ++ dc.x += textnw(buf, i) + textnw(&c,1); ++ if( first ) dc.x += ( dc.font.ascent + dc.font.descent ) / 2; ++ first = False; ++ } else if( first ) { ++ ox = dc.x += textnw(&c,1); ++ } ++ *ptr = c; ++ col = dc.colors[ c-1 ]; ++ buf = ++ptr; ++ } ++ if( !first ) dc.x-=(dc.font.ascent+dc.font.descent)/2; ++ drawtext(buf, col, True); ++ dc.x = ox; ++} ++ ++void ++drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) { + int x; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + +- gcv.foreground = col[invert ? ColBG : ColFG]; ++ gcv.foreground = col[ ColFG ]; + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + x = (dc.font.ascent + dc.font.descent + 2) / 4; + r.x = dc.x + 1; +@@ -761,18 +791,18 @@ + } + + void +-drawtext(const char *text, unsigned long col[ColLast], Bool invert) { ++drawtext(const char *text, unsigned long col[ColLast], Bool pad) { + char buf[256]; + int i, x, y, h, len, olen; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + +- XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); ++ XSetForeground(dpy, dc.gc, col[ ColBG ]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + olen = strlen(text); +- h = dc.font.ascent + dc.font.descent; +- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; ++ h = pad ? (dc.font.ascent + dc.font.descent) : 0; ++ y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2); + x = dc.x + (h / 2); + /* shorten text if necessary */ + for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); +@@ -781,7 +811,7 @@ + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); +- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); ++ XSetForeground(dpy, dc.gc, col[ ColFG ]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else +@@ -830,7 +860,7 @@ + detachstack(c); + attachstack(c); + grabbuttons(c, True); +- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); ++ XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + } + else +@@ -1139,7 +1169,7 @@ + } + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); +- XSetWindowBorder(dpy, w, dc.norm[ColBorder]); ++ XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]); + configure(c); /* propagates border_width, if size doesn't change */ + updatesizehints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); +@@ -1544,12 +1574,11 @@ + cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); + cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); + /* init appearance */ +- dc.norm[ColBorder] = getcolor(normbordercolor); +- dc.norm[ColBG] = getcolor(normbgcolor); +- dc.norm[ColFG] = getcolor(normfgcolor); +- dc.sel[ColBorder] = getcolor(selbordercolor); +- dc.sel[ColBG] = getcolor(selbgcolor); +- dc.sel[ColFG] = getcolor(selfgcolor); ++ for(int i=0; i<NUMCOLORS; i++) { ++ dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] ); ++ dc.colors[i][ColFG] = getcolor( colors[i][ColFG] ); ++ dc.colors[i][ColBG] = getcolor( colors[i][ColBG] ); ++ } + 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); +@@ -1711,7 +1740,7 @@ + if(!c) + return; + grabbuttons(c, False); +- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); ++ XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]); + if(setfocus) + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + } diff --git a/dwm.suckless.org/patches/dwm-statuscolors-5.9.diff b/dwm.suckless.org/patches/statuscolors/dwm-statuscolors-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-statuscolors-6.1.diff b/dwm.suckless.org/patches/statuscolors/dwm-statuscolors-6.1.diff diff --git a/dwm.suckless.org/patches/statuscolors/index.md b/dwm.suckless.org/patches/statuscolors/index.md @@ -0,0 +1,62 @@ +# colored status text # + +## Description ## + +This patch enables colored text in the status bar. It changes the way colors are defined in config.h, allowing the user to define multiple color combinations for use in their status script. + +## Configuration ## + +Download the patch and apply it according to the [general instructions](.). + +Modify the colors definition in 'config.h' to suit your needs. Make sure to define at least 3 colors as they will be used for 'normal', 'selected', and 'urgent' windows, respectively. + +## Usage ## + +Add code to your status script to output the raw characters '\x03' to switch to the 'urgent' color, or '\x04' to switch to the 4th defined color, etc. Note that the color indices in the status text are +1 from the definition in 'config.h' (because '\0' is the string terminator). To switch back to the normal text color use '\x01'. To enter the raw character '\x01' in vim, press ctrl+v followed by x, 0, and 1 in that order. '\x01' gives the first character, which appears as a bold "A" on the screen to distinguish it from the regular character A. + +### Example ### + +The following definition in 'config.h': + + #define NUMCOLORS 4 + static const char colors[NUMCOLORS][MAXCOLORS][8] = { + // border foreground background + { "#000033", "#dddddd", "#000033" }, // normal + { "#000088", "#ffffff", "#000088" }, // selected + { "#ff0000", "#000000", "#ffff00" }, // urgent/warning (black on yellow) + { "#ff0000", "#ffffff", "#ff0000" }, // error (white on red) + // add more here + }; + +Coupled with a matching status script produces the following: +  + +A really silly example: + + echo -e "normal \x01 selected \x03 warning/urgent \x04 error \x01 back to normal text" | dwm + +An example status script snippet to take advantage of the colors: + + status="" + if [$batperc -le 10]; then + # use "warning" color + status+="\x03 BAT: $batperc" + elif [$batperc -le 5]; then + # use "error" color + status+="\x04 BAT: $batperc" + else + # default is normal color + status+="BAT: $batperc" + fi + + # switch back to normal color for date + status+="\x01| "+$(date) + + echo -e $status + +## Download ## + + * [dwm-5.7.2-statuscolors.diff](dwm-5.7.2-statuscolors.diff) + * [dwm-5.8.2-statuscolors.diff](dwm-5.8.2-statuscolors.diff) + * [dwm-statuscolors-5.9.diff](dwm-statuscolors-5.9.diff) + * [dwm-statuscolors-6.1.diff](dwm-statuscolors-6.1.diff) diff --git a/dwm.suckless.org/patches/dwm-5.7.2-statuscolors.png b/dwm.suckless.org/patches/statuscolors/statuscolors.png Binary files differ. diff --git a/dwm.suckless.org/patches/stdin.md b/dwm.suckless.org/patches/stdin.md @@ -1,21 +0,0 @@ -stdin -===== - -Description ------------ - -dwm releases before 5.3 read the status text from stdin. -This patch is mainly a workaround for the freezing issue caused by -`XSelectInput` with the previous version of the [warp](warp) patch. -Some people might like to write their status to a pipe, though. - -Download --------- - -* [dwm-r1533-stdin.diff](dwm-r1533-stdin.diff) - -Author ------- - -This was originally part of dwm-5.2 and written by Anselm R. Garbe. -It was ported to later versions of dwm by Moritz Wilhelmy, mw wzff de. diff --git a/dwm.suckless.org/patches/dwm-r1533-stdin.diff b/dwm.suckless.org/patches/stdin/dwm-r1533-stdin.diff diff --git a/dwm.suckless.org/patches/stdin/index.md b/dwm.suckless.org/patches/stdin/index.md @@ -0,0 +1,21 @@ +stdin +===== + +Description +----------- + +dwm releases before 5.3 read the status text from stdin. +This patch is mainly a workaround for the freezing issue caused by +`XSelectInput` with the previous version of the [warp](warp) patch. +Some people might like to write their status to a pipe, though. + +Download +-------- + +* [dwm-r1533-stdin.diff](dwm-r1533-stdin.diff) + +Author +------ + +This was originally part of dwm-5.2 and written by Anselm R. Garbe. +It was ported to later versions of dwm by Moritz Wilhelmy, mw wzff de. diff --git a/dwm.suckless.org/patches/sticky.md b/dwm.suckless.org/patches/sticky.md @@ -1,16 +0,0 @@ -# sticky - -## Description - -Press `MODKEY+s` (default) to make a client 'sticky'. A sticky client is visible -on all tags. This is similar to setting the client's `tags` to all 1's, but with -the ability to easily return it to its original tag by toggling it off by -pressing `MODKEY+s` again. - -## Download - - * [dwm-sticky-6.1.diff](dwm-sticky-6.1.diff) - * [dwm-sticky-20160911-ab9571b.diff](dwm-sticky-20160911-ab9571b.diff) - -## Author - * Ryan Roden-Corrent <ryan@rcorre.net> diff --git a/dwm.suckless.org/patches/dwm-sticky-20160911-ab9571b.diff b/dwm.suckless.org/patches/sticky/dwm-sticky-20160911-ab9571b.diff diff --git a/dwm.suckless.org/patches/dwm-sticky-6.1.diff b/dwm.suckless.org/patches/sticky/dwm-sticky-6.1.diff diff --git a/dwm.suckless.org/patches/sticky/index.md b/dwm.suckless.org/patches/sticky/index.md @@ -0,0 +1,16 @@ +# sticky + +## Description + +Press `MODKEY+s` (default) to make a client 'sticky'. A sticky client is visible +on all tags. This is similar to setting the client's `tags` to all 1's, but with +the ability to easily return it to its original tag by toggling it off by +pressing `MODKEY+s` again. + +## Download + + * [dwm-sticky-6.1.diff](dwm-sticky-6.1.diff) + * [dwm-sticky-20160911-ab9571b.diff](dwm-sticky-20160911-ab9571b.diff) + +## Author + * Ryan Roden-Corrent <ryan@rcorre.net> diff --git a/dwm.suckless.org/patches/swallow.md b/dwm.suckless.org/patches/swallow.md @@ -1,52 +0,0 @@ -swallow -======= - -Description ------------ - -This patch adds "window swallowing" to dwm as known from Plan 9's windowing -system `rio`. - -Clients marked with `isterminal` in config.h swallow a window opened by -any child process, e.g. running `xclock` in a terminal. -Closing the `xclock` window restores the terminal window in the current -position. - -This patch helps users spawning a lot of graphical programs from their -command line by avoiding cluttering the screen with many unusable terminals. -Being deep down in a directory hierarchy just does not make the use of -dmenu feasible. - -Dependencies ------------- - - * libxcb - * Xlib-libxcb - * xcb-res - -These dependencies are needed due to the use of the latest revision of the X -Resource Extension which is unsupported in vanilla Xlib. - -Download --------- - - * [dwm-swallow-20170909-ceac8c9.diff](dwm-swallow-20170909-ceac8c9.diff) - * [dwm-swallow-6.1.diff](dwm-swallow-6.1.diff) - * [dwm-swallow-20160717-56a31dc.diff](dwm-swallow-20160717-56a31dc.diff) - -Notes ------ - -The window swallowing functionality requires `dwm` to walk the process tree, -which is an inherently OS-specific task. Only Linux is supported at this time. -Please contact one of the authors if you would like to help expand the list -of supported operating systems. - -Only terminals created by local processes can swallow windows, and only -windows created by local processes can be swallowed. - -Authors -------- - - * Rob King - <jking@deadpixi.com> - * Laslo Hunhold - <dev@frign.de> (6.1, git port) diff --git a/dwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff b/dwm.suckless.org/patches/swallow/dwm-swallow-20160717-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-swallow-20170909-ceac8c9.diff b/dwm.suckless.org/patches/swallow/dwm-swallow-20170909-ceac8c9.diff diff --git a/dwm.suckless.org/patches/dwm-swallow-6.1.diff b/dwm.suckless.org/patches/swallow/dwm-swallow-6.1.diff diff --git a/dwm.suckless.org/patches/swallow/index.md b/dwm.suckless.org/patches/swallow/index.md @@ -0,0 +1,52 @@ +swallow +======= + +Description +----------- + +This patch adds "window swallowing" to dwm as known from Plan 9's windowing +system `rio`. + +Clients marked with `isterminal` in config.h swallow a window opened by +any child process, e.g. running `xclock` in a terminal. +Closing the `xclock` window restores the terminal window in the current +position. + +This patch helps users spawning a lot of graphical programs from their +command line by avoiding cluttering the screen with many unusable terminals. +Being deep down in a directory hierarchy just does not make the use of +dmenu feasible. + +Dependencies +------------ + + * libxcb + * Xlib-libxcb + * xcb-res + +These dependencies are needed due to the use of the latest revision of the X +Resource Extension which is unsupported in vanilla Xlib. + +Download +-------- + + * [dwm-swallow-20170909-ceac8c9.diff](dwm-swallow-20170909-ceac8c9.diff) + * [dwm-swallow-6.1.diff](dwm-swallow-6.1.diff) + * [dwm-swallow-20160717-56a31dc.diff](dwm-swallow-20160717-56a31dc.diff) + +Notes +----- + +The window swallowing functionality requires `dwm` to walk the process tree, +which is an inherently OS-specific task. Only Linux is supported at this time. +Please contact one of the authors if you would like to help expand the list +of supported operating systems. + +Only terminals created by local processes can swallow windows, and only +windows created by local processes can be swallowed. + +Authors +------- + + * Rob King - <jking@deadpixi.com> + * Laslo Hunhold - <dev@frign.de> (6.1, git port) diff --git a/dwm.suckless.org/patches/swapfocus.md b/dwm.suckless.org/patches/swapfocus.md @@ -1,18 +0,0 @@ -# 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://github.com/jceb/dwm-clean-patches). - - * [dwm-swapfocus-20160731-56a31dc.diff](dwm-swapfocus-20160731-56a31dc.diff) - * [dwm-6.1-swapfocus.diff](dwm-6.1-swapfocus.diff) (1807b) (20140209) - * [dwm-10e232f9ace7-swapfocus.diff](dwm-10e232f9ace7-swapfocus.diff) (1484b) (20120406) - * [dwm-swapfocus-6.0.diff](dwm-swapfocus-6.0.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 - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff b/dwm.suckless.org/patches/swapfocus/dwm-10e232f9ace7-swapfocus.diff diff --git a/dwm.suckless.org/patches/dwm-5.8.2-swap.diff b/dwm.suckless.org/patches/swapfocus/dwm-5.8.2-swap.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-swapfocus.diff b/dwm.suckless.org/patches/swapfocus/dwm-6.1-swapfocus.diff diff --git a/dwm.suckless.org/patches/dwm-swapfocus-20160731-56a31dc.diff b/dwm.suckless.org/patches/swapfocus/dwm-swapfocus-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-swapfocus-6.0.diff b/dwm.suckless.org/patches/swapfocus/dwm-swapfocus-6.0.diff diff --git a/dwm.suckless.org/patches/swapfocus/index.md b/dwm.suckless.org/patches/swapfocus/index.md @@ -0,0 +1,18 @@ +# 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://github.com/jceb/dwm-clean-patches). + + * [dwm-swapfocus-20160731-56a31dc.diff](dwm-swapfocus-20160731-56a31dc.diff) + * [dwm-6.1-swapfocus.diff](dwm-6.1-swapfocus.diff) (1807b) (20140209) + * [dwm-10e232f9ace7-swapfocus.diff](dwm-10e232f9ace7-swapfocus.diff) (1484b) (20120406) + * [dwm-swapfocus-6.0.diff](dwm-swapfocus-6.0.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 - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/switchcol.md b/dwm.suckless.org/patches/switchcol.md @@ -1,20 +0,0 @@ -# switchcol - -## Description - -Switch focus between the 2 columns (master or stack) easily. This patch only -has one function, it remembers the most recently focused client in the 2 -columns for each tag (it is implemented by searching the stack list to find -the most recent client in the other column). - -## Configuration - - /*config.h*/ - { MODKEY, XK_n, switchcol, {0} }, - -## Download - -* [dwm-switchcol-6.1.diff](dwm-switchcol-6.1.diff) (1126b) (20160325) - -## Author -* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/dwm-switchcol-6.1.diff b/dwm.suckless.org/patches/switchcol/dwm-switchcol-6.1.diff diff --git a/dwm.suckless.org/patches/switchcol/index.md b/dwm.suckless.org/patches/switchcol/index.md @@ -0,0 +1,20 @@ +# switchcol + +## Description + +Switch focus between the 2 columns (master or stack) easily. This patch only +has one function, it remembers the most recently focused client in the 2 +columns for each tag (it is implemented by searching the stack list to find +the most recent client in the other column). + +## Configuration + + /*config.h*/ + { MODKEY, XK_n, switchcol, {0} }, + +## Download + +* [dwm-switchcol-6.1.diff](dwm-switchcol-6.1.diff) (1126b) (20160325) + +## Author +* phi <crispyfrog@163.com> diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray.md @@ -1,27 +0,0 @@ -systray -======= - -Description ------------ -A simple system tray implementation. Multi-monitor is also supported. The tray -is following the selected monitor. - -Download --------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-systray-20161218-bb3bd6f.diff](dwm-systray-20161218-bb3bd6f.diff) - * [dwm-systray-20160731-56a31dc.diff](dwm-systray-20160731-56a31dc.diff) - * [dwm-systray-git-20160626-7af4d43.diff](dwm-systray-git-20160626-7af4d43.diff) (7af4d43) - * [dwm-git-20160103-systray.diff](dwm-git-20160103-systray.diff) (3465bed) - * [dwm-6.1-systray.diff](dwm-6.1-systray.diff) (22K) (20151109) - * [dwm-git-20130119-systray.diff](dwm-git-20130119-systray.diff) (19946b) - * [dwm-systray-6.0.diff](dwm-systray-6.0.diff) (19788b) (20130119) - -Author ------- - * Jan Christoph Ebersbach <jceb@e-jc.de> - * Eon S. Jeon <esjeon@hyunmu.am> (14343e69cc59) - * David Phillips (5ed9c48 (6.1), and 20160103) - * Eric Pruitt (7af4d43 (6.1), and 20160626) diff --git a/dwm.suckless.org/patches/dwm-6.1-systray.diff b/dwm.suckless.org/patches/systray/dwm-6.1-systray.diff diff --git a/dwm.suckless.org/patches/dwm-git-20130119-systray.diff b/dwm.suckless.org/patches/systray/dwm-git-20130119-systray.diff diff --git a/dwm.suckless.org/patches/dwm-git-20160103-systray.diff b/dwm.suckless.org/patches/systray/dwm-git-20160103-systray.diff diff --git a/dwm.suckless.org/patches/dwm-systray-20160731-56a31dc.diff b/dwm.suckless.org/patches/systray/dwm-systray-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-systray-20161218-bb3bd6f.diff b/dwm.suckless.org/patches/systray/dwm-systray-20161218-bb3bd6f.diff diff --git a/dwm.suckless.org/patches/dwm-systray-6.0.diff b/dwm.suckless.org/patches/systray/dwm-systray-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-systray-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/systray/dwm-systray-git-20160626-7af4d43.diff diff --git a/dwm.suckless.org/patches/systray/index.md b/dwm.suckless.org/patches/systray/index.md @@ -0,0 +1,27 @@ +systray +======= + +Description +----------- +A simple system tray implementation. Multi-monitor is also supported. The tray +is following the selected monitor. + +Download +-------- +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-systray-20161218-bb3bd6f.diff](dwm-systray-20161218-bb3bd6f.diff) + * [dwm-systray-20160731-56a31dc.diff](dwm-systray-20160731-56a31dc.diff) + * [dwm-systray-git-20160626-7af4d43.diff](dwm-systray-git-20160626-7af4d43.diff) (7af4d43) + * [dwm-git-20160103-systray.diff](dwm-git-20160103-systray.diff) (3465bed) + * [dwm-6.1-systray.diff](dwm-6.1-systray.diff) (22K) (20151109) + * [dwm-git-20130119-systray.diff](dwm-git-20130119-systray.diff) (19946b) + * [dwm-systray-6.0.diff](dwm-systray-6.0.diff) (19788b) (20130119) + +Author +------ + * Jan Christoph Ebersbach <jceb@e-jc.de> + * Eon S. Jeon <esjeon@hyunmu.am> (14343e69cc59) + * David Phillips (5ed9c48 (6.1), and 20160103) + * Eric Pruitt (7af4d43 (6.1), and 20160626) diff --git a/dwm.suckless.org/patches/tab.md b/dwm.suckless.org/patches/tab.md @@ -1,149 +0,0 @@ -Tab -=== - -Description ------------ - -Transforms the monocle layout into a ''tabbed'' layout if more than one window -is present on the monocle view. Navigating from window to window is done by -clicking on the window tabs or using the usual Mod1-j, Mod1-k keys. The tabs are -arranged in a bar on top or at bottom of the screen, which can also be displayed -in the other layouts than monocle. Three display modes can be selected at run -time, auto display, permanent display and no display. In permanent mode the tab -bar is always display independently of the layout, while in the auto mode it is -displayed only with the monocle layout and in presence of several windows. - -This patch can be used as an alternative to the -[tabbed](//tools.suckless.org/tabbed/) tool. It differs in two ways: the -''tab'' feature is limited to the monocle mode; it works with any application -without requiring to support the XEmbed protocol nor to define in advance the -set of applications to be supported. - -Usage ------ - -With the default configuration, use the key combination Mod1-w to toggle the tab -bar display. Switch focus to a window with a mouse left-click on its tab or by -using the usual Mod1-j, Mod1-k commands. Usage is also documented in the dwm man -page once the patch is applied. - -The selected view (''tag'') is reminded at the right corner of the tab bar. This -feature is mainly meant to be used when the standard status bar is disabled. In -case of a multi-tag view three dots are displayed without additional details. - -Configuration and Installation ------------------------------- - -### Quick installation - -#### Using the default configuration file - -* Make sure the directory where you build dwm does not contain a config.h file; -* Apply the patch; -* Run make and make install. - -The bar is displayed only with monocle layout when the view contains more than -one window. The section "More Options" explains how to add more display options. - -#### Using an existing customised configuration file - -<ul> -<li>Apply the patch; -<li>Add the following lines to your config.h dwm configuration file: -</ul> - /* Display modes of the tab bar: never shown, always shown, shown only in */ - /* monocle mode in presence of several windows. */ - /* A mode can be disabled by moving it after the showtab_nmodes end marker */ - enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; - static const int showtab = showtab_auto; /* Default tab bar show mode */ - static const Bool toptab = True; /* False means bottom tab bar */ - -If you use the combined pertag+tab patch, include also (adapt the number of '0' to your `tags` array configuration): - - /* default layout per tags */ - /* The first element is for all-tag view, following i-th element corresponds to */ - /* tags[i]. Layout is referred using the layouts array index.*/ - static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -<ul> -<li>Run make and make install. -</ul> - -The tab bar is displayed only with the monocle layout when the view contains -more than one window. The Mod1-w key and the mouse support are not included in -this configuration. Activation of these options is explained in the next -section. - -### More Options - -Pressing the key Mod1-w will cycle over the display modes of the tab bar described below with -the following element added to the `keys` array: - - { MODKEY, XK_w, tabmode, {-1} } - -Selection of a window by a mouse left-click on its tab is enabled by adding the -following element to the `buttons` array: - - { ClkTabBar, 0, Button1, focuswin, {0} }, - -An example on how to insert these lines can be found in the default config file -template, config.def.h. - -The tab bar includes three display options: always, never, auto. In auto mode, -the tab bar is displayed only with the monocle layout and when the view contains -more than one window. The modes available at run time can be selected by -changing the order of the elements in the `showtab_mode` enum of the config.h -configuration file: the modes before `showtab_nmodes` are enabled, the ones -after are disabled. The default mode is specified in the `showtab` variable, it -must be one of the enabled modes. - -Note: keyboard shortcuts to switch to a given display mode can be defined by -using the `tabmode` function like in the definition of the `Mod1-w` -key provided above and passing as argument the display mode -(`showtab_never`, `showtab_always`, -`showtab_auto`) instead of -1. - -The tab bar can be displayed on top or at bottom of the screen, which is -controlled by the 'toptab' variable. If the tab bar is displayed at bottom, then -it is recommended to set the variable `resizehints` of the config.h file to -False. This setting prevents possible gap between the windows and the tab bar. -You can find more details about this variable and gap between windows in the -dwm FAQ. - -Download --------- - -<i>Please contact the author if the patch provided for the git master branch does not work with the current head.</i> - - * Tab patch alone - * For dwm 6.1: [dwm-6.1-tab-v2b.diff](dwm-6.1-tab-v2b.diff) - * For dwm from the git master branch: [dwm-tab-v2b-56a31dc.diff](dwm-tab-v2b-56a31dc.diff) - - * Combined patch of tab and the [pertag](pertag) patch from Jan Christoph Ebersbach. - * Follow the [link](pertag) for the description of this patch and the credits. The possibility to define the default layout per view has been added. - * For dwm 6.1: [dwm-6.1-pertag-tab-v2b.diff](dwm-6.1-pertag-tab-v2b.diff) - * For dwm from the git master branch: [dwm-tab-v2b-pertab-56a31dc.diff](dwm-tab-v2b-pertab-56a31dc.diff) - -Old versions - - * [dwm-master_2015-12-19_3465be-tab-v2b.diff](historical/dwm-master_2015-12-19_3465be-tab-v2b.diff) - * [dwm-master_2015-12-19_3465be-pertag-tab-v2b.diff](historical/dwm-master_2015-12-19_3465be-pertag-tab-v2b.diff) - * [dwm-master_2015-10-20_7e1182c-tab-v2b.diff](historical/dwm-master_2015-10-20_7e1182c-tab-v2b.diff), [dwm-master_2015-10-20_7e1182c-pertag-tab-v2b.diff](historical/dwm-master_2015-10-20_7e1182c-pertag-tab-v2b.diff) - * [dwm-master_2015-03-05_14343e-tab-v2b.diff](historical/dwm-master_2015-03-05_14343e-tab-v2b.diff), [dwm-master_2015-03-05_14343e-pertag-tab-v2b.diff](historical/dwm-master_2015-03-05_14343e-pertag-tab-v2b.diff) - * [dwm-6.0-tab-v2b.diff](historical/dwm-6.0-tab-v2b.diff), [dwm-6.0-pertag-tab-v2b.diff](historical/dwm-6.0-pertag-tab-v2b.diff) - * [dwm-master_2013-08-27_cdec978-tab-v2a.diff](historical/dwm-master_2013-08-27_cdec978-tab-v2a.diff), [dwm-master_2013-08-27_cdec978-pertag-tab-v2a.diff](historical/dwm-master_2013-08-27_cdec978-pertag-tab-v2a.diff) - * [dwm-6.0-tab-v2a.diff](historical/dwm-6.0-tab-v2a.diff), [dwm-6.0-pertag-tab-v2a.diff](historical/dwm-6.0-pertag-tab-v2a.diff) - * [dwm-6.0-tab-v2.diff](historical/dwm-6.0-tab-v2.diff), [dwm-6.0-pertag-tab-v2.diff](historical/dwm-6.0-pertag-tab-v2.diff) - - -Change log ----------- - -<dl> - <dt>v2b </dt><dl>Fixed in the pertag-tab patch the support for per-tag default layout specification. No change in the tab only patch.</dl> - <dt>v2a </dt><dl>Typo corrected in the man page. For the combined pertag-tab patch, specification of a default layout per-tag layout was added in the config.h configuration file, but it was not taken into account properly. The version v2b fixed this issue.</dl> - <dt>v2 </dt><dl>First public version.</dl> -</dl> - -Author ------- - * Philippe Gras - `<philippe dot gras at free dot fr>` diff --git a/dwm.suckless.org/patches/dwm-6.1-pertag-tab-v2b.diff b/dwm.suckless.org/patches/tab/dwm-6.1-pertag-tab-v2b.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-tab-v2b.diff b/dwm.suckless.org/patches/tab/dwm-6.1-tab-v2b.diff diff --git a/dwm.suckless.org/patches/dwm-tab-v2b-56a31dc.diff b/dwm.suckless.org/patches/tab/dwm-tab-v2b-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-tab-v2b-pertab-56a31dc.diff b/dwm.suckless.org/patches/tab/dwm-tab-v2b-pertab-56a31dc.diff diff --git a/dwm.suckless.org/patches/tab/index.md b/dwm.suckless.org/patches/tab/index.md @@ -0,0 +1,137 @@ +tab +=== + +Description +----------- + +Transforms the monocle layout into a ''tabbed'' layout if more than one window +is present on the monocle view. Navigating from window to window is done by +clicking on the window tabs or using the usual Mod1-j, Mod1-k keys. The tabs are +arranged in a bar on top or at bottom of the screen, which can also be displayed +in the other layouts than monocle. Three display modes can be selected at run +time, auto display, permanent display and no display. In permanent mode the tab +bar is always display independently of the layout, while in the auto mode it is +displayed only with the monocle layout and in presence of several windows. + +This patch can be used as an alternative to the +[tabbed](//tools.suckless.org/tabbed/) tool. It differs in two ways: the +''tab'' feature is limited to the monocle mode; it works with any application +without requiring to support the XEmbed protocol nor to define in advance the +set of applications to be supported. + +Usage +----- + +With the default configuration, use the key combination Mod1-w to toggle the tab +bar display. Switch focus to a window with a mouse left-click on its tab or by +using the usual Mod1-j, Mod1-k commands. Usage is also documented in the dwm man +page once the patch is applied. + +The selected view (''tag'') is reminded at the right corner of the tab bar. This +feature is mainly meant to be used when the standard status bar is disabled. In +case of a multi-tag view three dots are displayed without additional details. + +Configuration and Installation +------------------------------ + +### Quick installation + +#### Using the default configuration file + +* Make sure the directory where you build dwm does not contain a config.h file; +* Apply the patch; +* Run make and make install. + +The bar is displayed only with monocle layout when the view contains more than +one window. The section "More Options" explains how to add more display options. + +#### Using an existing customised configuration file + +<ul> +<li>Apply the patch; +<li>Add the following lines to your config.h dwm configuration file: +</ul> + /* Display modes of the tab bar: never shown, always shown, shown only in */ + /* monocle mode in presence of several windows. */ + /* A mode can be disabled by moving it after the showtab_nmodes end marker */ + enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; + static const int showtab = showtab_auto; /* Default tab bar show mode */ + static const Bool toptab = True; /* False means bottom tab bar */ + +If you use the combined pertag+tab patch, include also (adapt the number of '0' to your `tags` array configuration): + + /* default layout per tags */ + /* The first element is for all-tag view, following i-th element corresponds to */ + /* tags[i]. Layout is referred using the layouts array index.*/ + static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +<ul> +<li>Run make and make install. +</ul> + +The tab bar is displayed only with the monocle layout when the view contains +more than one window. The Mod1-w key and the mouse support are not included in +this configuration. Activation of these options is explained in the next +section. + +### More Options + +Pressing the key Mod1-w will cycle over the display modes of the tab bar described below with +the following element added to the `keys` array: + + { MODKEY, XK_w, tabmode, {-1} } + +Selection of a window by a mouse left-click on its tab is enabled by adding the +following element to the `buttons` array: + + { ClkTabBar, 0, Button1, focuswin, {0} }, + +An example on how to insert these lines can be found in the default config file +template, config.def.h. + +The tab bar includes three display options: always, never, auto. In auto mode, +the tab bar is displayed only with the monocle layout and when the view contains +more than one window. The modes available at run time can be selected by +changing the order of the elements in the `showtab_mode` enum of the config.h +configuration file: the modes before `showtab_nmodes` are enabled, the ones +after are disabled. The default mode is specified in the `showtab` variable, it +must be one of the enabled modes. + +Note: keyboard shortcuts to switch to a given display mode can be defined by +using the `tabmode` function like in the definition of the `Mod1-w` +key provided above and passing as argument the display mode +(`showtab_never`, `showtab_always`, +`showtab_auto`) instead of -1. + +The tab bar can be displayed on top or at bottom of the screen, which is +controlled by the 'toptab' variable. If the tab bar is displayed at bottom, then +it is recommended to set the variable `resizehints` of the config.h file to +False. This setting prevents possible gap between the windows and the tab bar. +You can find more details about this variable and gap between windows in the +dwm FAQ. + +Download +-------- + +<i>Please contact the author if the patch provided for the git master branch does not work with the current head.</i> + + * Tab patch alone + * For dwm 6.1: [dwm-6.1-tab-v2b.diff](dwm-6.1-tab-v2b.diff) + * For dwm from the git master branch: [dwm-tab-v2b-56a31dc.diff](dwm-tab-v2b-56a31dc.diff) + + * Combined patch of tab and the [pertag](pertag) patch from Jan Christoph Ebersbach. + * Follow the [link](pertag) for the description of this patch and the credits. The possibility to define the default layout per view has been added. + * For dwm 6.1: [dwm-6.1-pertag-tab-v2b.diff](dwm-6.1-pertag-tab-v2b.diff) + * For dwm from the git master branch: [dwm-tab-v2b-pertab-56a31dc.diff](dwm-tab-v2b-pertab-56a31dc.diff) + +Change log +---------- + +<dl> + <dt>v2b </dt><dl>Fixed in the pertag-tab patch the support for per-tag default layout specification. No change in the tab only patch.</dl> + <dt>v2a </dt><dl>Typo corrected in the man page. For the combined pertag-tab patch, specification of a default layout per-tag layout was added in the config.h configuration file, but it was not taken into account properly. The version v2b fixed this issue.</dl> + <dt>v2 </dt><dl>First public version.</dl> +</dl> + +Author +------ + * Philippe Gras - `<philippe dot gras at free dot fr>` diff --git a/dwm.suckless.org/patches/tagall.md b/dwm.suckless.org/patches/tagall.md @@ -1,31 +0,0 @@ -# tag all # - -## Description ## - -Shortcut to move all (floating) windows from one tag to another. - -## Download ## -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-tagall-20160731-56a31dc.diff](dwm-tagall-20160731-56a31dc.diff) - * [dwm-tagall-6.1.diff](dwm-tagall-6.1.diff) (1058b) (20140209) - * [dwm-10e232f9ace7-tagall.diff](dwm-10e232f9ace7-tagall.diff) (988b) (20120406) - * [dwm-tagall-6.0.diff](dwm-tagall-6.0.diff) (988b) (20120406) - -## Configuration ## - - * MODKEY+Shift+F1 moves all floating windows of the current tag to tag 1 - - { MODKEY|ShiftMask, XK_F1, tagall, {.v = "F1"} }, \ - ... - { MODKEY|ShiftMask, XK_F9, tagall, {.v = "F9"} }, \ - - * MODKEY+Shift+F1 moves all windows of the current tag to tag 1 - - { MODKEY|ShiftMask, XK_F1, tagall, {.v = "1"} }, \ - ... - { MODKEY|ShiftMask, XK_F9, tagall, {.v = "9"} }, \ - -## Author ## - * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff b/dwm.suckless.org/patches/tagall/dwm-10e232f9ace7-tagall.diff diff --git a/dwm.suckless.org/patches/dwm-tagall-20160731-56a31dc.diff b/dwm.suckless.org/patches/tagall/dwm-tagall-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-tagall-6.0.diff b/dwm.suckless.org/patches/tagall/dwm-tagall-6.0.diff diff --git a/dwm.suckless.org/patches/dwm-tagall-6.1.diff b/dwm.suckless.org/patches/tagall/dwm-tagall-6.1.diff diff --git a/dwm.suckless.org/patches/tagall/index.md b/dwm.suckless.org/patches/tagall/index.md @@ -0,0 +1,31 @@ +# tag all # + +## Description ## + +Shortcut to move all (floating) windows from one tag to another. + +## Download ## +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-tagall-20160731-56a31dc.diff](dwm-tagall-20160731-56a31dc.diff) + * [dwm-tagall-6.1.diff](dwm-tagall-6.1.diff) (1058b) (20140209) + * [dwm-10e232f9ace7-tagall.diff](dwm-10e232f9ace7-tagall.diff) (988b) (20120406) + * [dwm-tagall-6.0.diff](dwm-tagall-6.0.diff) (988b) (20120406) + +## Configuration ## + + * MODKEY+Shift+F1 moves all floating windows of the current tag to tag 1 + + { MODKEY|ShiftMask, XK_F1, tagall, {.v = "F1"} }, \ + ... + { MODKEY|ShiftMask, XK_F9, tagall, {.v = "F9"} }, \ + + * MODKEY+Shift+F1 moves all windows of the current tag to tag 1 + + { MODKEY|ShiftMask, XK_F1, tagall, {.v = "1"} }, \ + ... + { MODKEY|ShiftMask, XK_F9, tagall, {.v = "9"} }, \ + +## Author ## + * Jan Christoph Ebersbach - <jceb@e-jc.de> diff --git a/dwm.suckless.org/patches/taggrid.md b/dwm.suckless.org/patches/taggrid.md @@ -1,79 +0,0 @@ -taggrid -===== -Description ------------ -This patch adds an ability to place tags in rows like in many other -window managers like xfce ore OpenBox. - -Applying --------- -Patch uses drawtagmask flagset to show tags. Two flags can be applied to it: - - * `#define DRAWCLASSICTAGS 1 << 0` - - this will make patch to draw classic tags row; - - * `#define DRAWTAGGRID 1 << 1` - - this will make patch to draw the grid of tags like this: - -  - -The patch defines `switchtag` function which handle global shortcuts to -navigate in grid. This function accept unsigned int argument which represents -flagset of next flags: - - * `#define SWITCHTAG_UP 1 << 0` - - `#define SWITCHTAG_DOWN 1 << 1` - - `#define SWITCHTAG_LEFT 1 << 2` - - `#define SWITCHTAG_RIGHT 1 << 3` - - this four defines the direction of moving current tags; - - * `#define SWITCHTAG_TOGGLETAG 1 << 4` - - `#define SWITCHTAG_TAG 1 << 5` - - `#define SWITCHTAG_VIEW 1 << 6` - - `#define SWITCHTAG_TOGGLEVIEW 1 << 7` - - this four defines the behaviour of switching. They will make `switchtag` work - like according functions. - -Example -------- -Default config file defines nest: - - `{ MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } },` - - `{ MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } },` - - `{ MODKEY|ControlMask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_VIEW } },` - - `{ MODKEY|ControlMask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_VIEW } },` - -this will simply move set of active tags in specified (`UP`, `DOWN`, `RIGHT` or `LEFT`) direction by pressing `ctrl+alt+ARROW`; - - `{ MODKEY|Mod4Mask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` - - `{ MODKEY|Mod4Mask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` - - `{ MODKEY|Mod4Mask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` - - `{ MODKEY|Mod4Mask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` - -this will move active window in specified direction and perform the action, described above. - -Download --------- - - * [dwm-6.1-taggrid.diff](dwm-6.1-taggrid.diff) (2014-02-16) - -Author ------- - - * Yury Shvedov - [shved AT lvk DOT cs DOT msu DOT su](mailto:shved@lvk.cs.msu.su) (or [mestofel13 AT gmail DOT com](mailto:mestofel13@gmail.com)). diff --git a/dwm.suckless.org/patches/taggrid.png b/dwm.suckless.org/patches/taggrid.png Binary files differ. diff --git a/dwm.suckless.org/patches/dwm-6.1-taggrid.diff b/dwm.suckless.org/patches/taggrid/dwm-6.1-taggrid.diff diff --git a/dwm.suckless.org/patches/taggrid/index.md b/dwm.suckless.org/patches/taggrid/index.md @@ -0,0 +1,79 @@ +taggrid +===== +Description +----------- +This patch adds an ability to place tags in rows like in many other +window managers like xfce ore OpenBox. + +Applying +-------- +Patch uses drawtagmask flagset to show tags. Two flags can be applied to it: + + * `#define DRAWCLASSICTAGS 1 << 0` + + this will make patch to draw classic tags row; + + * `#define DRAWTAGGRID 1 << 1` + + this will make patch to draw the grid of tags like this: + +  + +The patch defines `switchtag` function which handle global shortcuts to +navigate in grid. This function accept unsigned int argument which represents +flagset of next flags: + + * `#define SWITCHTAG_UP 1 << 0` + + `#define SWITCHTAG_DOWN 1 << 1` + + `#define SWITCHTAG_LEFT 1 << 2` + + `#define SWITCHTAG_RIGHT 1 << 3` + + this four defines the direction of moving current tags; + + * `#define SWITCHTAG_TOGGLETAG 1 << 4` + + `#define SWITCHTAG_TAG 1 << 5` + + `#define SWITCHTAG_VIEW 1 << 6` + + `#define SWITCHTAG_TOGGLEVIEW 1 << 7` + + this four defines the behaviour of switching. They will make `switchtag` work + like according functions. + +Example +------- +Default config file defines nest: + + `{ MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } },` + + `{ MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } },` + + `{ MODKEY|ControlMask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_VIEW } },` + + `{ MODKEY|ControlMask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_VIEW } },` + +this will simply move set of active tags in specified (`UP`, `DOWN`, `RIGHT` or `LEFT`) direction by pressing `ctrl+alt+ARROW`; + + `{ MODKEY|Mod4Mask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` + + `{ MODKEY|Mod4Mask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` + + `{ MODKEY|Mod4Mask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` + + `{ MODKEY|Mod4Mask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_TAG | SWITCHTAG_VIEW } },` + +this will move active window in specified direction and perform the action, described above. + +Download +-------- + + * [dwm-6.1-taggrid.diff](dwm-6.1-taggrid.diff) (2014-02-16) + +Author +------ + + * Yury Shvedov - [shved AT lvk DOT cs DOT msu DOT su](mailto:shved@lvk.cs.msu.su) (or [mestofel13 AT gmail DOT com](mailto:mestofel13@gmail.com)). diff --git a/dwm.suckless.org/patches/taggrid/taggrid.png b/dwm.suckless.org/patches/taggrid/taggrid.png Binary files differ. diff --git a/dwm.suckless.org/patches/tagintostack.md b/dwm.suckless.org/patches/tagintostack.md @@ -1,21 +0,0 @@ -tagintostack -=============== - -Description ------------ -`tagintostack` new clients attach into the stack area when you toggle -a new tag into view. This means your master area will remain unchanged when -toggling views. -* the `allmaster` patch will cause all clients in the master area to be left -alone -* the `onemaster` patch will cause the first client in the master area to be left -alone (this is a much simpler piece of code) - -Download --------- -* [dwm-6.1-tagintostack-allmaster.diff](dwm-6.1-tagintostack-allmaster.diff) (568b) (20140306) -* [dwm-6.1-tagintostack-onemaster.diff](dwm-6.1-tagintostack-onemaster.diff) (1138b) (20140306) - -Author ------- -* Aaron Burrow - <burrows.labs@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-6.1-tagintostack-allmaster.diff b/dwm.suckless.org/patches/tagintostack/dwm-6.1-tagintostack-allmaster.diff diff --git a/dwm.suckless.org/patches/dwm-6.1-tagintostack-onemaster.diff b/dwm.suckless.org/patches/tagintostack/dwm-6.1-tagintostack-onemaster.diff diff --git a/dwm.suckless.org/patches/tagintostack/index.md b/dwm.suckless.org/patches/tagintostack/index.md @@ -0,0 +1,21 @@ +tagintostack +=============== + +Description +----------- +`tagintostack` new clients attach into the stack area when you toggle +a new tag into view. This means your master area will remain unchanged when +toggling views. +* the `allmaster` patch will cause all clients in the master area to be left +alone +* the `onemaster` patch will cause the first client in the master area to be left +alone (this is a much simpler piece of code) + +Download +-------- +* [dwm-6.1-tagintostack-allmaster.diff](dwm-6.1-tagintostack-allmaster.diff) (568b) (20140306) +* [dwm-6.1-tagintostack-onemaster.diff](dwm-6.1-tagintostack-onemaster.diff) (1138b) (20140306) + +Author +------ +* Aaron Burrow - <burrows.labs@gmail.com> diff --git a/dwm.suckless.org/patches/tcl.c b/dwm.suckless.org/patches/tcl.c @@ -1,74 +0,0 @@ -void -tcl(Monitor * m) -{ - int x, y, h, w, mw, sw, bdw; - unsigned int i, n; - Client * c; - - for (n = 0, c = nexttiled(m->clients); c; - c = nexttiled(c->next), n++); - - if (n == 0) - return; - - c = nexttiled(m->clients); - - mw = m->mfact * m->ww; - sw = (m->ww - mw) / 2; - bdw = (2 * c->bw); - resize(c, - n < 3 ? m->wx : m->wx + sw, - m->wy, - n == 1 ? m->ww - bdw : mw - bdw, - m->wh - bdw, - False); - - if (--n == 0) - return; - - w = (m->ww - mw) / ((n > 1) + 1); - c = nexttiled(c->next); - - if (n > 1) - { - x = m->wx + ((n > 1) ? mw + sw : mw); - y = m->wy; - h = m->wh / (n / 2); - - if (h < bh) - h = m->wh; - - for (i = 0; c && i < n / 2; c = nexttiled(c->next), i++) - { - resize(c, - x, - y, - w - bdw, - (i + 1 == n / 2) ? m->wy + m->wh - y - bdw : h - bdw, - False); - - if (h != m->wh) - y = c->y + HEIGHT(c); - } - } - - x = (n + 1 / 2) == 1 ? mw : m->wx; - y = m->wy; - h = m->wh / ((n + 1) / 2); - - if (h < bh) - h = m->wh; - - for (i = 0; c; c = nexttiled(c->next), i++) - { - resize(c, - x, - y, - (i + 1 == (n + 1) / 2) ? w - bdw : w - bdw, - (i + 1 == (n + 1) / 2) ? m->wy + m->wh - y - bdw : h - bdw, - False); - - if (h != m->wh) - y = c->y + HEIGHT(c); - } -} diff --git a/dwm.suckless.org/patches/three-column.md b/dwm.suckless.org/patches/three-column.md @@ -1,38 +0,0 @@ -# Three Column Layout - -## Description - -Three Column Layout (tcl) is a new layout with a wide master panel centered on the screen. - - +-----+-------------+-----+ - | | | | - |-----+ +-----+ - | | M | | - |-----+ +-----+ - | | | | - +-----+-------------+-----+ - -## Usage - - 1. Include the `tcl.c` source file and add `tcl` to the `Layout` section of your `config.h` file. - Example from `config.default.h`: - - #include "tcl.c" - static Layout layout[] = { \ - /* symbol function */ \ - { "[]=", tile }, /* first entry is default */ \ - { "><>", floating }, \ - { "|||", tcl }, \ - }; - -## Download - - * [tcl.c layout](tcl.c) - -## Maintainer - - * Chris Truett - <chris.truett@gmail.com> - -## Note - -This layout idea was found in a rough form in this [mailing list post](//lists.suckless.org/dev/1008/5506.html). diff --git a/dwm.suckless.org/patches/three-column/index.md b/dwm.suckless.org/patches/three-column/index.md @@ -0,0 +1,38 @@ +# Three Column Layout + +## Description + +Three Column Layout (tcl) is a new layout with a wide master panel centered on the screen. + + +-----+-------------+-----+ + | | | | + |-----+ +-----+ + | | M | | + |-----+ +-----+ + | | | | + +-----+-------------+-----+ + +## Usage + + 1. Include the `tcl.c` source file and add `tcl` to the `Layout` section of your `config.h` file. + Example from `config.default.h`: + + #include "tcl.c" + static Layout layout[] = { \ + /* symbol function */ \ + { "[]=", tile }, /* first entry is default */ \ + { "><>", floating }, \ + { "|||", tcl }, \ + }; + +## Download + + * [tcl.c layout](tcl.c) + +## Maintainer + + * Chris Truett - <chris.truett@gmail.com> + +## Note + +This layout idea was found in a rough form in this [mailing list post](//lists.suckless.org/dev/1008/5506.html). diff --git a/dwm.suckless.org/patches/three-column/tcl.c b/dwm.suckless.org/patches/three-column/tcl.c @@ -0,0 +1,74 @@ +void +tcl(Monitor * m) +{ + int x, y, h, w, mw, sw, bdw; + unsigned int i, n; + Client * c; + + for (n = 0, c = nexttiled(m->clients); c; + c = nexttiled(c->next), n++); + + if (n == 0) + return; + + c = nexttiled(m->clients); + + mw = m->mfact * m->ww; + sw = (m->ww - mw) / 2; + bdw = (2 * c->bw); + resize(c, + n < 3 ? m->wx : m->wx + sw, + m->wy, + n == 1 ? m->ww - bdw : mw - bdw, + m->wh - bdw, + False); + + if (--n == 0) + return; + + w = (m->ww - mw) / ((n > 1) + 1); + c = nexttiled(c->next); + + if (n > 1) + { + x = m->wx + ((n > 1) ? mw + sw : mw); + y = m->wy; + h = m->wh / (n / 2); + + if (h < bh) + h = m->wh; + + for (i = 0; c && i < n / 2; c = nexttiled(c->next), i++) + { + resize(c, + x, + y, + w - bdw, + (i + 1 == n / 2) ? m->wy + m->wh - y - bdw : h - bdw, + False); + + if (h != m->wh) + y = c->y + HEIGHT(c); + } + } + + x = (n + 1 / 2) == 1 ? mw : m->wx; + y = m->wy; + h = m->wh / ((n + 1) / 2); + + if (h < bh) + h = m->wh; + + for (i = 0; c; c = nexttiled(c->next), i++) + { + resize(c, + x, + y, + (i + 1 == (n + 1) / 2) ? w - bdw : w - bdw, + (i + 1 == (n + 1) / 2) ? m->wy + m->wh - y - bdw : h - bdw, + False); + + if (h != m->wh) + y = c->y + HEIGHT(c); + } +} diff --git a/dwm.suckless.org/patches/tilegap.md b/dwm.suckless.org/patches/tilegap.md @@ -1,16 +0,0 @@ -tilegap -======= - -Description ------------ -Window gaps for the tile layout done right (in my humble opinion). The -same size gap between master and stack, window and window, and window -and screen edge. Size configurable in config.h. - -Download --------- -- [dwm-tilegap-6.0.diff](dwm-tilegap-6.0.diff) (948b) (20150707) - -Author ------- -- Brandon Mulcahy - <brandon@jangler.info> diff --git a/dwm.suckless.org/patches/dwm-tilegap-6.0.diff b/dwm.suckless.org/patches/tilegap/dwm-tilegap-6.0.diff diff --git a/dwm.suckless.org/patches/tilegap/index.md b/dwm.suckless.org/patches/tilegap/index.md @@ -0,0 +1,16 @@ +tilegap +======= + +Description +----------- +Window gaps for the tile layout done right (in my humble opinion). The +same size gap between master and stack, window and window, and window +and screen edge. Size configurable in config.h. + +Download +-------- +- [dwm-tilegap-6.0.diff](dwm-tilegap-6.0.diff) (948b) (20150707) + +Author +------ +- Brandon Mulcahy - <brandon@jangler.info> diff --git a/dwm.suckless.org/patches/transparency.md b/dwm.suckless.org/patches/transparency.md @@ -1,15 +0,0 @@ -# transparency - -## Description - -This patch provides rudimentary experimentel transparency (xcompmgr needed). -Opacity is set for every not focused client, and also for focused client -when a rule is found. There may be Bugs. A lot of them. Creeeeepy! - -## Download - - * [dwm-transparency.diff](https://svn.0mark.unserver.de/dwm/trunk/patches/dwm-transparency.diff) latest transparency patch - -## Author - - * Stefan Mark - <0mark@unserver.de> diff --git a/dwm.suckless.org/patches/urgentborder.md b/dwm.suckless.org/patches/urgentborder.md @@ -1,15 +0,0 @@ -# custom urgent border - -## Description - -This patch makes borders of "urgent" windows a different color. -By default it is bright red. -Use config.h item "urgbordercolor" to change it. - -## Download - - * [dwm-6.1-urg-border.diff](dwm-6.1-urg-border.diff) (2.2K) (20150307) - -## Author - - * Alexander Huemer - alexander dot huemer dot xx dot vu (Based on former work by Ray Kohler - ataraxia937 gmail com) diff --git a/dwm.suckless.org/patches/dwm-6.1-urg-border.diff b/dwm.suckless.org/patches/urgentborder/dwm-6.1-urg-border.diff diff --git a/dwm.suckless.org/patches/urgentborder/index.md b/dwm.suckless.org/patches/urgentborder/index.md @@ -0,0 +1,15 @@ +# custom urgent border + +## Description + +This patch makes borders of "urgent" windows a different color. +By default it is bright red. +Use config.h item "urgbordercolor" to change it. + +## Download + + * [dwm-6.1-urg-border.diff](dwm-6.1-urg-border.diff) (2.2K) (20150307) + +## Author + + * Alexander Huemer - alexander dot huemer dot xx dot vu (Based on former work by Ray Kohler - ataraxia937 gmail com) diff --git a/dwm.suckless.org/patches/uselessgap.md b/dwm.suckless.org/patches/uselessgap.md @@ -1,64 +0,0 @@ -# useless gap - -## Description - -For aesthetic purposes, this patch: - -- adds "useless gaps" around windows -- removes everything (gaps and borders) when in monocle mode for aesthetic purpose. - -The size of the gap is configured in `config.h`: - -``` -static const unsigned int gappx = 6; /* gap pixel between windows */ -``` - -## Example - -No gaps: - - +-----------------+-------+ - | | | - | | | - | | | - | +-------| - | | | - | | | - | | | - +-----------------+-------+ - -With gaps around windows: - - +---------------------------+ - |+----------------++-------+| - || || || - || || || - || || || - || |+-------+| - || |+-------+| - || || || - || || || - || || || - |+----------------++-------+| - +---------------------------+ - -NB: there are some alternatives in the patches section, adding gaps between -windows, but not between windows and the screen borders, only in the default -tile mode... - - -## Download - - * [dwm-uselessgap-6.1.diff](dwm-uselessgap-6.1.diff) (4K) (20150815), now supports nmaster. - * [dwm-uselessgap-5.9.diff](dwm-uselessgap-5.9.diff) (1.8k) (20110107 updated. Thanks Jordan for your bug report) - - Updated to use the new resizeclient() function instead of resize() - - * [dwm-uselessgap-5.8.diff](historical/dwm-uselessgap-5.8.diff) (1.7k) (20100225 updated. Thanks Guillaume for your bug report) - Fix floating clients bug and remove all borders in monocle mode. - - * [dwm-gap-5.7.2.diff](historical/dwm-gap-5.7.2.diff) (0.7k) (20091215) - -## Author - -* [jerome](http://blog.jardinmagique.info) <jerome@gcu.info> diff --git a/dwm.suckless.org/patches/uselessgap/dwm-gap-5.7.2.diff b/dwm.suckless.org/patches/uselessgap/dwm-gap-5.7.2.diff @@ -0,0 +1,23 @@ +--- a/dwm.c 2009-09-17 10:48:57.000000000 +0200 ++++ b/dwm.c 2009-09-16 18:54:37.000000000 +0200 +@@ -1270,10 +1270,10 @@ + XWindowChanges wc; + + if(applysizehints(c, &x, &y, &w, &h, interact)) { +- c->x = wc.x = x; +- c->y = wc.y = y; +- c->w = wc.width = w; +- c->h = wc.height = h; ++ c->x = wc.x = x + gappx; ++ c->y = wc.y = y + gappx; ++ c->w = wc.width = w - 2 * gappx ; ++ c->h = wc.height = h - 2 * gappx ; + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + configure(c); + +diff -r 72e52c5333ef config.def.h +--- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 ++++ b/config.def.h Tue Dec 15 18:39:44 2009 +0100 +@@ -7,14 +7,15 @@ ++static const unsigned int gappx = 4; /* gap pixel between windows */ diff --git a/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.8.diff b/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.8.diff @@ -0,0 +1,49 @@ +diff -r 72e52c5333ef config.def.h +--- a/config.def.h Wed Nov 25 13:56:17 2009 +0000 ++++ b/config.def.h Thu Mar 11 16:32:24 2010 +0100 +@@ -9,6 +9,7 @@ + static const char selbgcolor[] = "#0066ff"; + static const char selfgcolor[] = "#ffffff"; + static const unsigned int borderpx = 1; /* border pixel of windows */ ++static const unsigned int gappx = 6; /* gap pixel between 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 */ +diff -r 72e52c5333ef dwm.c +--- a/dwm.c Wed Nov 25 13:56:17 2009 +0000 ++++ b/dwm.c Thu Mar 11 16:32:24 2010 +0100 +@@ -269,6 +269,7 @@ + static DC dc; + static Monitor *mons = NULL, *selmon = NULL; + static Window root; ++static int globalborder ; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -1299,16 +1300,21 @@ + resize(Client *c, int x, int y, int w, int h, Bool interact) { + XWindowChanges wc; + ++ if(c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) { globalborder = 0 ; } ++ else { ++ if (selmon->lt[selmon->sellt]->arrange == monocle) { globalborder = 0 - borderpx ; } ++ else { globalborder = gappx ; } ++ } + if(applysizehints(c, &x, &y, &w, &h, interact)) { +- c->x = wc.x = x; +- c->y = wc.y = y; +- c->w = wc.width = w; +- c->h = wc.height = h; ++ c->x = wc.x = x + globalborder; ++ c->y = wc.y = y + globalborder; ++ c->w = wc.width = w - 2 * globalborder ; ++ c->h = wc.height = h - 2 * globalborder ; + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + configure(c); + XSync(dpy, False); +- } ++ } + } + + void diff --git a/dwm.suckless.org/patches/dwm-uselessgap-5.9.diff b/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-uselessgap-6.1.diff b/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-6.1.diff diff --git a/dwm.suckless.org/patches/uselessgap/index.md b/dwm.suckless.org/patches/uselessgap/index.md @@ -0,0 +1,64 @@ +# useless gap + +## Description + +For aesthetic purposes, this patch: + +- adds "useless gaps" around windows +- removes everything (gaps and borders) when in monocle mode for aesthetic purpose. + +The size of the gap is configured in `config.h`: + +``` +static const unsigned int gappx = 6; /* gap pixel between windows */ +``` + +## Example + +No gaps: + + +-----------------+-------+ + | | | + | | | + | | | + | +-------| + | | | + | | | + | | | + +-----------------+-------+ + +With gaps around windows: + + +---------------------------+ + |+----------------++-------+| + || || || + || || || + || || || + || |+-------+| + || |+-------+| + || || || + || || || + || || || + |+----------------++-------+| + +---------------------------+ + +NB: there are some alternatives in the patches section, adding gaps between +windows, but not between windows and the screen borders, only in the default +tile mode... + + +## Download + + * [dwm-uselessgap-6.1.diff](dwm-uselessgap-6.1.diff) (4K) (20150815), now supports nmaster. + * [dwm-uselessgap-5.9.diff](dwm-uselessgap-5.9.diff) (1.8k) (20110107 updated. Thanks Jordan for your bug report) + + Updated to use the new resizeclient() function instead of resize() + + * [dwm-uselessgap-5.8.diff](dwm-uselessgap-5.8.diff) (1.7k) (20100225 updated. Thanks Guillaume for your bug report) + Fix floating clients bug and remove all borders in monocle mode. + + * [dwm-gap-5.7.2.diff](dwm-gap-5.7.2.diff) (0.7k) (20091215) + +## Author + +* [jerome](http://blog.jardinmagique.info) <jerome@gcu.info> diff --git a/dwm.suckless.org/patches/viewontag.md b/dwm.suckless.org/patches/viewontag.md @@ -1,14 +0,0 @@ -# viewontag - -## Description - - * follow a window to the tag it is being moved to - -## Download - - * [dwm-r1522-viewontag.diff](dwm-r1522-viewontag.diff) (dwm r1522) (20100725) - -## Author - - * Markus P. - peters_mops at arcor . de - diff --git a/dwm.suckless.org/patches/dwm-r1522-viewontag.diff b/dwm.suckless.org/patches/viewontag/dwm-r1522-viewontag.diff diff --git a/dwm.suckless.org/patches/viewontag/index.md b/dwm.suckless.org/patches/viewontag/index.md @@ -0,0 +1,14 @@ +# viewontag + +## Description + + * follow a window to the tag it is being moved to + +## Download + + * [dwm-r1522-viewontag.diff](dwm-r1522-viewontag.diff) (dwm r1522) (20100725) + +## Author + + * Markus P. - peters_mops at arcor . de + diff --git a/dwm.suckless.org/patches/warp.md b/dwm.suckless.org/patches/warp.md @@ -1,24 +0,0 @@ -warp -==== - -Description ------------ - -This patch warps the mouse cursor to the center of the currently focused window -or screen when the mouse cursor is (a) on a different screen or (b) on top of a -different window. - -Download --------- - -* [dwm-warp-5.9.diff](dwm-warp-5.9.diff) (20111028) -* [dwm-warp-6.1.diff](dwm-warp-6.1.diff) (20151215) -* [dwm-warp-git-20160626-7af4d43.diff](dwm-warp-git-20160626-7af4d43.diff) - -Author ------- - -* Evan Gates (emg) <evan.gates@gmail.com> -* Enno Boland (Gottox) -* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (don't warp in monocle) -* Winston Weinert (winny) <winston@ml1.net> diff --git a/dwm.suckless.org/patches/dwm-warp-5.9.diff b/dwm.suckless.org/patches/warp/dwm-warp-5.9.diff diff --git a/dwm.suckless.org/patches/dwm-warp-6.1.diff b/dwm.suckless.org/patches/warp/dwm-warp-6.1.diff diff --git a/dwm.suckless.org/patches/dwm-warp-git-20160626-7af4d43.diff b/dwm.suckless.org/patches/warp/dwm-warp-git-20160626-7af4d43.diff diff --git a/dwm.suckless.org/patches/warp/index.md b/dwm.suckless.org/patches/warp/index.md @@ -0,0 +1,24 @@ +warp +==== + +Description +----------- + +This patch warps the mouse cursor to the center of the currently focused window +or screen when the mouse cursor is (a) on a different screen or (b) on top of a +different window. + +Download +-------- + +* [dwm-warp-5.9.diff](dwm-warp-5.9.diff) (20111028) +* [dwm-warp-6.1.diff](dwm-warp-6.1.diff) (20151215) +* [dwm-warp-git-20160626-7af4d43.diff](dwm-warp-git-20160626-7af4d43.diff) + +Author +------ + +* Evan Gates (emg) <evan.gates@gmail.com> +* Enno Boland (Gottox) +* [Jochen Sprickerhof](mailto:project@firstname.lastname.de) (don't warp in monocle) +* Winston Weinert (winny) <winston@ml1.net> diff --git a/dwm.suckless.org/patches/winview.md b/dwm.suckless.org/patches/winview.md @@ -1,54 +0,0 @@ -Winview -======== - -Description ------------ - -Dwm tags are a powerfull feature that allows organizing windows in -workspaces. Sometime it can be difficult to remember the tag to activate to -unhide a window. With the winview patch the window to unhide can be selected -from the all-window view. The user switches to the all-window view (`Mod1-0`), -selects the window (`Mod1-j`/`k` or using the mouse) and press `Mod1-o`. The key -`Mod1-o` switches the view to the selected window tag. - -Recommend patches ------------------ - -The [grid](gridmode) layout is well adapted to display many windows in a limited -space. Using both [grid](gridmode) and [pertag](pertag) patches you will be able to -select this layout for the all-window view while keeping your preferred -layout for the other views. - -Configuration and Installation ------------------------------- - -#### Using the default configuration file - -* Make sure the directory where you build dwm does not contain a config.h file; -* Apply the patch; -* Run make and make install. - -#### Using an existing customised configuration file - -<ul> -<li>Apply the patch; -<li>Add the following element in the keys array: -</ul> - { MODKEY, XK_o, winview, {0} }, -<ul> -<li>Run make and make install. -</ul> - -An example of how to insert this line can be found in the default config file -template, config.def.h. - -Download --------- - - * [dwm-6.1-winview.diff](dwm-6.1-winview.diff) - * [dwm-6.0-winview.diff](historical/dwm-6.0-winview.diff) - -Author ------- - * Philippe Gras - `<philippe dot gras at free dot fr>` - diff --git a/dwm.suckless.org/patches/winview/dwm-6.0-winview.diff b/dwm.suckless.org/patches/winview/dwm-6.0-winview.diff @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 77ff358..3ba0efe 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -84,6 +84,7 @@ static Key keys[] = { + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ { MODKEY, XK_o, winview, {0} }, + }; + + /* button definitions */ +diff --git a/dwm.1 b/dwm.1 +index 5268a06..1188c82 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -104,6 +104,9 @@ Increase master area size. + .B Mod1\-h + Decrease master area size. + .TP ++.B Mod1\-o ++Select view of the window in focus. The list of tags to be displayed is matched to the window tag list. ++.TP + .B Mod1\-Return + Zooms/cycles focused window to/from master area (tiled layouts only). + .TP +diff --git a/dwm.c b/dwm.c +index 1d78655..abf944c 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -247,6 +247,7 @@ static void updatewmhints(Client *c); + static void view(const Arg *arg); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); ++static void winview(const Arg* arg); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); +@@ -2080,6 +2081,26 @@ wintomon(Window w) { + return selmon; + } + ++/* Selects for the view of the focused window. The list of tags */ ++/* to be displayed is matched to the focused window tag list. */ ++void ++winview(const Arg* arg){ ++ Window win, win_r, win_p, *win_c; ++ unsigned nc; ++ int unused; ++ Client* c; ++ Arg a; ++ ++ if (!XGetInputFocus(dpy, &win, &unused)) return; ++ while(XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc) ++ && win_p != win_r) win = win_p; ++ ++ if (!(c = wintoclient(win))) return; ++ ++ a.ui = c->tags; ++ view(&a); ++} ++ + /* 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-6.1-winview.diff b/dwm.suckless.org/patches/winview/dwm-6.1-winview.diff diff --git a/dwm.suckless.org/patches/winview/index.md b/dwm.suckless.org/patches/winview/index.md @@ -0,0 +1,54 @@ +winview +======== + +Description +----------- + +Dwm tags are a powerfull feature that allows organizing windows in +workspaces. Sometime it can be difficult to remember the tag to activate to +unhide a window. With the winview patch the window to unhide can be selected +from the all-window view. The user switches to the all-window view (`Mod1-0`), +selects the window (`Mod1-j`/`k` or using the mouse) and press `Mod1-o`. The key +`Mod1-o` switches the view to the selected window tag. + +Recommend patches +----------------- + +The [grid](gridmode) layout is well adapted to display many windows in a limited +space. Using both [grid](gridmode) and [pertag](pertag) patches you will be able to +select this layout for the all-window view while keeping your preferred +layout for the other views. + +Configuration and Installation +------------------------------ + +#### Using the default configuration file + +* Make sure the directory where you build dwm does not contain a config.h file; +* Apply the patch; +* Run make and make install. + +#### Using an existing customised configuration file + +<ul> +<li>Apply the patch; +<li>Add the following element in the keys array: +</ul> + { MODKEY, XK_o, winview, {0} }, +<ul> +<li>Run make and make install. +</ul> + +An example of how to insert this line can be found in the default config file +template, config.def.h. + +Download +-------- + + * [dwm-6.1-winview.diff](dwm-6.1-winview.diff) + * [dwm-6.0-winview.diff](dwm-6.0-winview.diff) + +Author +------ + * Philippe Gras - `<philippe dot gras at free dot fr>` + diff --git a/dwm.suckless.org/patches/xkb.md b/dwm.suckless.org/patches/xkb.md @@ -1,33 +0,0 @@ -xkb -===== -Description ------------ -This patch replaces main functionality of xxkb. It will remember the -client's xkb status and restores it when client became focused. - -Applying --------- -Firstly you have to configure xkb as you need as described -[here](http://www.x.org/archive/X11R7.5/doc/input/XKB-Config.html). -The patch depends on two variables: - - * `showxkb` flag defines, should patch show current xkb group on - the bar or not; - - * `xkb_layouts` array defines the text, which will appear on the - bar according to current group if `showxkb` set to `TRUE`. - -There is new field in Rule struckture, by witch you can specify -default xkb layout for window (see config.def.h for details). -This could be useful with dmenu_run, but unfortunately for some reasons -rules can't be applied to dmenu. - -Download --------- - - * [dwm-6.1-xkb.diff](dwm-6.1-xkb.diff) (2014-02-15) - -Author ------- - - * Yury Shvedov - [shved AT lvk DOT cs DOT msu DOT su](mailto:shved@lvk.cs.msu.su) (or [mestofel13 AT gmail DOT com](mailto:mestofel13@gmail.com)). diff --git a/dwm.suckless.org/patches/dwm-6.1-xkb.diff b/dwm.suckless.org/patches/xkb/dwm-6.1-xkb.diff diff --git a/dwm.suckless.org/patches/xkb/index.md b/dwm.suckless.org/patches/xkb/index.md @@ -0,0 +1,33 @@ +xkb +===== +Description +----------- +This patch replaces main functionality of xxkb. It will remember the +client's xkb status and restores it when client became focused. + +Applying +-------- +Firstly you have to configure xkb as you need as described +[here](http://www.x.org/archive/X11R7.5/doc/input/XKB-Config.html). +The patch depends on two variables: + + * `showxkb` flag defines, should patch show current xkb group on + the bar or not; + + * `xkb_layouts` array defines the text, which will appear on the + bar according to current group if `showxkb` set to `TRUE`. + +There is new field in Rule struckture, by witch you can specify +default xkb layout for window (see config.def.h for details). +This could be useful with dmenu_run, but unfortunately for some reasons +rules can't be applied to dmenu. + +Download +-------- + + * [dwm-6.1-xkb.diff](dwm-6.1-xkb.diff) (2014-02-15) + +Author +------ + + * Yury Shvedov - [shved AT lvk DOT cs DOT msu DOT su](mailto:shved@lvk.cs.msu.su) (or [mestofel13 AT gmail DOT com](mailto:mestofel13@gmail.com)). diff --git a/dwm.suckless.org/patches/xtile.md b/dwm.suckless.org/patches/xtile.md @@ -1,169 +0,0 @@ -Xtile -===== - -Description ------------ - -This patch implements a generalization of the tile layout which adds two attributes -(direction and fact) to three areas (global, master, stack). The global area is the entire -allocatable visual space and it's subdivided into the master and stack subareas. - -The direction of the global area controls the position of the master area relatively to -the stack area and it can be one of `DirHor` (traditional right stack), `DirVer` (bottom -stack), `DirRotHor` (left stack) and `DirRotVer` (top stack). The direction of the master -and of the stack areas are independently set and can be one of `DirHor` and `DirVer`. -This combines to a total of 4\*2\*2=16 layouts. - -The fact numbers indicate the relative size of the first subarea/client along the -direction of the considered area (i.e. width for `DirHor` and `DirRotHor` and height for -`DirVer` and `DirRotVer`). A fact of 1 means that the first subarea/client is on par the -rest, while a fact of 2 means that its size must double the size of each of the remaining -subareas/clients, etc. So the fact for the global area is similar to the traditional -mfact in the sense that it manages the relative allocation of visual space between the -master and stack subareas, while the fact for the master area stands for the relative -importance of the first master client against the rest of masters and, similarly, the fact -for the stack area stands for the importance of the first slave client in relation to the -rest of slaves. - -xtile adds two new commands to dwm: `setdir` and `setfact` (which supersedes `setmfact`). -Both commands take an array of three values (of type `int` for `setdir` and `float` for -`setfact`), one value for each area (the first one for the global area, the second one for -the master area and the third one for the stack area). If you pass the value `v` as -`INC(v)` it will be taken as a relative increment to be added to the current value, -otherwise it will be taken as an absolute value. Usually the resulting value will be -truncated to the valid range of values for each area/attribute combination, but relative -increments for directions wrap around the limits of the valid range. Notice that INC(0) -means "do nothing here", so it gives you a way to easily modify the value for some area -while leaving the rest untouched. - -Default key bindings --------------------- - -The areas are selected by modifiers as follows: - - Modifier | Area -----------------------|:-------------------------------: -`MODKEY` | Global -`MODKEY+Shift` | Master -`MODKEY+Control` | Stack -`MODKEY+Shift+Control`| All three areas simultaneously - -Each of the modifiers then combines with each of the following keys up to a total of -4\*3=12 key bindings: - - Key | Function -:------:|:-----------------------: - `r` | Rotate direction - `h` | Decrement fact by 10%. - `l` | Increment fact by 10%. - -There are two provided default "presets" or "schemas" also: - - Modifier | Key | Preset -------------------|:------:|:-------------: -`MODKEY+Shift` | `t` | Right stack -`MODKEY+Control` | `t` | Bottom stack - -These presets allow to quickly switch between different no-nonsense tilings avoiding the -need to rotate through all the nonsense combinations in-between. But notice that -`MODKEY+Shift+Control+r` (i.e. simultaneously rotate all three areas) usually produces -sensible layouts (due to the way directions were designed to rotate). - -You can also easily define your own presets by calling `setdir` and `setfact` as needed. -For example, here is the configuration code for the default presets described above: - - { MODKEY|ShiftMask, XK_t, setdirs, {.v = (int[]){ DirHor, DirVer, DirVer } } }, - { MODKEY|ControlMask, XK_t, setdirs, {.v = (int[]){ DirVer, DirHor, DirHor } } }, - -Layout symbol -------------- - -The layout symbol will probably look cryptic at first sight but it's very easily decoded. -It consists of three characters, one for the direction of each area: - -* Global area: '<', '>', 'v', '^', just think of it as an arrow that points in the - direction of the master area. - -* Master area: '|' for vertically tiled masters and '-' for horizontally tiled masters. - -* Stack area: same as for the master area. - -For example, '<||' stands for the default right stack tile provided by dwm and '^--' -stands for bstack (as defined by the bottom stack patch). - -Digressions ------------ - -### Why facts per area? - -There is some arbitrariness in the way facts are defined by xtile: why facts for the first -master and the first slave and not, say, for the first two clients instead? Considering -that most real life layouts will have one or two masters and a variable number of slaves, -the road xtile took will enable the user to effectively control the relative size of the -three/four most important clients in a very intuitive way that built on his previous -understanding of the mfact and the master and stack area concepts. OTOH it's not clear to -me how to allow the specification of facts for the first two clients in an intuitive way: - -* If there is only one master this alternative approach is equivalent to xtile's one. -* If there are two masters, only one fact will be required to specify the share of the - master area that belongs to each one, so what to do with the second fact? -* If this second fact is taken as the share of the second master vs the share of the - rest (the slaves), it's not clear how to define these inter-area shares. - -### Why not deck area? - -One obvious additional generalization would have been to extrapolate the nmaster idea to -all three areas, or at least to the stack area. So if you allowed only m masters and n -slaves you would end up with m+n tiled windows and with the rest of the clients in the -current tagset stacked or decked "below" the last tiled client. flextile, -clients-per-tag and deck patches provide variations on this kind of layout. I've also -implemented a version of xtile that supports it and even subsumes monocle, but I think -this promotes a bad pattern of usage. Coupled with stack manipulation operations as the -ones provided by the stacker or push patches, there is the temptation to manage visibility -by moving the desired clients in the current tagset to the first n+m visible positions of -the focus stack (not to be confused with the stack area). There are a number of problems -with this approach: - -* The stack is global to dwm, so pushing around clients in one tag will rearrange them in - other tags also. This could become a problem if you rely too much on explicit stack - management. - -* The deck area badly violates the principle of least surprise. If you only change focus - sequentially by using `mod-j`/`mod-k` there is no way to exit the deck at a client - different to the last/first decked one. If you use the mouse or the `focusstack` command - provided by the stacker patch to jump directly from the deck to a non-decked client, - each time you reach the deck again by using `mod-j`/`mod-k` the visible decked client - will be replaced by the first/last decked one. In general, there is a devilish interplay - of the focus stack and the z-stack that makes the deck unusable as a tabbed view of the - decked clients, at least for more than one or two decked clients. - -Fortunately, dwm provides a much better mechanism to restrict visibility: tags. IMO there -is no need to provide a half-assed alternative to one of dwm's strongest selling points. - -Other patches -------------- - -Recommended complementary patches: - -* [gaps](gaps): to add mostly useless gaps that nevertheless make more apparent which - client has the focus. - -* [stacker](stacker): to better accommodate the clients to the more elaborate layouts - allowed by xtile. But I would add: subject to the caveats that I've expressed above. - -Mandatory dependencies: - -* [pertag](pertag): we all know this one. - -Related patches: [bottom stack](bottomstack), [flextile](flextile), cfacts, -[stackmfact](stackmfact). - -Download --------- - -* [dwm-6.0-xtile.diff](dwm-6.0-xtile.diff) - -Author ------- - -* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/dwm-6.0-xtile.diff b/dwm.suckless.org/patches/xtile/dwm-6.0-xtile.diff diff --git a/dwm.suckless.org/patches/xtile/index.md b/dwm.suckless.org/patches/xtile/index.md @@ -0,0 +1,169 @@ +xtile +===== + +Description +----------- + +This patch implements a generalization of the tile layout which adds two attributes +(direction and fact) to three areas (global, master, stack). The global area is the entire +allocatable visual space and it's subdivided into the master and stack subareas. + +The direction of the global area controls the position of the master area relatively to +the stack area and it can be one of `DirHor` (traditional right stack), `DirVer` (bottom +stack), `DirRotHor` (left stack) and `DirRotVer` (top stack). The direction of the master +and of the stack areas are independently set and can be one of `DirHor` and `DirVer`. +This combines to a total of 4\*2\*2=16 layouts. + +The fact numbers indicate the relative size of the first subarea/client along the +direction of the considered area (i.e. width for `DirHor` and `DirRotHor` and height for +`DirVer` and `DirRotVer`). A fact of 1 means that the first subarea/client is on par the +rest, while a fact of 2 means that its size must double the size of each of the remaining +subareas/clients, etc. So the fact for the global area is similar to the traditional +mfact in the sense that it manages the relative allocation of visual space between the +master and stack subareas, while the fact for the master area stands for the relative +importance of the first master client against the rest of masters and, similarly, the fact +for the stack area stands for the importance of the first slave client in relation to the +rest of slaves. + +xtile adds two new commands to dwm: `setdir` and `setfact` (which supersedes `setmfact`). +Both commands take an array of three values (of type `int` for `setdir` and `float` for +`setfact`), one value for each area (the first one for the global area, the second one for +the master area and the third one for the stack area). If you pass the value `v` as +`INC(v)` it will be taken as a relative increment to be added to the current value, +otherwise it will be taken as an absolute value. Usually the resulting value will be +truncated to the valid range of values for each area/attribute combination, but relative +increments for directions wrap around the limits of the valid range. Notice that INC(0) +means "do nothing here", so it gives you a way to easily modify the value for some area +while leaving the rest untouched. + +Default key bindings +-------------------- + +The areas are selected by modifiers as follows: + + Modifier | Area +----------------------|:-------------------------------: +`MODKEY` | Global +`MODKEY+Shift` | Master +`MODKEY+Control` | Stack +`MODKEY+Shift+Control`| All three areas simultaneously + +Each of the modifiers then combines with each of the following keys up to a total of +4\*3=12 key bindings: + + Key | Function +:------:|:-----------------------: + `r` | Rotate direction + `h` | Decrement fact by 10%. + `l` | Increment fact by 10%. + +There are two provided default "presets" or "schemas" also: + + Modifier | Key | Preset +------------------|:------:|:-------------: +`MODKEY+Shift` | `t` | Right stack +`MODKEY+Control` | `t` | Bottom stack + +These presets allow to quickly switch between different no-nonsense tilings avoiding the +need to rotate through all the nonsense combinations in-between. But notice that +`MODKEY+Shift+Control+r` (i.e. simultaneously rotate all three areas) usually produces +sensible layouts (due to the way directions were designed to rotate). + +You can also easily define your own presets by calling `setdir` and `setfact` as needed. +For example, here is the configuration code for the default presets described above: + + { MODKEY|ShiftMask, XK_t, setdirs, {.v = (int[]){ DirHor, DirVer, DirVer } } }, + { MODKEY|ControlMask, XK_t, setdirs, {.v = (int[]){ DirVer, DirHor, DirHor } } }, + +Layout symbol +------------- + +The layout symbol will probably look cryptic at first sight but it's very easily decoded. +It consists of three characters, one for the direction of each area: + +* Global area: '<', '>', 'v', '^', just think of it as an arrow that points in the + direction of the master area. + +* Master area: '|' for vertically tiled masters and '-' for horizontally tiled masters. + +* Stack area: same as for the master area. + +For example, '<||' stands for the default right stack tile provided by dwm and '^--' +stands for bstack (as defined by the bottom stack patch). + +Digressions +----------- + +### Why facts per area? + +There is some arbitrariness in the way facts are defined by xtile: why facts for the first +master and the first slave and not, say, for the first two clients instead? Considering +that most real life layouts will have one or two masters and a variable number of slaves, +the road xtile took will enable the user to effectively control the relative size of the +three/four most important clients in a very intuitive way that built on his previous +understanding of the mfact and the master and stack area concepts. OTOH it's not clear to +me how to allow the specification of facts for the first two clients in an intuitive way: + +* If there is only one master this alternative approach is equivalent to xtile's one. +* If there are two masters, only one fact will be required to specify the share of the + master area that belongs to each one, so what to do with the second fact? +* If this second fact is taken as the share of the second master vs the share of the + rest (the slaves), it's not clear how to define these inter-area shares. + +### Why not deck area? + +One obvious additional generalization would have been to extrapolate the nmaster idea to +all three areas, or at least to the stack area. So if you allowed only m masters and n +slaves you would end up with m+n tiled windows and with the rest of the clients in the +current tagset stacked or decked "below" the last tiled client. flextile, +clients-per-tag and deck patches provide variations on this kind of layout. I've also +implemented a version of xtile that supports it and even subsumes monocle, but I think +this promotes a bad pattern of usage. Coupled with stack manipulation operations as the +ones provided by the stacker or push patches, there is the temptation to manage visibility +by moving the desired clients in the current tagset to the first n+m visible positions of +the focus stack (not to be confused with the stack area). There are a number of problems +with this approach: + +* The stack is global to dwm, so pushing around clients in one tag will rearrange them in + other tags also. This could become a problem if you rely too much on explicit stack + management. + +* The deck area badly violates the principle of least surprise. If you only change focus + sequentially by using `mod-j`/`mod-k` there is no way to exit the deck at a client + different to the last/first decked one. If you use the mouse or the `focusstack` command + provided by the stacker patch to jump directly from the deck to a non-decked client, + each time you reach the deck again by using `mod-j`/`mod-k` the visible decked client + will be replaced by the first/last decked one. In general, there is a devilish interplay + of the focus stack and the z-stack that makes the deck unusable as a tabbed view of the + decked clients, at least for more than one or two decked clients. + +Fortunately, dwm provides a much better mechanism to restrict visibility: tags. IMO there +is no need to provide a half-assed alternative to one of dwm's strongest selling points. + +Other patches +------------- + +Recommended complementary patches: + +* [gaps](gaps): to add mostly useless gaps that nevertheless make more apparent which + client has the focus. + +* [stacker](stacker): to better accommodate the clients to the more elaborate layouts + allowed by xtile. But I would add: subject to the caveats that I've expressed above. + +Mandatory dependencies: + +* [pertag](pertag): we all know this one. + +Related patches: [bottom stack](bottomstack), [flextile](flextile), cfacts, +[stackmfact](stackmfact). + +Download +-------- + +* [dwm-6.0-xtile.diff](dwm-6.0-xtile.diff) + +Author +------ + +* Carlos Pita (memeplex) <carlosjosepita@gmail.com> diff --git a/dwm.suckless.org/patches/zoomswap.md b/dwm.suckless.org/patches/zoomswap.md @@ -1,52 +0,0 @@ -zoomswap -======== - -Description ------------ -This patch swaps the current window (C) with the previous master (P) when zooming. - - Original behaviour : - +-----------------+-------+ - | | | - | | | - | | | - | P +-------| - | | | - | | C | - | | | - +-----------------+-------+ - - +-----------------+-------+ - | | | - | | P | - | | | - | C +-------| - | | | - | | | - | | | - +-----------------+-------+ - - - New Behaviour : - +-----------------+-------+ - | | | - | | | - | | | - | C +-------+ - | | | - | | P | - | | | - +-----------------+-------+ - -Download --------- -Patches against different versions of dwm are available at -[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). - - * [dwm-zoomswap-20160731-56a31dc.diff](dwm-zoomswap-20160731-56a31dc.diff) - * [dwm-6.1-zoomswap.diff](dwm-6.1-zoomswap.diff) (2585b) (20120406) - * [dwm-zoomswap-6.0.diff](dwm-zoomswap-6.0.diff) (1.6K) (20120406) - -Author ------- - * Jan Christoph Ebersbach - `<jceb at e-jc dot de>` diff --git a/dwm.suckless.org/patches/dwm-6.1-zoomswap.diff b/dwm.suckless.org/patches/zoomswap/dwm-6.1-zoomswap.diff diff --git a/dwm.suckless.org/patches/dwm-zoomswap-20160731-56a31dc.diff b/dwm.suckless.org/patches/zoomswap/dwm-zoomswap-20160731-56a31dc.diff diff --git a/dwm.suckless.org/patches/dwm-zoomswap-6.0.diff b/dwm.suckless.org/patches/zoomswap/dwm-zoomswap-6.0.diff diff --git a/dwm.suckless.org/patches/zoomswap/index.md b/dwm.suckless.org/patches/zoomswap/index.md @@ -0,0 +1,52 @@ +zoomswap +======== + +Description +----------- +This patch swaps the current window (C) with the previous master (P) when zooming. + + Original behaviour : + +-----------------+-------+ + | | | + | | | + | | | + | P +-------| + | | | + | | C | + | | | + +-----------------+-------+ + + +-----------------+-------+ + | | | + | | P | + | | | + | C +-------| + | | | + | | | + | | | + +-----------------+-------+ + + + New Behaviour : + +-----------------+-------+ + | | | + | | | + | | | + | C +-------+ + | | | + | | P | + | | | + +-----------------+-------+ + +Download +-------- +Patches against different versions of dwm are available at +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + + * [dwm-zoomswap-20160731-56a31dc.diff](dwm-zoomswap-20160731-56a31dc.diff) + * [dwm-6.1-zoomswap.diff](dwm-6.1-zoomswap.diff) (2585b) (20120406) + * [dwm-zoomswap-6.0.diff](dwm-zoomswap-6.0.diff) (1.6K) (20120406) + +Author +------ + * Jan Christoph Ebersbach - `<jceb at e-jc dot de>`