summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Chausse <benjamin@chausse.xyz>2020-10-17 23:49:53 -0400
committerBenjamin Chausse <benjamin@chausse.xyz>2020-10-17 23:49:53 -0400
commitf93a225bb6bbda31d1981f3f8844f4a104b3e787 (patch)
tree84317abdc59582fb7f25f74d6383ba400b676895
parentf2a833eaa026fe676eb1f98ea943808363f5a189 (diff)
README overhaul
-rw-r--r--README48
-rw-r--r--README.md243
-rw-r--r--config.def.h1
-rw-r--r--dwm.c9
-rw-r--r--patches/dwm-activetagindicatorbar-6.2.diff17
-rw-r--r--patches/dwm-bar-height-6.2.diff25
-rw-r--r--patches/dwm-statuscmd-signal-6.2.diff157
7 files changed, 448 insertions, 52 deletions
diff --git a/README b/README
deleted file mode 100644
index 95d4fd0..0000000
--- a/README
+++ /dev/null
@@ -1,48 +0,0 @@
-dwm - dynamic window manager
-============================
-dwm is an extremely fast, small, and dynamic window manager for X.
-
-
-Requirements
-------------
-In order to build dwm you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (dwm is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install dwm (if
-necessary as root):
-
- make clean install
-
-
-Running dwm
------------
-Add the following line to your .xinitrc to start dwm using startx:
-
- exec dwm
-
-In order to connect dwm to a specific display, make sure that
-the DISPLAY environment variable is set correctly, e.g.:
-
- DISPLAY=foo.bar:1 exec dwm
-
-(This will start dwm on display :1 of the host foo.bar.)
-
-In order to display status info in the bar, you can do something
-like this in your .xinitrc:
-
- while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
- do
- sleep 1
- done &
- exec dwm
-
-
-Configuration
--------------
-The configuration of dwm is done by creating a custom config.h
-and (re)compiling the source code.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4353403
--- /dev/null
+++ b/README.md
@@ -0,0 +1,243 @@
+My dwm
+---
+A Dynamic Window Manager
+
+dwm is an extremely fast, small, and dynamic window manager for X.
+It is written with the [suckless philosophy][15]
+in mind and is objectively one of the best window managers out there.
+
+## What my build has to offer
+I have patched dwm extensively using official patches but also with the
+awesome patches [Floris Laporte][16] makes for his own build to
+make the experience more enjoyable. Here are the following patches which I
+installed:
+
+- [dwm-activetagindicatorbar-6.2][1]
+- [dwm-alpha-20180613-b69c870][2]
+- [dwm-bar-height-6.2][3]
+- [dwm-centeredmaster-6.1][4]
+- [dwm-dwmc-6.2][5]
+- [dwm-focusmaster][6]
+- [dwm-fullscreen][7]
+- [dwm-gaplessgrid-20160731-56a31dc][8]
+- [dwm-libxft-bgra][9]
+- [dwm-movestack-6.1][10]
+- [dwm-rotatestack-20161021-ab9571b][11]
+- [dwm-statuscmd-signal-6.2][21]
+- [dwm-tilegap][12]
+- [dwm-zoomswap-6.2][13]
+- [flaport-center][14]
+- [flaport-mastermon][14]
+- [flaport-swallow][14]
+
+So that's a nice list... But what does it actually mean? Here are the main
+points that make my build stand out.
+
+**Decentralized keybindings:**
+
+So if I have a piece of software that does one thing and does it well, why
+would I use anything else. I personally use the *Simple X Hotkey Daemon*
+([SXHKD][17]) to manage all my keybindings and dwm should be no exception.
+That's why I use the [dwmc][5] patch to allow sxhkd to control dwm.
+
+For this reason, I highly recommend you take a look at my [dotfiles][18]
+repository as it contains my current configuration for sxhkd. **This build
+of dwm is basically unusable until you have sxhkd setup for it.** This also
+means sxhkd should be launched along dwm inside your `.xinitrc`. As a bonus,
+if you install this build of dwm with my dotfiles using [archer][19], you
+can press `super + alt + shift + h` to view a procedurally generated pdf of
+all my keybindings.
+
+**Window swallowing:**
+
+This is a feature which allows terminals to "transform" themselves into the
+software they are launching (essentially saving screen real estate). For
+example: If I were to open a video inside mpv from my terminal, the terminal
+window would disapear and where it once was, mpv would appear.
+
+**Aesthetics:**
+
+I love transparency and that's why I added the [alpha][2] patch to my build.
+While I was at it, I switched the standard corner square bar indicator for a
+centered rectangle on each tag using the [activetagindicatorbar][1] patch.
+Most fonts don't play well with it so I added the [bar-height][3] patch to make
+the bar taller. I don't like to have gaps everywhere, but I don't dislike them
+either. Therefore, I only added them to the tiling layout (which is where they
+make the most sense).
+
+**Emoji Compatibility:**
+
+Some Suckless software have a frustrating tendency of crashing when
+encountering color emoji. This got fixed with the [libxft-bgra][9] patch. I'm
+not the greatest fan of emojis (I personally prefer the fontawesome fonts for
+icons), but in the unlikely event that one makes it's way to my statusbar, it
+will not crash.
+
+**dwmblocks compatibility:**
+
+I personnally have a personal build of [dwmblocks][20] which is capable of
+handling click events. For that to work, I had to add the
+[statuscmd-signal][21] patch.
+
+**Accessible stack navigation and manipulation:**
+
+I don't want to spend half an hour placing a window where I want in in the
+stack. I need a suite of functions aiding me to do certain motions
+either to position windows or navigate through them:
+
+- [Rotatestack][11]: Rotate the entire stack (clockwise/couterclockwise).
+- [Movestack][10]: Move the current window up or down the stack.
+- [FocusMaster][6]: Focus the master window (the last spawned window).
+- [ZoomSwap][13]: Swap the master window with the currently focused one.
+
+**Diverse but consise tiling modes:**
+
+I'm not a fan of having so many tiling modes I need a patch just to switch
+through all of them. I only included those I found usefull on a day to day
+basis. The following schematics will showcase these (1 being the newest
+spawned window):
+
+```
+ Tile (Regular):
+┌───────────────────────────────┐┌────────────────────────────────┐
+│ 1 ││ 2 │
+│ ││ │
+│ │└────────────────────────────────┘
+│ │┌────────────────────────────────┐
+│ ││ 3 │
+│ ││ │
+│ │└────────────────────────────────┘
+│ │┌────────────────────────────────┐
+│ ││ 4 │
+│ ││ │
+│ │└────────────────────────────────┘
+│ │┌────────────────────────────────┐
+│ ││ 5 │
+│ ││ │
+│ │└────────────────────────────────┘
+│ │┌────────────────────────────────┐
+│ ││ 6 │
+│ ││ │
+└───────────────────────────────┘└────────────────────────────────┘
+
+ Centered Master:
+┌───────────────┐┌───────────────────────────────┐┌───────────────┐
+│ 3 ││ 1 ││ 2 │
+│ ││ ││ │
+└───────────────┘│ │└───────────────┘
+┌───────────────┐│ │┌───────────────┐
+│ 5 ││ ││ 4 │
+│ ││ ││ │
+└───────────────┘│ │└───────────────┘
+┌───────────────┐│ │┌───────────────┐
+│ 7 ││ ││ 6 │
+│ ││ ││ │
+└───────────────┘│ │└───────────────┘
+┌───────────────┐│ │┌───────────────┐
+│ 9 ││ ││ 8 │
+│ ││ ││ │
+└───────────────┘│ │└───────────────┘
+┌───────────────┐│ │┌───────────────┐
+│ 11 ││ ││ 10 │
+│ ││ ││ │
+└───────────────┘└───────────────────────────────┘└───────────────┘
+
+ Floating Centered Master:
+┌───────────────┐┌───────────────┐┌───────────────┐┌───────────────┐
+│ 2 ││ 3 ││ 4 ││ 5 │
+│ ││ ││ ││ │
+│ ┌──────────────────────────────────────┐ │
+│ │ 1 │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ │ │ │
+│ └──────────────────────────────────────┘ │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+└───────────────┘└───────────────┘└───────────────┘└───────────────┘
+
+ Gappless Grid:
+┌───────────────┐┌───────────────┐┌───────────────┐┌───────────────┐
+│ 1 ││ 5 ││ 9 ││ 13 │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+└───────────────┘└───────────────┘└───────────────┘└───────────────┘
+┌───────────────┐┌───────────────┐┌───────────────┐┌───────────────┐
+│ 2 ││ 6 ││ 10 ││ 14 │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+└───────────────┘└───────────────┘└───────────────┘└───────────────┘
+┌───────────────┐┌───────────────┐┌───────────────┐┌───────────────┐
+│ 3 ││ 7 ││ 11 ││ 15 │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+└───────────────┘└───────────────┘└───────────────┘└───────────────┘
+┌───────────────┐┌───────────────┐┌───────────────┐┌───────────────┐
+│ 4 ││ 8 ││ 12 ││ 16 │
+│ ││ ││ ││ │
+│ ││ ││ ││ │
+└───────────────┘└───────────────┘└───────────────┘└───────────────┘
+
+```
+There are 3 more layout which don't require drawings:
+- Fullscreen
+- Monocle: Windows are stacked one over the over in "fullscreen"
+ (the statusbar remains).
+- Floating: Windows don't respond to any tiling function and simply
+ spawn in the top left corner (they remain in place coming from
+ another tiling function).
+
+## Requirements
+In order to build dwm you need the Xlib header files.
+
+
+## Installation
+Edit config.mk to match your local setup (dwm is installed into
+the /usr/local namespace by default).
+
+Afterwards enter the following command to build and install dwm (if
+necessary as root):
+```
+ make clean install
+```
+
+## Running dwm
+Add the following line to your .xinitrc to start dwm using startx:
+```
+ exec dwm
+```
+
+## Configuration
+The configuration of dwm is done by creating a custom config.h
+and (re)compiling the source code.
+
+
+[1]: https://dwm.suckless.org/patches/activetagindicatorbar/
+[2]: https://dwm.suckless.org/patches/alpha/
+[3]: https://dwm.suckless.org/patches/bar_height/
+[4]: https://dwm.suckless.org/patches/centeredmaster/
+[5]: https://dwm.suckless.org/patches/dwmc/
+[6]: https://dwm.suckless.org/patches/focusmaster/
+[7]: https://dwm.suckless.org/patches/fullscreen/
+[8]: https://dwm.suckless.org/patches/gaplessgrid/
+[9]: https://youtu.be/f9qNXV01yzg
+[10]: https://dwm.suckless.org/patches/movestack/
+[11]: https://dwm.suckless.org/patches/rotatestack/
+[12]: https://dwm.suckless.org/patches/tilegap/
+[13]: https://dwm.suckless.org/patches/zoomswap/
+[14]: https://github.com/flaport/dwm
+[15]: https://suckless.org/philosophy/
+[16]: https://github.com/flaport
+[17]: https://github.com/baskerville/sxhkd
+[18]: https://git.chausse.xyz/dotfiles/
+[19]: https://git.chausse.xyz/archer/
+[20]: https://git.chausse.xyz/dwmblocks/
+[21]: https://dwm.suckless.org/patches/statuscmd/
diff --git a/config.def.h b/config.def.h
index bb6b530..6c2db1c 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,6 +7,7 @@ static const unsigned int snap = 15; /* snap pixel */
static const int swallowfloating = 1; /* 1 means swallow floating windows by default */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int user_bh = 28; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */
static const char *fonts[] = { "monospace:size=12" };
static const char dmenufont[] = "monospace:size=12";
static const char col_gray1[] = "#222d32";
diff --git a/dwm.c b/dwm.c
index d353e23..ae533e7 100644
--- a/dwm.c
+++ b/dwm.c
@@ -896,9 +896,10 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? ( m == selmon ? SchemeSel : SchemeInactive) : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
+ drw_rect(drw, x + boxw, 0, w - ( 2 * boxw + 1), boxw,
+ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+ urg & 1 << i);
+
x += w;
}
}
@@ -2003,7 +2004,7 @@ setup(void)
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
- bh = drw->fonts->h + 2;
+ bh = user_bh ? user_bh : drw->fonts->h + 2;
updategeom();
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
diff --git a/patches/dwm-activetagindicatorbar-6.2.diff b/patches/dwm-activetagindicatorbar-6.2.diff
new file mode 100644
index 0000000..4450099
--- /dev/null
+++ b/patches/dwm-activetagindicatorbar-6.2.diff
@@ -0,0 +1,17 @@
+diff -up dwm-a/dwm.c dwm-b/dwm.c
+--- dwm-a/dwm.c 2019-02-02 06:55:28.000000000 -0600
++++ dwm-b/dwm.c 2019-02-23 21:43:13.359179100 -0600
+@@ -719,9 +719,10 @@ drawbar(Monitor *m)
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+- drw_rect(drw, x + boxs, boxs, boxw, boxw,
+- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+- urg & 1 << i);
++ drw_rect(drw, x + boxw, 0, w - ( 2 * boxw + 1), boxw,
++ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
++ urg & 1 << i);
++
+ x += w;
+ }
+ w = blw = TEXTW(m->ltsymbol);
diff --git a/patches/dwm-bar-height-6.2.diff b/patches/dwm-bar-height-6.2.diff
new file mode 100644
index 0000000..a576111
--- /dev/null
+++ b/patches/dwm-bar-height-6.2.diff
@@ -0,0 +1,25 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..9814500 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -5,6 +5,7 @@ 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 */
++static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+diff --git a/dwm.c b/dwm.c
+index 4465af1..2c27cb3 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1545,7 +1545,7 @@ setup(void)
+ if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+ die("no fonts could be loaded.");
+ lrpad = drw->fonts->h;
+- bh = drw->fonts->h + 2;
++ bh = user_bh ? user_bh : drw->fonts->h + 2;
+ updategeom();
+ /* init atoms */
+ utf8string = XInternAtom(dpy, "UTF8_STRING", False);
diff --git a/patches/dwm-statuscmd-signal-6.2.diff b/patches/dwm-statuscmd-signal-6.2.diff
new file mode 100644
index 0000000..97fda1b
--- /dev/null
+++ b/patches/dwm-statuscmd-signal-6.2.diff
@@ -0,0 +1,157 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..b67825e 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -103,7 +103,9 @@ static Button buttons[] = {
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
++ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
++ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
++ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..c600131 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
+ static void configure(Client *c);
+ static void configurenotify(XEvent *e);
+ static void configurerequest(XEvent *e);
++static void copyvalidchars(char *text, char *rawtext);
+ static Monitor *createmon(void);
+ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+@@ -169,6 +170,7 @@ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
++static int getdwmblockspid();
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+@@ -205,6 +207,7 @@ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
++static void sigdwmblocks(const Arg *arg);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -237,6 +240,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
++static char rawstext[256];
++static int dwmblockssig;
++pid_t dwmblockspid = 0;
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh, blw = 0; /* bar geometry */
+@@ -439,9 +445,26 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - TEXTW(stext))
++ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
+ click = ClkStatusText;
+- else
++
++ char *text = rawstext;
++ int i = -1;
++ char ch;
++ dwmblockssig = 0;
++ while (text[++i]) {
++ if ((unsigned char)text[i] < ' ') {
++ ch = text[i];
++ text[i] = '\0';
++ x += TEXTW(text) - lrpad;
++ text[i] = ch;
++ text += i+1;
++ i = -1;
++ if (x >= ev->x) break;
++ dwmblockssig = ch;
++ }
++ }
++ } else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+ focus(c);
+@@ -627,6 +650,19 @@ configurerequest(XEvent *e)
+ XSync(dpy, False);
+ }
+
++void
++copyvalidchars(char *text, char *rawtext)
++{
++ int i = -1, j = 0;
++
++ while(rawtext[++i]) {
++ if ((unsigned char)rawtext[i] >= ' ') {
++ text[j++] = rawtext[i];
++ }
++ }
++ text[j] = '\0';
++}
++
+ Monitor *
+ createmon(void)
+ {
+@@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop)
+ return atom;
+ }
+
++int
++getdwmblockspid()
++{
++ char buf[16];
++ FILE *fp = popen("pidof -s dwmblocks", "r");
++ fgets(buf, sizeof(buf), fp);
++ pid_t pid = strtoul(buf, NULL, 10);
++ pclose(fp);
++ dwmblockspid = pid;
++ return pid != 0 ? 0 : -1;
++}
++
+ int
+ getrootptr(int *x, int *y)
+ {
+@@ -1636,6 +1684,23 @@ sigchld(int unused)
+ while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+
++void
++sigdwmblocks(const Arg *arg)
++{
++ union sigval sv;
++ sv.sival_int = (dwmblockssig << 8) | arg->i;
++ if (!dwmblockspid)
++ if (getdwmblockspid() == -1)
++ return;
++
++ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) {
++ if (errno == ESRCH) {
++ if (!getdwmblockspid())
++ sigqueue(dwmblockspid, SIGUSR1, sv);
++ }
++ }
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+@@ -1987,8 +2052,10 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
+ strcpy(stext, "dwm-"VERSION);
++ else
++ copyvalidchars(stext, rawstext);
+ drawbar(selmon);
+ }
+