2024-09-18

dwm config.h

static const unsigned int borderpx = 0; // 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 = 0; // 0 means bottom bar
static const char *fonts[] = {"gohufont-uni-11"};
static const char dmenufont[] = "gohufont-uni-11";
static const char col_fg[] = "#bbbbbb";
static const char col_bg[] = "#000000";
static const char col_bgs[] = "#111111";
static const char *colors[][3] = {
  // fg bg border
  [SchemeNorm] = {col_fg, col_bg, col_bg},
  [SchemeSel] = {col_fg, col_bgs, col_bg},
};

// tagging
static const char *tags[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};

static const Rule rules[] = {
  // xprop(1):
  //    WM_CLASS(STRING) = instance, class
  //    WM_NAME(STRING) = title

  // class instance title tags mask isfloating monitor
  {"zenity", NULL, NULL, 0, 1, -1},
  {"Gimp", NULL, NULL, 0, 1, -1}
};

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 int resizehints = 1; // 1 means respect size hints in tiled resizals
static const int lockfullscreen = 1; // 1 will force focus on the fullscreen window

static const Layout layouts[] = {
  // first entry is default
  // symbol, arrange function
  {" ", tstackhoriz},
  {" ", bstackhoriz},
  {" ", tile}
};

// Mod4Mask = windows key
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
  {MODKEY, KEY, view, {.ui = 1 << TAG}}, \
    {MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \
    {MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \
    {MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG}}

// helper for spawning shell commands in the pre dwm-5.0 fashion
#define SHCMD(cmd) {.v = (const char*[]){"/bin/sh", "-c", cmd, NULL}}

static char dmenumon[2] = "0"; // component of dmenucmd, manipulated in spawn()
static const char *dmenucmd[] = {"dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_bg, "-nf", col_fg, "-sb", col_bgs, "-sf", col_fg, NULL};
static const char *termcmd[] = {"st", NULL};

static Key keys[] = {
  // modifier key function argument
  // adapted for qgmlwb
  {MODKEY, XK_z, togglebar, {0}},
  {MODKEY, XK_Return, zoom, {0}},
  {MODKEY, XK_Tab, view, {0}},
  {MODKEY, XK_t, focusstack, {.i = +1}},
  {MODKEY, XK_n, focusstack, {.i = -1}},
  {MODKEY, XK_d, setmfact, {.f = -0.05}},
  {MODKEY, XK_s, setmfact, {.f = +0.05}},
  {MODKEY, XK_x, focusmon, {.i = -1}},
  {MODKEY, XK_c, focusmon, {.i = +1}},
  {MODKEY|ShiftMask, XK_t, tagmon, {.i = -1}},
  {MODKEY|ShiftMask, XK_n, tagmon, {.i = +1}},
    {MODKEY, XK_space, setlayout, {0}},
  TAGKEYS(XK_q, 0),
  TAGKEYS(XK_g, 1),
  TAGKEYS(XK_m, 2),
  TAGKEYS(XK_l, 3),
  TAGKEYS(XK_a, 4),
  TAGKEYS(XK_e, 5),
  TAGKEYS(XK_o, 6),
  TAGKEYS(XK_h, 7),
  TAGKEYS(XK_k, 8),
  {MODKEY|ShiftMask, XK_w, quit, {0}}
};

// click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin
static Button buttons[] = {
  // click event mask button function argument
  {ClkLtSymbol, 0, Button1, setlayout, {0}},
  {ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]}},
  {ClkWinTitle, 0, Button2, zoom, {0}},
  {ClkStatusText, 0, Button2, spawn, {.v = termcmd}},
  {ClkClientWin, MODKEY, Button1, movemouse, {0}},
  {ClkClientWin, MODKEY, Button2, togglefloating, {0}},
  {ClkClientWin, MODKEY, Button3, resizemouse, {0}},
  {ClkTagBar, 0, Button1, view, {0}},
  {ClkTagBar, 0, Button3, toggleview, {0}},
  {ClkTagBar, MODKEY, Button1, tag, {0}},
  {ClkTagBar, MODKEY, Button3, toggletag, {0}},
};

patch that adds a vertically stacking layout

adds tstackhoriz and tstack. based on bottomstack.

new windows will be inserted at the bottom and fill the lower partition. other windows move to the top and share the upper partition. tstackhoriz is an ideal layout for vertically rotated monitors. since these tend to create a tall screen strip, just stacking windows is usually sufficient and easy to manage.

applied like "patch -p1 -i stack.diff" in the dwm/ source directory.

diff --git a/dwm.c b/dwm.c
index 67c6b2b..2c391c0 100644
--- a/dwm.c
+++ b/dwm.c
@@ -233,6 +233,9 @@ static int xerror(Display *dpy, XErrorEvent *ee);
 static int xerrordummy(Display *dpy, XErrorEvent *ee);
 static int xerrorstart(Display *dpy, XErrorEvent *ee);
 static void zoom(const Arg *arg);
+static void bstack(Monitor *m);
+static void bstackhoriz(Monitor *m);
+static void tstackhoriz(Monitor *m);

 /* variables */
 static const char broken[] = "broken";
@@ -2163,3 +2166,95 @@ main(int argc, char *argv[])
    XCloseDisplay(dpy);
    return EXIT_SUCCESS;
 }
+
+static void
+bstack(Monitor *m) {
+   int w, h, mh, mx, tx, ty, tw;
+   unsigned int i, n;
+   Client *c;
+
+   for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+   if (n == 0)
+       return;
+   if (n > m->nmaster) {
+       mh = m->nmaster ? m->mfact * m->wh : 0;
+       tw = m->ww / (n - m->nmaster);
+       ty = m->wy + mh;
+   } else {
+       mh = m->wh;
+       tw = m->ww;
+       ty = m->wy;
+   }
+   for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+       if (i < m->nmaster) {
+           w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
+           resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0);
+           mx += WIDTH(c);
+       } else {
+           h = m->wh - mh;
+           resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0);
+           if (tw != m->ww)
+               tx += WIDTH(c);
+       }
+   }
+}
+
+static void
+bstackhoriz(Monitor *m) {
+   int w, mh, mx, tx, ty, th;
+   unsigned int i, n;
+   Client *c;
+
+   for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+   if (n == 0)
+       return;
+   if (n > m->nmaster) {
+       mh = m->nmaster ? m->mfact * m->wh : 0;
+       th = (m->wh - mh) / (n - m->nmaster);
+       ty = m->wy + mh;
+   } else {
+       th = mh = m->wh;
+       ty = m->wy;
+   }
+   for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+       if (i < m->nmaster) {
+           w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
+           resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0);
+           mx += WIDTH(c);
+       } else {
+           resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), 0);
+           if (th != m->wh)
+               ty += HEIGHT(c);
+       }
+   }
+}
+
+static void
+tstackhoriz(Monitor *m) {
+  int w, mh, mx, tx, ty, th;
+  unsigned int i, n;
+  Client *c;
+
+  for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+  if (n == 0)
+    return;
+  if (n > m->nmaster) {
+    mh = m->nmaster ? m->mfact * m->wh : 0;
+    th = (m->wh - mh) / (n - m->nmaster);
+    ty = m->wy;
+  } else {
+    th = mh = m->wh;
+    ty = m->wy;
+  }
+  for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+    if (i < m->nmaster) {
+      w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
+      resize(c, m->wx + mx, m->wy + (n > m->nmaster ? th * (n - m->nmaster) : 0), w - (2 * c->bw), mh - (2 * c->bw), 0);
+      mx += WIDTH(c);
+    } else {
+      resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), 0);
+      if (th != m->wh)
+        ty += HEIGHT(c);
+    }
+  }
+}