[wiki] [sites] Tidy up dwm patch section into subdirectories || Laslo Hunhold

From: <git_AT_suckless.org>
Date: Sun, 05 Nov 2017 01:46:14 +0100

commit 556f2aae56b5862dbd1194abd184b39d55b667ed
Author: Laslo Hunhold <dev_AT_frign.de>
Date: Sun Nov 5 01:45:15 2017 +0100

    Tidy up dwm patch section into subdirectories

diff --git a/dwm.suckless.org/patches/dwm-alpha-6.1.diff b/dwm.suckless.org/patches/alpha/dwm-alpha-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-alpha-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-alpha.png
rename to dwm.suckless.org/patches/alpha/dwm-alpha.png
diff --git a/dwm.suckless.org/patches/alpha.md b/dwm.suckless.org/patches/alpha/index.md
similarity index 100%
rename from dwm.suckless.org/patches/alpha.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-alwaysfullscreen-20160713-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-alwaysfullscreen-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/alwaysfullscreen.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-attachabove-20160713-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-attachabove-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-attachabove-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/attachabove.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-attachaside-20160718-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-attachaside-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/attachaside.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-autoresize-20160718-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-autoresize-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-autoresize-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/autoresize.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-autostart-20161205-bb3bd6f.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/autostart.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-bottomstack-20160719-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-bottomstack-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/bottomstack.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-center-20160719-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-center-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/center.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-centeredmaster-20160719-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-centeredmaster-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/centeredmaster.md
rename to dwm.suckless.org/patches/centeredmaster/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.1-cfacts.diff b/dwm.suckless.org/patches/cfacts/dwm-cfacts-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-cfacts.diff
rename to dwm.suckless.org/patches/cfacts/dwm-cfacts-6.1.diff
diff --git a/dwm.suckless.org/patches/cfacts.md b/dwm.suckless.org/patches/cfacts/index.md
similarity index 97%
rename from dwm.suckless.org/patches/cfacts.md
rename to dwm.suckless.org/patches/cfacts/index.md
index 7e255f52..8ae35aea 100644
--- a/dwm.suckless.org/patches/cfacts.md
+++ b/dwm.suckless.org/patches/cfacts/index.md
_AT_@ -48,7 +48,7 @@ Default key bindings
 Download
 --------
 
-* [dwm-6.1-cfacts.diff](dwm-6.1-cfacts.diff)
+* [dwm-cfacts-6.1.diff](dwm-cfacts-6.1.diff)
 
 Author
 ------
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-clientspertag-5.6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/clientspertag.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-columns-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/columns.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-combo-5.9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-combo-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-combo-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/combo.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-cropwindows-20170709-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/cropwindows.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-current_desktop-5.8.2.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/current_desktop.md
rename to dwm.suckless.org/patches/current_desktop/index.md
diff --git a/dwm.suckless.org/patches/dwm-deck-20170909-ceac8c9.diff b/dwm.suckless.org/patches/deck/dwm-deck-20170909-ceac8c9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-deck-20170909-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-deck.diff
rename to dwm.suckless.org/patches/deck/dwm-deck-6.0.diff
diff --git a/dwm.suckless.org/patches/deck.md b/dwm.suckless.org/patches/deck/index.md
similarity index 96%
rename from dwm.suckless.org/patches/deck.md
rename to dwm.suckless.org/patches/deck/index.md
index 216be851..7073a774 100644
--- a/dwm.suckless.org/patches/deck.md
+++ b/dwm.suckless.org/patches/deck/index.md
_AT_@ -31,7 +31,7 @@ Description
 
 Download
 --------
-* [dwm-6.0-deck.diff](dwm-6.0-deck.diff)
+* [dwm-deck-6.0.diff](dwm-deck-6.0.diff)
 * [dwm-deck-20170909-ceac8c9.diff](dwm-deck-20170909-ceac8c9.diff)
 
 
diff --git a/dwm.suckless.org/patches/dwm.defaultopacity.patch b/dwm.suckless.org/patches/defaulttransparency/dwm-defaulttransparency-r1521.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm.defaultopacity.patch
rename to dwm.suckless.org/patches/defaulttransparency/dwm-defaulttransparency-r1521.diff
diff --git a/dwm.suckless.org/patches/defaulttransparency.md b/dwm.suckless.org/patches/defaulttransparency/index.md
similarity index 86%
rename from dwm.suckless.org/patches/defaulttransparency.md
rename to dwm.suckless.org/patches/defaulttransparency/index.md
index 2ecc674a..acd76237 100644
--- a/dwm.suckless.org/patches/defaulttransparency.md
+++ b/dwm.suckless.org/patches/defaulttransparency/index.md
_AT_@ -15,7 +15,7 @@ It is based on the transparency patch of Stefan Mark.
 
 ## Download
 
- * [dwm.defaultopacity.patch](//dwm.suckless.org/patches/dwm.defaultopacity.patch)
+ * [dwm-defaulttransparency-r1521.diff](dwm-defaulttransparency-r1521.diff)
    latest patch (against r1521)
 
 ## Author
diff --git a/dwm.suckless.org/patches/dwm-dualstatus-6.0.diff b/dwm.suckless.org/patches/dualstatus/dwm-dualstatus-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-dualstatus-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-dualstatus-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-dualstatus.png
rename to dwm.suckless.org/patches/dualstatus/dwm-dualstatus.png
diff --git a/dwm.suckless.org/patches/dualstatus.md b/dwm.suckless.org/patches/dualstatus/index.md
similarity index 100%
rename from dwm.suckless.org/patches/dualstatus.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-dwmfifo-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwmfifo.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-emptyview-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/emptyview.md
rename to dwm.suckless.org/patches/emptyview/index.md
diff --git a/dwm.suckless.org/patches/dwm-r1606-exresize.diff b/dwm.suckless.org/patches/exresize/dwm-exresize-r1606.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1606-exresize.diff
rename to dwm.suckless.org/patches/exresize/dwm-exresize-r1606.diff
diff --git a/dwm.suckless.org/patches/exresize.md b/dwm.suckless.org/patches/exresize/index.md
similarity index 92%
rename from dwm.suckless.org/patches/exresize.md
rename to dwm.suckless.org/patches/exresize/index.md
index 01341c24..57688cff 100644
--- a/dwm.suckless.org/patches/exresize.md
+++ b/dwm.suckless.org/patches/exresize/index.md
_AT_@ -18,7 +18,7 @@ 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)
+ * [dwm-exresize-r1606.diff](dwm-exresize-r1606.diff) (Old patch, unknown version)
 
 Authors
 -------
diff --git a/dwm.suckless.org/patches/dwm-fakefullscreen-20170508-ceac8c9.diff b/dwm.suckless.org/patches/fakefullscreen/dwm-fakefullscreen-20170508-ceac8c9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-fakefullscreen-20170508-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/fakefullscreen.md
rename to dwm.suckless.org/patches/fakefullscreen/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-fancybar-5.6.1.diff b/dwm.suckless.org/patches/fancybar/dwm-fancybar-5.6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-fancybar-5.6.1.diff
rename to dwm.suckless.org/patches/fancybar/dwm-fancybar-5.6.1.diff
diff --git a/dwm.suckless.org/patches/dwm-fancybar-6.1.diff b/dwm.suckless.org/patches/fancybar/dwm-fancybar-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-fancybar-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-fancybar-git-20160725-7af4d43.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-winview.diff
rename to dwm.suckless.org/patches/fancybar/fancybar.png
diff --git a/dwm.suckless.org/patches/fancybar.md b/dwm.suckless.org/patches/fancybar/index.md
similarity index 79%
rename from dwm.suckless.org/patches/fancybar.md
rename to dwm.suckless.org/patches/fancybar/index.md
index a9b0d509..3ea1acba 100644
--- a/dwm.suckless.org/patches/fancybar.md
+++ b/dwm.suckless.org/patches/fancybar/index.md
_AT_@ -6,13 +6,13 @@ 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]
+[![Screenshot][fancybar.png]][fancybar.png]
 
 *Fancybar in action*
 
 ## Download
 
- * [dwm-fancybar-5.6.1.diff](historical/dwm-fancybar-5.6.1.diff)
+ * [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)
 
_AT_@ -22,5 +22,3 @@ fit, they're cropped. The title of the selected window is inverted.
  * [Jochen Sprickerhof](mailto:project_AT_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/dwm-6.1-fancybarclickable.diff b/dwm.suckless.org/patches/fancybarclickable/dwm-fancybarclickable-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-fancybarclickable.diff
rename to 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
new file mode 100644
index 00000000..1bddcdce
Binary files /dev/null and b/dwm.suckless.org/patches/fancybarclickable/fancybarclickable.png differ
diff --git a/dwm.suckless.org/patches/fancybarclickable.md b/dwm.suckless.org/patches/fancybarclickable/index.md
similarity index 66%
rename from dwm.suckless.org/patches/fancybarclickable.md
rename to dwm.suckless.org/patches/fancybarclickable/index.md
index 8f278663..aa340d9b 100644
--- a/dwm.suckless.org/patches/fancybarclickable.md
+++ b/dwm.suckless.org/patches/fancybarclickable/index.md
_AT_@ -8,17 +8,14 @@ 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]
+[![Screenshot][fancybarclickable.png]][fancybarclickable.png]
 
 Download
 --------
-* [dwm-6.1-fancybarclickable.diff](dwm-6.1-fancybarclickable.diff) (Unclean patch)
+* [dwm-fancybarclickable-6.1.diff](dwm-fancybarclickable-6.1.diff) (Unclean patch)
 
 Authors
 -------
-* Stefan Mark wrote [fancycoloredbarclickable](fancycoloredbarclickable.md).
-* Mate Nagy wrote [fancybar](fancybar.md).
+* Mate Nagy wrote [fancybar](../fancybar/).
 * 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/fancycoloredbarclickable.md b/dwm.suckless.org/patches/fancycoloredbarclickable.md
deleted file mode 100644
index 866b8b45..00000000
--- a/dwm.suckless.org/patches/fancycoloredbarclickable.md
+++ /dev/null
_AT_@ -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_AT_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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-fibonacci-5.8.2.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/fibonacci.md
rename to dwm.suckless.org/patches/fibonacci/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff b/dwm.suckless.org/patches/flextile/dwm-flextile-5.8.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-flextile-5.8.1.diff
rename to dwm.suckless.org/patches/flextile/dwm-flextile-5.8.1.diff
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-flextile-5.8.2.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/flextile.md
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-float_border_color-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-float_border_color-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-float_border_color2-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/float_border_color.md
rename to dwm.suckless.org/patches/float_border_color/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.0-focusadjacenttag.diff b/dwm.suckless.org/patches/focusadjacenttag/dwm-focusadjacenttag-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-focusadjacenttag.diff
rename to dwm.suckless.org/patches/focusadjacenttag/dwm-focusadjacenttag-6.0.diff
diff --git a/dwm.suckless.org/patches/focusadjacenttag.md b/dwm.suckless.org/patches/focusadjacenttag/index.md
similarity index 92%
rename from dwm.suckless.org/patches/focusadjacenttag.md
rename to dwm.suckless.org/patches/focusadjacenttag/index.md
index 8dcff8ff..f2786b44 100644
--- a/dwm.suckless.org/patches/focusadjacenttag.md
+++ b/dwm.suckless.org/patches/focusadjacenttag/index.md
_AT_@ -22,7 +22,7 @@ Download
 --------
 
 <!-- Author emailed about this issue already -->
- * [dwm-6.0-focusadjacenttag.diff](dwm-6.0-focusadjacenttag.diff) (Unclean patch)
+ * [dwm-focusadjacenttag-6.0.diff](dwm-focusadjacenttag-6.0.diff) (Unclean patch)
 
 Authors
 -------
diff --git a/dwm.suckless.org/patches/dwm-focusonclick-20171030-6aa8e37.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-20171030-6aa8e37.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-focusonclick-20171030-6aa8e37.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-focusonclick-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-focusonclick-bb3bd6f.diff
rename to dwm.suckless.org/patches/focusonclick/dwm-focusonclick-bb3bd6f.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-git-20100321-focusonclick.diff b/dwm.suckless.org/patches/focusonclick/dwm-focusonclick-git-20100321.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-git-20100321-focusonclick.diff
rename to dwm.suckless.org/patches/focusonclick/dwm-focusonclick-git-20100321.diff
diff --git a/dwm.suckless.org/patches/focusonclick.md b/dwm.suckless.org/patches/focusonclick/index.md
similarity index 88%
rename from dwm.suckless.org/patches/focusonclick.md
rename to dwm.suckless.org/patches/focusonclick/index.md
index 4bee0ec2..04fd905d 100644
--- a/dwm.suckless.org/patches/focusonclick.md
+++ b/dwm.suckless.org/patches/focusonclick/index.md
_AT_@ -9,7 +9,7 @@
  * [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)
+ * [dwm-focusonclick-git-20100321.diff](dwm-focusonclick-git-20100321.diff)
 
 ## Author
 
diff --git a/dwm.suckless.org/patches/dwm-focusurgent-20160831-56a31dc.diff b/dwm.suckless.org/patches/focusurgent/dwm-focusurgent-20160831-56a31dc.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-focusurgent-20160831-56a31dc.diff
rename to dwm.suckless.org/patches/focusurgent/dwm-focusurgent-20160831-56a31dc.diff
diff --git a/dwm.suckless.org/patches/focusurgent.md b/dwm.suckless.org/patches/focusurgent/index.md
similarity index 100%
rename from dwm.suckless.org/patches/focusurgent.md
rename to dwm.suckless.org/patches/focusurgent/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-5.2-gaplessgrid.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-5.2-gaplessgrid.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-5.2-gaplessgrid.diff
rename to dwm.suckless.org/patches/gaplessgrid/dwm-5.2-gaplessgrid.diff
diff --git a/dwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-gaplessgrid-20160731-56a31dc.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-gaplessgrid-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-gaplessgrid-6.1.diff
rename to dwm.suckless.org/patches/gaplessgrid/dwm-gaplessgrid-6.1.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-r1437-gaplessgrid.diff b/dwm.suckless.org/patches/gaplessgrid/dwm-r1437-gaplessgrid.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-r1437-gaplessgrid.diff
rename to dwm.suckless.org/patches/gaplessgrid/dwm-r1437-gaplessgrid.diff
diff --git a/dwm.suckless.org/patches/gaplessgrid.c b/dwm.suckless.org/patches/gaplessgrid/gaplessgrid.c
similarity index 100%
rename from dwm.suckless.org/patches/gaplessgrid.c
rename to dwm.suckless.org/patches/gaplessgrid/gaplessgrid.c
diff --git a/dwm.suckless.org/patches/gapless_grid.md b/dwm.suckless.org/patches/gaplessgrid/index.md
similarity index 78%
rename from dwm.suckless.org/patches/gapless_grid.md
rename to dwm.suckless.org/patches/gaplessgrid/index.md
index a9ea5122..8efbd7dc 100644
--- a/dwm.suckless.org/patches/gapless_grid.md
+++ b/dwm.suckless.org/patches/gaplessgrid/index.md
_AT_@ -27,7 +27,7 @@ Download `gaplessgrid.c` and add the gapless layout to your `config.h`:
 ## Download
 
 * [dwm-gaplessgrid-20160731-56a31dc.diff](dwm-gaplessgrid-20160731-56a31dc.diff)
-* [dwm-gaplessgrid-6.1.diff](dwm-gaplessgrid-6.1.diff) (1180b) (20140209)
+* [dwm-gaplessgrid-6.1.diff](dwm-gaplessgrid-6.1.diff) (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)
+* [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/dwm-gaps-6.0.diff b/dwm.suckless.org/patches/gaps/dwm-gaps-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-gaps-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-xtile-gaps.diff
rename to dwm.suckless.org/patches/gaps/dwm-gaps-xtile-6.0.diff
diff --git a/dwm.suckless.org/patches/gaps.md b/dwm.suckless.org/patches/gaps/index.md
similarity index 90%
rename from dwm.suckless.org/patches/gaps.md
rename to dwm.suckless.org/patches/gaps/index.md
index 1a28f9b6..389f739e 100644
--- a/dwm.suckless.org/patches/gaps.md
+++ b/dwm.suckless.org/patches/gaps/index.md
_AT_@ -1,5 +1,4 @@
-
-Gaps
+gaps
 ====
 
 Description
_AT_@ -19,7 +18,7 @@ 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)
+* For xtile tile: [dwm-gaps-xtile-6.0.diff](dwm-gaps-xtile-6.0.diff)
 
 Author
 ------
diff --git a/dwm.suckless.org/patches/dwm-5.8-gestures.diff b/dwm.suckless.org/patches/gestures/dwm-5.8-gestures.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-5.8-gestures.diff
rename to dwm.suckless.org/patches/gestures/dwm-5.8-gestures.diff
diff --git a/dwm.suckless.org/patches/gestures.md b/dwm.suckless.org/patches/gestures/index.md
similarity index 100%
rename from dwm.suckless.org/patches/gestures.md
rename to dwm.suckless.org/patches/gestures/index.md
diff --git a/dwm.suckless.org/patches/dwm-gridmode-20170909-ceac8c9.diff b/dwm.suckless.org/patches/gridmode/dwm-gridmode-20170909-ceac8c9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-gridmode-20170909-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-gridmode-5.8.2.diff
rename to dwm.suckless.org/patches/gridmode/dwm-gridmode-5.8.2.diff
diff --git a/dwm.suckless.org/patches/gridmode.md b/dwm.suckless.org/patches/gridmode/index.md
similarity index 100%
rename from dwm.suckless.org/patches/gridmode.md
rename to dwm.suckless.org/patches/gridmode/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-hide_vacant_tags-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-hide_vacant_tags-git-20160626-7af4d43.diff
rename to 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.md b/dwm.suckless.org/patches/hide_vacant_tags/index.md
similarity index 100%
rename from dwm.suckless.org/patches/hide_vacant_tags.md
rename to dwm.suckless.org/patches/hide_vacant_tags/index.md
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
deleted file mode 100644
index d9cc776a..00000000
--- a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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))
-_AT_@ -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 {
-_AT_@ -102,6 +102,7 @@ typedef struct {
- unsigned long norm[ColLast];
- unsigned long sel[ColLast];
- Drawable drawable;
-+ Drawable tabdrawable;
- GC gc;
- struct {
- int ascent;
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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]);
-_AT_@ -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);
- }
-
-_AT_@ -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)) {
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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 */
-_AT_@ -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);
-_AT_@ -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;
-
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -862,6 +1011,7 @@ focus(Client *c) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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;
-_AT_@ -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);
- }
- }
-
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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 {
-_AT_@ -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)
-_AT_@ -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;
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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();
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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
deleted file mode 100644
index 749e7740..00000000
--- a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2a.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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))
-_AT_@ -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 {
-_AT_@ -102,6 +102,7 @@ typedef struct {
- unsigned long norm[ColLast];
- unsigned long sel[ColLast];
- Drawable drawable;
-+ Drawable tabdrawable;
- GC gc;
- struct {
- int ascent;
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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]);
-_AT_@ -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);
- }
-
-_AT_@ -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)) {
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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 */
-_AT_@ -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);
-_AT_@ -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;
-
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -862,6 +1011,7 @@ focus(Client *c) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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;
-_AT_@ -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);
- }
- }
-
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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 {
-_AT_@ -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)
-_AT_@ -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;
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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();
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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
deleted file mode 100644
index 749e7740..00000000
--- a/dwm.suckless.org/patches/historical/dwm-6.0-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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))
-_AT_@ -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 {
-_AT_@ -102,6 +102,7 @@ typedef struct {
- unsigned long norm[ColLast];
- unsigned long sel[ColLast];
- Drawable drawable;
-+ Drawable tabdrawable;
- GC gc;
- struct {
- int ascent;
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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]);
-_AT_@ -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);
- }
-
-_AT_@ -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)) {
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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 */
-_AT_@ -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);
-_AT_@ -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;
-
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -862,6 +1011,7 @@ focus(Client *c) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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;
-_AT_@ -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);
- }
- }
-
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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 {
-_AT_@ -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)
-_AT_@ -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;
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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();
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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-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
deleted file mode 100644
index 2f3c921e..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-pertag-tab-v2a.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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 {
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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]; };
-
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -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);
- }
-_AT_@ -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
", sizeof(Monitor));
-_AT_@ -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
", 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;
- }
-
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -801,6 +974,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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);
-_AT_@ -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);
- }
-
-_AT_@ -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();
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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
-_AT_@ -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);
- }
-_AT_@ -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
deleted file mode 100644
index 7f571e5b..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2013-08-27_cdec978-tab-v2a.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -801,6 +943,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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();
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
deleted file mode 100644
index 58aade93..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-pertag-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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 {
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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]; };
-
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -517,6 +565,7 @@ void
- clientmessage(XEvent *e) {
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-+ int i;
-
- if(!c)
- return;
-_AT_@ -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);
- }
-_AT_@ -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);
- }
-_AT_@ -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
", sizeof(Monitor));
-_AT_@ -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
", 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;
- }
-
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -800,6 +979,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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);
-_AT_@ -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);
- }
-
-_AT_@ -1512,6 +1711,8 @@ setup(void) {
- if (!drw->fontcount)
- die("No fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
-+
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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
-_AT_@ -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);
- }
-_AT_@ -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
deleted file mode 100644
index fe30f378..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-03-05_14343e-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -800,6 +942,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -1512,6 +1671,8 @@ setup(void) {
- if (!drw->fontcount)
- die("No fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
-+
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
deleted file mode 100644
index aa5e9dd8..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-pertag-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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 {
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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]; };
-
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -516,6 +564,7 @@ void
- clientmessage(XEvent *e) {
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-+ int i;
-
- if(!c)
- return;
-_AT_@ -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);
- }
-_AT_@ -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);
- }
-_AT_@ -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
", 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;
- }
-
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -800,6 +979,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
- }
-
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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);
-_AT_@ -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);
- }
-
-_AT_@ -1511,6 +1710,8 @@ setup(void) {
- if (!drw->fontcount)
- die("no fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
-+
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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;
-_AT_@ -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);
- }
-_AT_@ -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
-_AT_@ -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);
- }
-_AT_@ -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
deleted file mode 100644
index c1fa336b..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-10-20_7e1182c-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 */
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -800,6 +942,7 @@ focus(Client *c) {
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- void
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -1511,6 +1670,8 @@ setup(void) {
- if (!drw->fontcount)
- die("no fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
-+
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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
deleted file mode 100644
index 33504afa..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-pertag-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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 {
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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]; };
-
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
-_AT_@ -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);
- }
-
-_AT_@ -526,6 +575,7 @@ clientmessage(XEvent *e)
- {
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-+ int i;
-
- if (!c)
- return;
-_AT_@ -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);
- }
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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
", 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;
- }
-
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -820,6 +995,7 @@ focus(Client *c)
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- /* there are some broken focus acquiring clients */
-_AT_@ -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)
- {
-_AT_@ -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);
- }
-
-_AT_@ -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);
- }
-_AT_@ -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;
-_AT_@ -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);
-_AT_@ -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 {
-_AT_@ -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)
-_AT_@ -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]);
- }
-_AT_@ -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);
-_AT_@ -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);
- }
-
-_AT_@ -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.
");
-+ die("No fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -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);
- }
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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);
- }
-_AT_@ -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
deleted file mode 100644
index 900bab68..00000000
--- a/dwm.suckless.org/patches/historical/dwm-master_2015-12-19_3465be-tab-v2b.diff
+++ /dev/null
_AT_@ -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
-_AT_@ -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" };
-_AT_@ -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 } },
-_AT_@ -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
-_AT_@ -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
-_AT_@ -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.
-_AT_@ -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
-_AT_@ -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 {
-_AT_@ -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];
- };
-
-_AT_@ -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);
-_AT_@ -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 *);
-_AT_@ -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 *) = {
-_AT_@ -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);
-_AT_@ -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
-_AT_@ -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);
- }
-
-_AT_@ -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);
-_AT_@ -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);
-_AT_@ -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;
-_AT_@ -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
-_AT_@ -820,6 +961,7 @@ focus(Client *c)
- }
- selmon->sel = c;
- drawbars();
-+ drawtabs();
- }
-
- /* there are some broken focus acquiring clients */
-_AT_@ -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)
- {
-_AT_@ -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);
-_AT_@ -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)
-_AT_@ -1566,6 +1724,8 @@ setup(void)
- if (!drw->fontcount)
- die("no fonts could be loaded.
");
- bh = drw->fonts[0]->h + 2;
-+ th = bh;
-+
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-_AT_@ -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)
-_AT_@ -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
-_AT_@ -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/dwm-horizgrid-6.1.diff b/dwm.suckless.org/patches/horizgrid/dwm-horizgrid-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-horizgrid-6.1.diff
rename to dwm.suckless.org/patches/horizgrid/dwm-horizgrid-6.1.diff
diff --git a/dwm.suckless.org/patches/horizgrid.md b/dwm.suckless.org/patches/horizgrid/index.md
similarity index 100%
rename from dwm.suckless.org/patches/horizgrid.md
rename to dwm.suckless.org/patches/horizgrid/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.0-ispermanent.diff b/dwm.suckless.org/patches/ispermanent/dwm-ispermanent-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-ispermanent.diff
rename to dwm.suckless.org/patches/ispermanent/dwm-ispermanent-6.0.diff
diff --git a/dwm.suckless.org/patches/ispermanent.md b/dwm.suckless.org/patches/ispermanent/index.md
similarity index 81%
rename from dwm.suckless.org/patches/ispermanent.md
rename to dwm.suckless.org/patches/ispermanent/index.md
index 17b8e08c..8891b30f 100644
--- a/dwm.suckless.org/patches/ispermanent.md
+++ b/dwm.suckless.org/patches/ispermanent/index.md
_AT_@ -10,7 +10,7 @@ windows.
 Download
 --------
 
-* [dwm-6.0-ispermanent.diff](dwm-6.0-ispermanent.diff)
+* [dwm-ispermanent-6.0.diff](dwm-ispermanent-6.0.diff)
 
 Author
 ------
diff --git a/dwm.suckless.org/patches/dwm-keycodes-20170511-ceac8c9.diff b/dwm.suckless.org/patches/keycodes/dwm-keycodes-20170511-ceac8c9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-keycodes-20170511-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-keycodes-6.1.diff
rename to dwm.suckless.org/patches/keycodes/dwm-keycodes-6.1.diff
diff --git a/dwm.suckless.org/patches/keycodes.md b/dwm.suckless.org/patches/keycodes/index.md
similarity index 100%
rename from dwm.suckless.org/patches/keycodes.md
rename to dwm.suckless.org/patches/keycodes/index.md
diff --git a/dwm.suckless.org/patches/keymodes-5.8.2.diff b/dwm.suckless.org/patches/keymodes/dwm-keymodes-5.8.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/keymodes-5.8.2.diff
rename to dwm.suckless.org/patches/keymodes/dwm-keymodes-5.8.2.diff
diff --git a/dwm.suckless.org/patches/keymodes-5.8.2-vim.diff b/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-5.8.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/keymodes-5.8.2-vim.diff
rename to dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-5.8.2.diff
diff --git a/dwm.suckless.org/patches/keymodes-5.8.2-vim-config.h b/dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-config.h
similarity index 100%
rename from dwm.suckless.org/patches/keymodes-5.8.2-vim-config.h
rename to dwm.suckless.org/patches/keymodes/dwm-keymodes-vim-config.h
diff --git a/dwm.suckless.org/patches/keymodes.md b/dwm.suckless.org/patches/keymodes/index.md
similarity index 88%
rename from dwm.suckless.org/patches/keymodes.md
rename to dwm.suckless.org/patches/keymodes/index.md
index 6a031903..bb0c5a97 100644
--- a/dwm.suckless.org/patches/keymodes.md
+++ b/dwm.suckless.org/patches/keymodes/index.md
_AT_@ -21,7 +21,7 @@ There are two different patches:
 
  (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].
+ (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 */
_AT_@ -46,10 +46,5 @@ With this patch dwm starts in `COMMANDMODE` and you can use the key bindings as
 
 ## 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
+ * [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/dwm-keypressrelease-6.0.diff b/dwm.suckless.org/patches/keypressrelease/dwm-keypressrelease-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-keypressrelease-6.0.diff
rename to dwm.suckless.org/patches/keypressrelease/dwm-keypressrelease-6.0.diff
diff --git a/dwm.suckless.org/patches/keypressrelease.md b/dwm.suckless.org/patches/keypressrelease/index.md
similarity index 90%
rename from dwm.suckless.org/patches/keypressrelease.md
rename to dwm.suckless.org/patches/keypressrelease/index.md
index 919c70d9..a10ef4ee 100644
--- a/dwm.suckless.org/patches/keypressrelease.md
+++ b/dwm.suckless.org/patches/keypressrelease/index.md
_AT_@ -25,7 +25,6 @@ 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
 ------
diff --git a/dwm.suckless.org/patches/dwm-killunsel-ceac8c91ff.diff b/dwm.suckless.org/patches/killunsel/dwm-killunsel-ceac8c91ff.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-killunsel-ceac8c91ff.diff
rename to dwm.suckless.org/patches/killunsel/dwm-killunsel-ceac8c91ff.diff
diff --git a/dwm.suckless.org/patches/killunsel.md b/dwm.suckless.org/patches/killunsel/index.md
similarity index 100%
rename from dwm.suckless.org/patches/killunsel.md
rename to dwm.suckless.org/patches/killunsel/index.md
diff --git a/dwm.suckless.org/patches/dwm-mark-6.1.diff b/dwm.suckless.org/patches/mark/dwm-mark-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-mark-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-mark-new-6.1.diff
rename to dwm.suckless.org/patches/mark/dwm-mark-new-6.1.diff
diff --git a/dwm.suckless.org/patches/mark.md b/dwm.suckless.org/patches/mark/index.md
similarity index 100%
rename from dwm.suckless.org/patches/mark.md
rename to dwm.suckless.org/patches/mark/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-maximize_vert_horz-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-maximize_vert_horz-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-maximize_vert_horz-6.1.diff
rename to dwm.suckless.org/patches/maximize/dwm-maximize_vert_horz-6.1.diff
diff --git a/dwm.suckless.org/patches/maximize.md b/dwm.suckless.org/patches/maximize/index.md
similarity index 100%
rename from dwm.suckless.org/patches/maximize.md
rename to dwm.suckless.org/patches/maximize/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-monocle_count-5.8.2.diff
rename to dwm.suckless.org/patches/monocle_count/dwm-monocle_count-5.8.2.diff
diff --git a/dwm.suckless.org/patches/monocle_count.md b/dwm.suckless.org/patches/monocle_count/index.md
similarity index 100%
rename from dwm.suckless.org/patches/monocle_count.md
rename to dwm.suckless.org/patches/monocle_count/index.md
diff --git a/dwm.suckless.org/patches/dwm-r1437-moveontagmon.diff b/dwm.suckless.org/patches/moveontagmon/dwm-r1437-moveontagmon.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1437-moveontagmon.diff
rename to dwm.suckless.org/patches/moveontagmon/dwm-r1437-moveontagmon.diff
diff --git a/dwm.suckless.org/patches/moveontagmon.md b/dwm.suckless.org/patches/moveontagmon/index.md
similarity index 100%
rename from dwm.suckless.org/patches/moveontagmon.md
rename to dwm.suckless.org/patches/moveontagmon/index.md
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff b/dwm.suckless.org/patches/moveresize/dwm-10e232f9ace7-moveresize.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-moveresize.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-moveresize-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-moveresize-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-moveresize-6.1.diff
rename to dwm.suckless.org/patches/moveresize/dwm-moveresize-6.1.diff
diff --git a/dwm.suckless.org/patches/moveresize.md b/dwm.suckless.org/patches/moveresize/index.md
similarity index 100%
rename from dwm.suckless.org/patches/moveresize.md
rename to dwm.suckless.org/patches/moveresize/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff b/dwm.suckless.org/patches/movestack/dwm-movestack-5.8.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-movestack-5.8.2.diff
rename to dwm.suckless.org/patches/movestack/dwm-movestack-5.8.2.diff
diff --git a/dwm.suckless.org/patches/dwm-movestack-6.1.diff b/dwm.suckless.org/patches/movestack/dwm-movestack-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-movestack-6.1.diff
rename to dwm.suckless.org/patches/movestack/dwm-movestack-6.1.diff
diff --git a/dwm.suckless.org/patches/movestack.md b/dwm.suckless.org/patches/movestack/index.md
similarity index 94%
rename from dwm.suckless.org/patches/movestack.md
rename to dwm.suckless.org/patches/movestack/index.md
index b78df80f..83555ed6 100644
--- a/dwm.suckless.org/patches/movestack.md
+++ b/dwm.suckless.org/patches/movestack/index.md
_AT_@ -24,7 +24,7 @@ movestack(-1) will swap the client with the current focus with the previous clie
 ## Download
 
  * [dwm-movestack-6.1.diff](dwm-movestack-6.1.diff)
- * [dwm-movestack-5.8.2.diff](historical/dwm-movestack-5.8.2.diff)
+ * [dwm-movestack-5.8.2.diff](dwm-movestack-5.8.2.diff)
 
 ## Author
 
diff --git a/dwm.suckless.org/patches/dwm-r1615-mpdcontrol.diff b/dwm.suckless.org/patches/mpdcontrol/dwm-r1615-mpdcontrol.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1615-mpdcontrol.diff
rename to dwm.suckless.org/patches/mpdcontrol/dwm-r1615-mpdcontrol.diff
diff --git a/dwm.suckless.org/patches/mpdcontrol.md b/dwm.suckless.org/patches/mpdcontrol/index.md
similarity index 100%
rename from dwm.suckless.org/patches/mpdcontrol.md
rename to dwm.suckless.org/patches/mpdcontrol/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-nametag-5.7.2.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-nametag-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-nametag-prepend-6.1.diff
rename to dwm.suckless.org/patches/nametag/dwm-nametag-prepend-6.1.diff
diff --git a/dwm.suckless.org/patches/nametag.md b/dwm.suckless.org/patches/nametag/index.md
similarity index 100%
rename from dwm.suckless.org/patches/nametag.md
rename to dwm.suckless.org/patches/nametag/index.md
diff --git a/dwm.suckless.org/patches/nextprev.md b/dwm.suckless.org/patches/nextprev/index.md
similarity index 100%
rename from dwm.suckless.org/patches/nextprev.md
rename to dwm.suckless.org/patches/nextprev/index.md
diff --git a/dwm.suckless.org/patches/nextprevtag.c b/dwm.suckless.org/patches/nextprev/nextprevtag.c
similarity index 100%
rename from dwm.suckless.org/patches/nextprevtag.c
rename to dwm.suckless.org/patches/nextprev/nextprevtag.c
diff --git a/dwm.suckless.org/patches/nmaster.md b/dwm.suckless.org/patches/nmaster/index.md
similarity index 99%
rename from dwm.suckless.org/patches/nmaster.md
rename to dwm.suckless.org/patches/nmaster/index.md
index 4b02568e..773b7793 100644
--- a/dwm.suckless.org/patches/nmaster.md
+++ b/dwm.suckless.org/patches/nmaster/index.md
_AT_@ -1,4 +1,4 @@
-# nmaster patch
+# nmaster
 
 ## History
 
diff --git a/dwm.suckless.org/patches/nmaster-ncol.c b/dwm.suckless.org/patches/nmaster/nmaster-ncol.c
similarity index 100%
rename from dwm.suckless.org/patches/nmaster-ncol.c
rename to dwm.suckless.org/patches/nmaster/nmaster-ncol.c
diff --git a/dwm.suckless.org/patches/nmaster-sym.c b/dwm.suckless.org/patches/nmaster/nmaster-sym.c
similarity index 100%
rename from dwm.suckless.org/patches/nmaster-sym.c
rename to dwm.suckless.org/patches/nmaster/nmaster-sym.c
diff --git a/dwm.suckless.org/patches/nmaster.c b/dwm.suckless.org/patches/nmaster/nmaster.c
similarity index 100%
rename from dwm.suckless.org/patches/nmaster.c
rename to dwm.suckless.org/patches/nmaster/nmaster.c
diff --git a/dwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff b/dwm.suckless.org/patches/noborder/dwm-noborder-20160718-56a31dc.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-noborder-20160718-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-noborder-20170207-bb3bd6f.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-noborder-6.1.diff
rename to dwm.suckless.org/patches/noborder/dwm-noborder-6.1.diff
diff --git a/dwm.suckless.org/patches/noborder.md b/dwm.suckless.org/patches/noborder/index.md
similarity index 100%
rename from dwm.suckless.org/patches/noborder.md
rename to dwm.suckless.org/patches/noborder/index.md
diff --git a/dwm.suckless.org/patches/dwm-pango-6.0.diff b/dwm.suckless.org/patches/pango/dwm-pango-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pango-6.0.diff
rename to dwm.suckless.org/patches/pango/dwm-pango-6.0.diff
diff --git a/dwm.suckless.org/patches/pango.md b/dwm.suckless.org/patches/pango/index.md
similarity index 100%
rename from dwm.suckless.org/patches/pango.md
rename to dwm.suckless.org/patches/pango/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-pertag_without_bar.diff b/dwm.suckless.org/patches/pertag/dwm-5.8.2-pertag_without_bar.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-5.8.2-pertag_without_bar.diff
rename to dwm.suckless.org/patches/pertag/dwm-5.8.2-pertag_without_bar.diff
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-pertag_without_bar.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-pertag_without_bar.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-git-20120406-pertag.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pertag-20170513-ceac8c9.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-20170513-ceac8c9.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.1.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.1.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.2.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.2.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.4.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.4.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.4.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.6.1.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.6.1.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.6.1.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.7.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.7.2.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.7.2.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-5.8.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-pertag-5.8.2.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-5.8.2.diff
diff --git a/dwm.suckless.org/patches/dwm-pertag-6.0.diff b/dwm.suckless.org/patches/pertag/dwm-pertag-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pertag-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pertag-6.1.diff
rename to dwm.suckless.org/patches/pertag/dwm-pertag-6.1.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-r1578-pertag.diff b/dwm.suckless.org/patches/pertag/dwm-r1578-pertag.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-r1578-pertag.diff
rename to dwm.suckless.org/patches/pertag/dwm-r1578-pertag.diff
diff --git a/dwm.suckless.org/patches/pertag.md b/dwm.suckless.org/patches/pertag/index.md
similarity index 82%
rename from dwm.suckless.org/patches/pertag.md
rename to dwm.suckless.org/patches/pertag/index.md
index 354cf8d9..56f14b36 100644
--- a/dwm.suckless.org/patches/pertag.md
+++ b/dwm.suckless.org/patches/pertag/index.md
_AT_@ -40,12 +40,12 @@ Authors
  * [Jochen Sprickerhof](mailto:project_AT_firstname.lastname.de) (Updated to current git)
  * Lucas Gabriel Vuotto - <lvuotto92_AT_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
+[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/dwm-6.0-push_no_master.diff b/dwm.suckless.org/patches/push/dwm-6.0-push_no_master.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-push_no_master.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-push_no_master.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-push-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-push-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-push-6.1.diff
rename to dwm.suckless.org/patches/push/dwm-push-6.1.diff
diff --git a/dwm.suckless.org/patches/push.md b/dwm.suckless.org/patches/push/index.md
similarity index 100%
rename from dwm.suckless.org/patches/push.md
rename to dwm.suckless.org/patches/push/index.md
diff --git a/dwm.suckless.org/patches/dwm-pwkl-5.9.diff b/dwm.suckless.org/patches/pwkl/dwm-pwkl-5.9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pwkl-5.9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-pwkl-6.1.diff
rename to dwm.suckless.org/patches/pwkl/dwm-pwkl-6.1.diff
diff --git a/dwm.suckless.org/patches/pwkl.md b/dwm.suckless.org/patches/pwkl/index.md
similarity index 100%
rename from dwm.suckless.org/patches/pwkl.md
rename to dwm.suckless.org/patches/pwkl/index.md
diff --git a/dwm.suckless.org/patches/dwm-resizecorners-6.0.diff b/dwm.suckless.org/patches/resizecorners/dwm-resizecorners-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-resizecorners-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-resizecorners-6.1.diff
rename to dwm.suckless.org/patches/resizecorners/dwm-resizecorners-6.1.diff
diff --git a/dwm.suckless.org/patches/resizecorners.md b/dwm.suckless.org/patches/resizecorners/index.md
similarity index 100%
rename from dwm.suckless.org/patches/resizecorners.md
rename to dwm.suckless.org/patches/resizecorners/index.md
diff --git a/dwm.suckless.org/patches/dwm-rmaster-6.1.diff b/dwm.suckless.org/patches/rmaster/dwm-rmaster-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-rmaster-6.1.diff
rename to dwm.suckless.org/patches/rmaster/dwm-rmaster-6.1.diff
diff --git a/dwm.suckless.org/patches/rmaster.md b/dwm.suckless.org/patches/rmaster/index.md
similarity index 100%
rename from dwm.suckless.org/patches/rmaster.md
rename to dwm.suckless.org/patches/rmaster/index.md
diff --git a/dwm.suckless.org/patches/dwm-rotatestack-20161021-ab9571b.diff b/dwm.suckless.org/patches/rotatestack/dwm-rotatestack-20161021-ab9571b.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-rotatestack-20161021-ab9571b.diff
rename to dwm.suckless.org/patches/rotatestack/dwm-rotatestack-20161021-ab9571b.diff
diff --git a/dwm.suckless.org/patches/rotatestack.md b/dwm.suckless.org/patches/rotatestack/index.md
similarity index 100%
rename from dwm.suckless.org/patches/rotatestack.md
rename to dwm.suckless.org/patches/rotatestack/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.1-runorraise.diff b/dwm.suckless.org/patches/runorraise/dwm-6.1-runorraise.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-runorraise.diff
rename to dwm.suckless.org/patches/runorraise/dwm-6.1-runorraise.diff
diff --git a/dwm.suckless.org/patches/runorraise.md b/dwm.suckless.org/patches/runorraise/index.md
similarity index 100%
rename from dwm.suckless.org/patches/runorraise.md
rename to dwm.suckless.org/patches/runorraise/index.md
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff b/dwm.suckless.org/patches/save_floats/dwm-10e232f9ace7-save_floats.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-save_floats.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-save_floats.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-save_floats-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-savefloats-20160723-56a31dc.diff
rename to dwm.suckless.org/patches/save_floats/dwm-savefloats-20160723-56a31dc.diff
diff --git a/dwm.suckless.org/patches/save_floats.md b/dwm.suckless.org/patches/save_floats/index.md
similarity index 100%
rename from dwm.suckless.org/patches/save_floats.md
rename to dwm.suckless.org/patches/save_floats/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-schemeSwitch-20170804-ceac8c9.diff
rename to dwm.suckless.org/patches/scheme_switch/dwm-scheme_switch-20170804-ceac8c9.diff
diff --git a/dwm.suckless.org/patches/schemeSwitch.md b/dwm.suckless.org/patches/scheme_switch/index.md
similarity index 92%
rename from dwm.suckless.org/patches/schemeSwitch.md
rename to dwm.suckless.org/patches/scheme_switch/index.md
index 353c4274..1ac096f7 100644
--- a/dwm.suckless.org/patches/schemeSwitch.md
+++ b/dwm.suckless.org/patches/scheme_switch/index.md
_AT_@ -22,7 +22,7 @@ scheme, then schemeToggle() would toggle between original and the consecutive.
 
 Download
 --------
- * [dwm-schemeSwitch-20170804-ceac8c9.diff](dwm-schemeSwitch-20170804-ceac8c9.diff)
+ * [dwm-scheme_switch-20170804-ceac8c9.diff](dwm-scheme_switch-20170804-ceac8c9.diff)
 
 
 Authors
diff --git a/dwm.suckless.org/patches/dwm-scratchpad-20170207-bb3bd6f.diff b/dwm.suckless.org/patches/scratchpad/dwm-scratchpad-20170207-bb3bd6f.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-scratchpad-20170207-bb3bd6f.diff
rename to dwm.suckless.org/patches/scratchpad/dwm-scratchpad-20170207-bb3bd6f.diff
diff --git a/dwm.suckless.org/patches/scratchpad.md b/dwm.suckless.org/patches/scratchpad/index.md
similarity index 100%
rename from dwm.suckless.org/patches/scratchpad.md
rename to dwm.suckless.org/patches/scratchpad/index.md
diff --git a/dwm.suckless.org/patches/dwm-r1615-selfrestart.diff b/dwm.suckless.org/patches/selfrestart/dwm-r1615-selfrestart.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1615-selfrestart.diff
rename to dwm.suckless.org/patches/selfrestart/dwm-r1615-selfrestart.diff
diff --git a/dwm.suckless.org/patches/selfrestart.md b/dwm.suckless.org/patches/selfrestart/index.md
similarity index 100%
rename from dwm.suckless.org/patches/selfrestart.md
rename to dwm.suckless.org/patches/selfrestart/index.md
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff b/dwm.suckless.org/patches/single_tagset/dwm-10e232f9ace7-single_tagset.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-single_tagset.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-single_tagset.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-single_tagset-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-single_tagset-6.0.diff
rename to dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.0.diff
diff --git a/dwm.suckless.org/patches/single_tagset.md b/dwm.suckless.org/patches/single_tagset/index.md
similarity index 68%
rename from dwm.suckless.org/patches/single_tagset.md
rename to dwm.suckless.org/patches/single_tagset/index.md
index 59c9b6cc..6ff32016 100644
--- a/dwm.suckless.org/patches/single_tagset.md
+++ b/dwm.suckless.org/patches/single_tagset/index.md
_AT_@ -29,25 +29,6 @@ Patches against different versions of dwm are available at
  * [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_AT_e-jc.de>
diff --git a/dwm.suckless.org/patches/dwm-6.0-singularborders.diff b/dwm.suckless.org/patches/singularborders/dwm-6.0-singularborders.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-singularborders.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-singularborders_bstack.diff
rename to dwm.suckless.org/patches/singularborders/dwm-6.0-singularborders_bstack.diff
diff --git a/dwm.suckless.org/patches/singularborders.md b/dwm.suckless.org/patches/singularborders/index.md
similarity index 97%
rename from dwm.suckless.org/patches/singularborders.md
rename to dwm.suckless.org/patches/singularborders/index.md
index 41a7ec44..bfc75049 100644
--- a/dwm.suckless.org/patches/singularborders.md
+++ b/dwm.suckless.org/patches/singularborders/index.md
_AT_@ -1,5 +1,5 @@
-\singular borders
-===========
+singular borders
+================
 
 Description
 -----------
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-sizehints-5.7.2.diff
rename to dwm.suckless.org/patches/sizehints/dwm-sizehints-5.7.2.diff
diff --git a/dwm.suckless.org/patches/sizehints.md b/dwm.suckless.org/patches/sizehints/index.md
similarity index 100%
rename from dwm.suckless.org/patches/sizehints.md
rename to dwm.suckless.org/patches/sizehints/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-5.9.1-spawn_cwd.diff
rename to dwm.suckless.org/patches/spawn_cwd/dwm-5.9.1-spawn_cwd.diff
diff --git a/dwm.suckless.org/patches/spawn_cwd.md b/dwm.suckless.org/patches/spawn_cwd/index.md
similarity index 82%
rename from dwm.suckless.org/patches/spawn_cwd.md
rename to dwm.suckless.org/patches/spawn_cwd/index.md
index 11f15077..59b75657 100644
--- a/dwm.suckless.org/patches/spawn_cwd.md
+++ b/dwm.suckless.org/patches/spawn_cwd/index.md
_AT_@ -9,7 +9,7 @@ for more information.
 
 ## Download
 
- * [spawn_cwd.diff](dwm-5.9.1-spawn_cwd.diff) spawn_cwd.diff (2011-11-25)
+ * [dwm-5.9.1-spawn_cwd.diff](dwm-5.9.1-spawn_cwd.diff)
 
 ## Author
 
diff --git a/dwm.suckless.org/patches/dwm-stacker-6.0.diff b/dwm.suckless.org/patches/stacker/dwm-stacker-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-stacker-6.0.diff
rename to dwm.suckless.org/patches/stacker/dwm-stacker-6.0.diff
diff --git a/dwm.suckless.org/patches/stacker.md b/dwm.suckless.org/patches/stacker/index.md
similarity index 99%
rename from dwm.suckless.org/patches/stacker.md
rename to dwm.suckless.org/patches/stacker/index.md
index ee14977f..6b88e024 100644
--- a/dwm.suckless.org/patches/stacker.md
+++ b/dwm.suckless.org/patches/stacker/index.md
_AT_@ -1,4 +1,4 @@
-Stacker
+stacker
 =======
 
 Description
diff --git a/dwm.suckless.org/patches/dwm-6.0-smfact.diff b/dwm.suckless.org/patches/stackmfact/dwm-6.0-smfact.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-smfact.diff
rename to dwm.suckless.org/patches/stackmfact/dwm-6.0-smfact.diff
diff --git a/dwm.suckless.org/patches/stackmfact.md b/dwm.suckless.org/patches/stackmfact/index.md
similarity index 100%
rename from dwm.suckless.org/patches/stackmfact.md
rename to dwm.suckless.org/patches/stackmfact/index.md
diff --git a/dwm.suckless.org/patches/dwm-status2d-20161231-bb3bd6f.diff b/dwm.suckless.org/patches/status2d/dwm-status2d-20161231-bb3bd6f.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-status2d-20161231-bb3bd6f.diff
rename to dwm.suckless.org/patches/status2d/dwm-status2d-20161231-bb3bd6f.diff
diff --git a/dwm.suckless.org/patches/status2d.md b/dwm.suckless.org/patches/status2d/index.md
similarity index 86%
rename from dwm.suckless.org/patches/status2d.md
rename to dwm.suckless.org/patches/status2d/index.md
index bc36a160..178d90d4 100644
--- a/dwm.suckless.org/patches/status2d.md
+++ b/dwm.suckless.org/patches/status2d/index.md
_AT_@ -1,4 +1,4 @@
-Status2d
+status2d
 ========
 
 Description
_AT_@ -11,7 +11,6 @@ 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)
 
 
diff --git a/dwm.suckless.org/patches/status2d.png b/dwm.suckless.org/patches/status2d/status2d.png
similarity index 100%
rename from dwm.suckless.org/patches/status2d.png
rename to dwm.suckless.org/patches/status2d/status2d.png
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff b/dwm.suckless.org/patches/statusallmons/dwm-10e232f9ace7-statusallmons.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-statusallmons.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-statusallmons.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-statusallmons-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-statusallmons-5.8.2.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-statusallmons-6.0.diff
rename to dwm.suckless.org/patches/statusallmons/dwm-statusallmons-6.0.diff
diff --git a/dwm.suckless.org/patches/statusallmons.md b/dwm.suckless.org/patches/statusallmons/index.md
similarity index 100%
rename from dwm.suckless.org/patches/statusallmons.md
rename to dwm.suckless.org/patches/statusallmons/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-5.7.2-statuscolors.diff b/dwm.suckless.org/patches/statuscolors/dwm-5.7.2-statuscolors.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-5.7.2-statuscolors.diff
rename to dwm.suckless.org/patches/statuscolors/dwm-5.7.2-statuscolors.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-5.8.2-statuscolors.diff b/dwm.suckless.org/patches/statuscolors/dwm-5.8.2-statuscolors.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-5.8.2-statuscolors.diff
rename to dwm.suckless.org/patches/statuscolors/dwm-5.8.2-statuscolors.diff
diff --git a/dwm.suckless.org/patches/dwm-statuscolors-5.9.diff b/dwm.suckless.org/patches/statuscolors/dwm-statuscolors-5.9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-statuscolors-5.9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-statuscolors-6.1.diff
rename to dwm.suckless.org/patches/statuscolors/dwm-statuscolors-6.1.diff
diff --git a/dwm.suckless.org/patches/statuscolors.md b/dwm.suckless.org/patches/statuscolors/index.md
similarity index 94%
rename from dwm.suckless.org/patches/statuscolors.md
rename to dwm.suckless.org/patches/statuscolors/index.md
index 0c07c2fa..51177c51 100644
--- a/dwm.suckless.org/patches/statuscolors.md
+++ b/dwm.suckless.org/patches/statuscolors/index.md
_AT_@ -56,7 +56,7 @@ An example status script snippet to take advantage of the colors:
 
 ## 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-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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-5.7.2-statuscolors.png
rename to dwm.suckless.org/patches/statuscolors/statuscolors.png
diff --git a/dwm.suckless.org/patches/dwm-r1533-stdin.diff b/dwm.suckless.org/patches/stdin/dwm-r1533-stdin.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1533-stdin.diff
rename to dwm.suckless.org/patches/stdin/dwm-r1533-stdin.diff
diff --git a/dwm.suckless.org/patches/stdin.md b/dwm.suckless.org/patches/stdin/index.md
similarity index 100%
rename from dwm.suckless.org/patches/stdin.md
rename to dwm.suckless.org/patches/stdin/index.md
diff --git a/dwm.suckless.org/patches/dwm-sticky-20160911-ab9571b.diff b/dwm.suckless.org/patches/sticky/dwm-sticky-20160911-ab9571b.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-sticky-20160911-ab9571b.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-sticky-6.1.diff
rename to dwm.suckless.org/patches/sticky/dwm-sticky-6.1.diff
diff --git a/dwm.suckless.org/patches/sticky.md b/dwm.suckless.org/patches/sticky/index.md
similarity index 100%
rename from dwm.suckless.org/patches/sticky.md
rename to dwm.suckless.org/patches/sticky/index.md
diff --git a/dwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff b/dwm.suckless.org/patches/swallow/dwm-swallow-20160717-56a31dc.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-swallow-20160717-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-swallow-20170909-ceac8c9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-swallow-6.1.diff
rename to dwm.suckless.org/patches/swallow/dwm-swallow-6.1.diff
diff --git a/dwm.suckless.org/patches/swallow.md b/dwm.suckless.org/patches/swallow/index.md
similarity index 100%
rename from dwm.suckless.org/patches/swallow.md
rename to dwm.suckless.org/patches/swallow/index.md
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff b/dwm.suckless.org/patches/swapfocus/dwm-10e232f9ace7-swapfocus.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-swapfocus.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-5.8.2-swap.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-swapfocus.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-swapfocus-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-swapfocus-6.0.diff
rename to dwm.suckless.org/patches/swapfocus/dwm-swapfocus-6.0.diff
diff --git a/dwm.suckless.org/patches/swapfocus.md b/dwm.suckless.org/patches/swapfocus/index.md
similarity index 100%
rename from dwm.suckless.org/patches/swapfocus.md
rename to dwm.suckless.org/patches/swapfocus/index.md
diff --git a/dwm.suckless.org/patches/dwm-switchcol-6.1.diff b/dwm.suckless.org/patches/switchcol/dwm-switchcol-6.1.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-switchcol-6.1.diff
rename to dwm.suckless.org/patches/switchcol/dwm-switchcol-6.1.diff
diff --git a/dwm.suckless.org/patches/switchcol.md b/dwm.suckless.org/patches/switchcol/index.md
similarity index 100%
rename from dwm.suckless.org/patches/switchcol.md
rename to dwm.suckless.org/patches/switchcol/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.1-systray.diff b/dwm.suckless.org/patches/systray/dwm-6.1-systray.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-systray.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-git-20130119-systray.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-git-20160103-systray.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-systray-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-systray-20161218-bb3bd6f.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-systray-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-systray-git-20160626-7af4d43.diff
rename to dwm.suckless.org/patches/systray/dwm-systray-git-20160626-7af4d43.diff
diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray/index.md
similarity index 100%
rename from dwm.suckless.org/patches/systray.md
rename to dwm.suckless.org/patches/systray/index.md
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-pertag-tab-v2b.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-tab-v2b.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tab-v2b-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tab-v2b-pertab-56a31dc.diff
rename to dwm.suckless.org/patches/tab/dwm-tab-v2b-pertab-56a31dc.diff
diff --git a/dwm.suckless.org/patches/tab.md b/dwm.suckless.org/patches/tab/index.md
similarity index 83%
rename from dwm.suckless.org/patches/tab.md
rename to dwm.suckless.org/patches/tab/index.md
index 47192e90..7a42c676 100644
--- a/dwm.suckless.org/patches/tab.md
+++ b/dwm.suckless.org/patches/tab/index.md
_AT_@ -1,4 +1,4 @@
-Tab
+tab
 ===
 
 Description
_AT_@ -123,18 +123,6 @@ Download
    * 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
 ----------
 
diff --git a/dwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff b/dwm.suckless.org/patches/tagall/dwm-10e232f9ace7-tagall.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-10e232f9ace7-tagall.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tagall-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tagall-6.0.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tagall-6.1.diff
rename to dwm.suckless.org/patches/tagall/dwm-tagall-6.1.diff
diff --git a/dwm.suckless.org/patches/tagall.md b/dwm.suckless.org/patches/tagall/index.md
similarity index 100%
rename from dwm.suckless.org/patches/tagall.md
rename to dwm.suckless.org/patches/tagall/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.1-taggrid.diff b/dwm.suckless.org/patches/taggrid/dwm-6.1-taggrid.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-taggrid.diff
rename to dwm.suckless.org/patches/taggrid/dwm-6.1-taggrid.diff
diff --git a/dwm.suckless.org/patches/taggrid.md b/dwm.suckless.org/patches/taggrid/index.md
similarity index 100%
rename from dwm.suckless.org/patches/taggrid.md
rename to dwm.suckless.org/patches/taggrid/index.md
diff --git a/dwm.suckless.org/patches/taggrid.png b/dwm.suckless.org/patches/taggrid/taggrid.png
similarity index 100%
rename from dwm.suckless.org/patches/taggrid.png
rename to dwm.suckless.org/patches/taggrid/taggrid.png
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-tagintostack-allmaster.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-tagintostack-onemaster.diff
rename to dwm.suckless.org/patches/tagintostack/dwm-6.1-tagintostack-onemaster.diff
diff --git a/dwm.suckless.org/patches/tagintostack.md b/dwm.suckless.org/patches/tagintostack/index.md
similarity index 100%
rename from dwm.suckless.org/patches/tagintostack.md
rename to dwm.suckless.org/patches/tagintostack/index.md
diff --git a/dwm.suckless.org/patches/three-column.md b/dwm.suckless.org/patches/three-column/index.md
similarity index 100%
rename from dwm.suckless.org/patches/three-column.md
rename to dwm.suckless.org/patches/three-column/index.md
diff --git a/dwm.suckless.org/patches/tcl.c b/dwm.suckless.org/patches/three-column/tcl.c
similarity index 100%
rename from dwm.suckless.org/patches/tcl.c
rename to dwm.suckless.org/patches/three-column/tcl.c
diff --git a/dwm.suckless.org/patches/dwm-tilegap-6.0.diff b/dwm.suckless.org/patches/tilegap/dwm-tilegap-6.0.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-tilegap-6.0.diff
rename to dwm.suckless.org/patches/tilegap/dwm-tilegap-6.0.diff
diff --git a/dwm.suckless.org/patches/tilegap.md b/dwm.suckless.org/patches/tilegap/index.md
similarity index 100%
rename from dwm.suckless.org/patches/tilegap.md
rename to dwm.suckless.org/patches/tilegap/index.md
diff --git a/dwm.suckless.org/patches/transparency.md b/dwm.suckless.org/patches/transparency.md
deleted file mode 100644
index ca9fa35a..00000000
--- a/dwm.suckless.org/patches/transparency.md
+++ /dev/null
_AT_@ -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_AT_unserver.de>
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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-urg-border.diff
rename to dwm.suckless.org/patches/urgentborder/dwm-6.1-urg-border.diff
diff --git a/dwm.suckless.org/patches/urgentborder.md b/dwm.suckless.org/patches/urgentborder/index.md
similarity index 100%
rename from dwm.suckless.org/patches/urgentborder.md
rename to dwm.suckless.org/patches/urgentborder/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-gap-5.7.2.diff b/dwm.suckless.org/patches/uselessgap/dwm-gap-5.7.2.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-gap-5.7.2.diff
rename to dwm.suckless.org/patches/uselessgap/dwm-gap-5.7.2.diff
diff --git a/dwm.suckless.org/patches/historical/dwm-uselessgap-5.8.diff b/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.8.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-uselessgap-5.8.diff
rename to dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.8.diff
diff --git a/dwm.suckless.org/patches/dwm-uselessgap-5.9.diff b/dwm.suckless.org/patches/uselessgap/dwm-uselessgap-5.9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-uselessgap-5.9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-uselessgap-6.1.diff
rename to dwm.suckless.org/patches/uselessgap/dwm-uselessgap-6.1.diff
diff --git a/dwm.suckless.org/patches/uselessgap.md b/dwm.suckless.org/patches/uselessgap/index.md
similarity index 89%
rename from dwm.suckless.org/patches/uselessgap.md
rename to dwm.suckless.org/patches/uselessgap/index.md
index 888bdca1..881b1a4a 100644
--- a/dwm.suckless.org/patches/uselessgap.md
+++ b/dwm.suckless.org/patches/uselessgap/index.md
_AT_@ -54,10 +54,10 @@ tile mode...
 
         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)
+ * [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](historical/dwm-gap-5.7.2.diff) (0.7k) (20091215)
+ * [dwm-gap-5.7.2.diff](dwm-gap-5.7.2.diff) (0.7k) (20091215)
 
 ## Author
 
diff --git a/dwm.suckless.org/patches/dwm-r1522-viewontag.diff b/dwm.suckless.org/patches/viewontag/dwm-r1522-viewontag.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-r1522-viewontag.diff
rename to dwm.suckless.org/patches/viewontag/dwm-r1522-viewontag.diff
diff --git a/dwm.suckless.org/patches/viewontag.md b/dwm.suckless.org/patches/viewontag/index.md
similarity index 100%
rename from dwm.suckless.org/patches/viewontag.md
rename to dwm.suckless.org/patches/viewontag/index.md
diff --git a/dwm.suckless.org/patches/dwm-warp-5.9.diff b/dwm.suckless.org/patches/warp/dwm-warp-5.9.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-warp-5.9.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-warp-6.1.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-warp-git-20160626-7af4d43.diff
rename to dwm.suckless.org/patches/warp/dwm-warp-git-20160626-7af4d43.diff
diff --git a/dwm.suckless.org/patches/warp.md b/dwm.suckless.org/patches/warp/index.md
similarity index 100%
rename from dwm.suckless.org/patches/warp.md
rename to dwm.suckless.org/patches/warp/index.md
diff --git a/dwm.suckless.org/patches/historical/dwm-6.0-winview.diff b/dwm.suckless.org/patches/winview/dwm-6.0-winview.diff
similarity index 100%
rename from dwm.suckless.org/patches/historical/dwm-6.0-winview.diff
rename to dwm.suckless.org/patches/winview/dwm-6.0-winview.diff
diff --git a/dwm.suckless.org/patches/winview/dwm-6.1-winview.diff b/dwm.suckless.org/patches/winview/dwm-6.1-winview.diff
new file mode 100644
index 00000000..e69de29b
diff --git a/dwm.suckless.org/patches/winview.md b/dwm.suckless.org/patches/winview/index.md
similarity index 95%
rename from dwm.suckless.org/patches/winview.md
rename to dwm.suckless.org/patches/winview/index.md
index cbd5a1f5..84c4af98 100644
--- a/dwm.suckless.org/patches/winview.md
+++ b/dwm.suckless.org/patches/winview/index.md
_AT_@ -1,4 +1,4 @@
-Winview
+winview
 ========
 
 Description
_AT_@ -46,7 +46,7 @@ Download
 --------
 
  * [dwm-6.1-winview.diff](dwm-6.1-winview.diff)
- * [dwm-6.0-winview.diff](historical/dwm-6.0-winview.diff)
+ * [dwm-6.0-winview.diff](dwm-6.0-winview.diff)
 
 Author
 ------
diff --git a/dwm.suckless.org/patches/dwm-6.1-xkb.diff b/dwm.suckless.org/patches/xkb/dwm-6.1-xkb.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-xkb.diff
rename to dwm.suckless.org/patches/xkb/dwm-6.1-xkb.diff
diff --git a/dwm.suckless.org/patches/xkb.md b/dwm.suckless.org/patches/xkb/index.md
similarity index 100%
rename from dwm.suckless.org/patches/xkb.md
rename to dwm.suckless.org/patches/xkb/index.md
diff --git a/dwm.suckless.org/patches/dwm-6.0-xtile.diff b/dwm.suckless.org/patches/xtile/dwm-6.0-xtile.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.0-xtile.diff
rename to dwm.suckless.org/patches/xtile/dwm-6.0-xtile.diff
diff --git a/dwm.suckless.org/patches/xtile.md b/dwm.suckless.org/patches/xtile/index.md
similarity index 99%
rename from dwm.suckless.org/patches/xtile.md
rename to dwm.suckless.org/patches/xtile/index.md
index 915c7891..0a3e67bc 100644
--- a/dwm.suckless.org/patches/xtile.md
+++ b/dwm.suckless.org/patches/xtile/index.md
_AT_@ -1,4 +1,4 @@
-Xtile
+xtile
 =====
 
 Description
diff --git a/dwm.suckless.org/patches/dwm-6.1-zoomswap.diff b/dwm.suckless.org/patches/zoomswap/dwm-6.1-zoomswap.diff
similarity index 100%
rename from dwm.suckless.org/patches/dwm-6.1-zoomswap.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-zoomswap-20160731-56a31dc.diff
rename to 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
similarity index 100%
rename from dwm.suckless.org/patches/dwm-zoomswap-6.0.diff
rename to dwm.suckless.org/patches/zoomswap/dwm-zoomswap-6.0.diff
diff --git a/dwm.suckless.org/patches/zoomswap.md b/dwm.suckless.org/patches/zoomswap/index.md
similarity index 100%
rename from dwm.suckless.org/patches/zoomswap.md
rename to dwm.suckless.org/patches/zoomswap/index.md
Received on Sun Nov 05 2017 - 01:46:14 CET

This archive was generated by hypermail 2.3.0 : Sun Nov 05 2017 - 01:48:18 CET