diff --git a/config.h b/config.h new file mode 100644 index 0000000..9467dd1 --- /dev/null +++ b/config.h @@ -0,0 +1,121 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 1; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const int showbar = 0; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#222222"; +static const char col_gray2[] = "#444444"; +static const char col_gray3[] = "#bbbbbb"; +static const char col_gray4[] = "#eeeeee"; +static const char col_cyan[] = "#005577"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +/* 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 */ + { "Firefox", NULL, NULL, 7, 0, -1 }, +}; + +/* 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 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 int attachbelow = 1; /* 1 means attach after the currently active window */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#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} }, +#define HOLDKEY 0xffeb // 0 - disable; 0xffe9 - Mod1Mask; 0xffeb - Mod4Mask + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +static const char *termcmd[] = { "st", NULL }; + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_i, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_s, focusstack, {.i = +1 } }, + { MODKEY, XK_r, focusstack, {.i = -1 } }, + { MODKEY, XK_t, switchcol, {0} }, + { MODKEY, XK_n, switchcol, {0} }, + { MODKEY|ShiftMask, XK_r, incnmaster, {.i = +1 } }, + { MODKEY|ShiftMask, XK_s, incnmaster, {.i = -1 } }, + { MODKEY|ShiftMask, XK_t, setmfact, {.f = -0.05} }, + { MODKEY|ShiftMask, XK_n, setmfact, {.f = +0.05} }, + { MODKEY, XK_c, transfer, {0} }, + //{ MODKEY, XK_Return, zoom, {0} }, + //{ MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_b, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_asterisk, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_asterisk, tag, {.ui = ~0 } }, + //{ MODKEY, XK_comma, focusmon, {.i = -1 } }, + //{ MODKEY, XK_period, focusmon, {.i = +1 } }, + //{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + //{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_quotedbl, 0) + TAGKEYS( XK_guillemotleft, 1) + TAGKEYS( XK_guillemotright, 2) + TAGKEYS( XK_parenleft, 3) + TAGKEYS( XK_parenright, 4) + TAGKEYS( XK_at, 5) + TAGKEYS( XK_plus, 6) + TAGKEYS( XK_minus, 7) + TAGKEYS( XK_slash, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, + { 0, HOLDKEY, holdbar, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, 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} }, +}; + diff --git a/dwm-attachbelow-6.2.diff b/dwm-attachbelow-6.2.diff new file mode 100644 index 0000000..ccad820 --- /dev/null +++ b/dwm-attachbelow-6.2.diff @@ -0,0 +1,97 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..cb8053a 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -35,6 +35,7 @@ static const Rule rules[] = { + 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 int attachbelow = 1; /* 1 means attach after the currently active window */ + + static const Layout layouts[] = { + /* symbol arrange function */ +diff --git a/dwm.1 b/dwm.1 +index 13b3729..fb6e76c 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -29,6 +29,9 @@ 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 ++The attach below patch makes newly spawned windows attach after the currently ++selected window ++.P + dwm draws a small border around windows to indicate the focus state. + .SH OPTIONS + .TP +diff --git a/dwm.c b/dwm.c +index 4465af1..bd715a2 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachBelow(Client *c); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -405,6 +406,21 @@ attach(Client *c) + c->next = c->mon->clients; + c->mon->clients = c; + } ++void ++attachBelow(Client *c) ++{ ++ //If there is nothing on the monitor or the selected client is floating, attach as normal ++ if(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating) { ++ attach(c); ++ return; ++ } ++ ++ //Set the new client's next property to the same as the currently selected clients next ++ c->next = c->mon->sel->next; ++ //Set the currently selected clients next property to the new client ++ c->mon->sel->next = c; ++ ++} + + void + attachstack(Client *c) +@@ -1062,7 +1078,10 @@ manage(Window w, XWindowAttributes *wa) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); +- attach(c); ++ if( attachbelow ) ++ attachBelow(c); ++ else ++ attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1417,7 +1436,10 @@ sendmon(Client *c, Monitor *m) + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); ++ if( attachbelow ) ++ attachBelow(c); ++ else ++ attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1897,7 +1919,10 @@ updategeom(void) + m->clients = c->next; + detachstack(c); + c->mon = mons; +- attach(c); ++ if( attachbelow ) ++ attachBelow(c); ++ else ++ attach(c); + attachstack(c); + } + if (m == selmon) diff --git a/dwm-hide_vacant_tags-6.3.diff b/dwm-hide_vacant_tags-6.3.diff new file mode 100644 index 0000000..0ccc7fc --- /dev/null +++ b/dwm-hide_vacant_tags-6.3.diff @@ -0,0 +1,39 @@ +diff --git a/dwm.c b/dwm.c +index a96f33c..f2da729 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -432,9 +432,15 @@ buttonpress(XEvent *e) + } + if (ev->window == selmon->barwin) { + i = x = 0; +- do ++ unsigned int occ = 0; ++ for(c = m->clients; c; c=c->next) ++ occ |= c->tags; ++ do { ++ /* Do not reserve space for vacant tags */ ++ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) ++ continue; + x += TEXTW(tags[i]); +- while (ev->x >= x && ++i < LENGTH(tags)); ++ } while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + click = ClkTagBar; + arg.ui = 1 << i; +@@ -719,13 +725,12 @@ drawbar(Monitor *m) + } + x = 0; + for (i = 0; i < LENGTH(tags); i++) { ++ /* Do not draw vacant tags */ ++ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) ++ continue; + w = TEXTW(tags[i]); + 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); + x += w; + } + w = blw = TEXTW(m->ltsymbol); diff --git a/dwm-holdbar-modkey-pertag-nobar-6.2.diff b/dwm-holdbar-modkey-pertag-nobar-6.2.diff new file mode 100644 index 0000000..a48f553 --- /dev/null +++ b/dwm-holdbar-modkey-pertag-nobar-6.2.diff @@ -0,0 +1,275 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..f3d9b45 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -50,6 +50,7 @@ static const Layout layouts[] = { + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, ++#define HOLDKEY 0xffe9 // 0 - disable; 0xffe9 - Mod1Mask; 0xffeb - Mod4Mask + + /* helper for spawning shell commands in the pre dwm-5.0 fashion */ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +@@ -94,6 +95,7 @@ static Key keys[] = { + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ { 0, HOLDKEY, holdbar, {0} }, + }; + + /* button definitions */ +diff --git a/dwm.c b/dwm.c +index 4465af1..4e5afa8 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -111,6 +111,7 @@ typedef struct { + void (*arrange)(Monitor *); + } Layout; + ++typedef struct Pertag Pertag; + struct Monitor { + char ltsymbol[16]; + float mfact; +@@ -130,6 +131,7 @@ struct Monitor { + Monitor *next; + Window barwin; + const Layout *lt[2]; ++ Pertag *pertag; + }; + + typedef struct { +@@ -176,6 +178,7 @@ static void grabbuttons(Client *c, int focused); + static void grabkeys(void); + static void incnmaster(const Arg *arg); + static void keypress(XEvent *e); ++static void keyrelease(XEvent *e); + static void killclient(const Arg *arg); + static void manage(Window w, XWindowAttributes *wa); + static void mappingnotify(XEvent *e); +@@ -210,6 +213,7 @@ static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); + static void togglebar(const Arg *arg); ++static void holdbar(const Arg *arg); + static void togglefloating(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); +@@ -217,6 +221,7 @@ static void unfocus(Client *c, int setfocus); + static void unmanage(Client *c, int destroyed); + static void unmapnotify(XEvent *e); + static void updatebarpos(Monitor *m); ++static void updateholdbarpos(Monitor *m); + static void updatebars(void); + static void updateclientlist(void); + static int updategeom(void); +@@ -245,6 +250,7 @@ static int (*xerrorxlib)(Display *, XErrorEvent *); + static unsigned int numlockmask = 0; + static void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, ++ [ButtonRelease] = keyrelease, + [ClientMessage] = clientmessage, + [ConfigureRequest] = configurerequest, + [ConfigureNotify] = configurenotify, +@@ -252,6 +258,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { + [EnterNotify] = enternotify, + [Expose] = expose, + [FocusIn] = focusin, ++ [KeyRelease] = keyrelease, + [KeyPress] = keypress, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, +@@ -271,10 +278,62 @@ static Window root, wmcheckwin; + /* 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 */ ++}; ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + + /* function implementations */ ++void ++holdbar(const Arg *arg) ++{ ++ if (selmon->showbar) ++ return; ++ selmon->showbar = 2; ++ updateholdbarpos(selmon); ++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++} ++ ++void ++keyrelease(XEvent *e) ++{ ++ if (XEventsQueued(dpy, QueuedAfterReading)) { ++ XEvent ne; ++ XPeekEvent(dpy, &ne); ++ ++ if (ne.type == KeyPress && ne.xkey.time == e->xkey.time && ++ ne.xkey.keycode == e->xkey.keycode) { ++ XNextEvent(dpy, &ne); ++ return; ++ } ++ } ++ if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) { ++ selmon->showbar = 0; ++ updateholdbarpos(selmon); ++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ arrange(selmon); ++ } ++} ++ ++void ++updateholdbarpos(Monitor *m) ++{ ++ m->wy = m->my; ++ m->wh = m->mh; ++ if (m->showbar) { ++ m->by = m->topbar ? m->wy : m->wy + m->wh - bh; ++ m->wy = m->topbar ? m->wy - bh + bh : m->wy; ++ } else { ++ m->by = -bh; ++ } ++} ++ + void + applyrules(Client *c) + { +@@ -631,6 +690,7 @@ Monitor * + createmon(void) + { + Monitor *m; ++ unsigned int i; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; +@@ -641,6 +701,17 @@ createmon(void) + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ m->pertag = ecalloc(1, sizeof(Pertag)); ++ m->pertag->curtag = m->pertag->prevtag = 1; ++ ++ for (i = 0; i <= LENGTH(tags); i++) { ++ m->pertag->nmasters[i] = m->nmaster; ++ m->pertag->mfacts[i] = m->mfact; ++ ++ m->pertag->ltidxs[i][0] = m->lt[0]; ++ m->pertag->ltidxs[i][1] = m->lt[1]; ++ m->pertag->sellts[i] = m->sellt; ++ } + return m; + } + +@@ -966,7 +1037,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); + } + +@@ -1501,9 +1572,9 @@ void + setlayout(const Arg *arg) + { + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) +- selmon->sellt ^= 1; ++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; + if (arg && arg->v) +- selmon->lt[selmon->sellt] = (Layout *)arg->v; ++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); +@@ -1522,7 +1593,7 @@ setmfact(const Arg *arg) + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; +- selmon->mfact = f; ++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon); + } + +@@ -1699,7 +1770,7 @@ tile(Monitor *m) + void + togglebar(const Arg *arg) + { +- selmon->showbar = !selmon->showbar; ++ selmon->showbar = (selmon->showbar == 2 ? 1 : !selmon->showbar); + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +@@ -1738,9 +1809,30 @@ void + toggleview(const Arg *arg) + { + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); ++ int i; + + if (newtagset) { + selmon->tagset[selmon->seltags] = 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; ++ } ++ ++ /* 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]; ++ + focus(NULL); + arrange(selmon); + } +@@ -2035,11 +2127,34 @@ 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->tagset[selmon->seltags] = arg->ui & TAGMASK; ++ selmon->pertag->prevtag = selmon->pertag->curtag; ++ ++ 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]; ++ + focus(NULL); + arrange(selmon); + } diff --git a/dwm-rotatestack-20161021-ab9571b.diff b/dwm-rotatestack-20161021-ab9571b.diff new file mode 100644 index 0000000..ed74c6d --- /dev/null +++ b/dwm-rotatestack-20161021-ab9571b.diff @@ -0,0 +1,102 @@ +diff --git a/config.def.h b/config.def.h +index fd77a07..09737d7 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -64,6 +64,8 @@ static Key keys[] = { + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, ++ { MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } }, ++ { MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, +diff --git a/dwm.c b/dwm.c +index 421bf27..1ec8b10 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -165,6 +165,8 @@ static void detachstack(Client *c); + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); ++static void enqueue(Client *c); ++static void enqueuestack(Client *c); + static void enternotify(XEvent *e); + static void expose(XEvent *e); + static void focus(Client *c); +@@ -194,6 +196,7 @@ static void resize(Client *c, int x, int y, int w, int h, int interact); + static void resizeclient(Client *c, int x, int y, int w, int h); + static void resizemouse(const Arg *arg); + static void restack(Monitor *m); ++static void rotatestack(const Arg *arg); + static void run(void); + static void scan(void); + static int sendevent(Client *c, Atom proto); +@@ -765,6 +768,28 @@ drawbars(void) + } + + void ++enqueue(Client *c) ++{ ++ Client *l; ++ for (l = c->mon->clients; l && l->next; l = l->next); ++ if (l) { ++ l->next = c; ++ c->next = NULL; ++ } ++} ++ ++void ++enqueuestack(Client *c) ++{ ++ Client *l; ++ for (l = c->mon->stack; l && l->snext; l = l->snext); ++ if (l) { ++ l->snext = c; ++ c->snext = NULL; ++ } ++} ++ ++void + enternotify(XEvent *e) + { + Client *c; +@@ -1390,6 +1415,38 @@ restack(Monitor *m) + } + + void ++rotatestack(const Arg *arg) ++{ ++ Client *c = NULL, *f; ++ ++ if (!selmon->sel) ++ return; ++ f = selmon->sel; ++ if (arg->i > 0) { ++ for (c = nexttiled(selmon->clients); c && nexttiled(c->next); c = nexttiled(c->next)); ++ if (c){ ++ detach(c); ++ attach(c); ++ detachstack(c); ++ attachstack(c); ++ } ++ } else { ++ if ((c = nexttiled(selmon->clients))){ ++ detach(c); ++ enqueue(c); ++ detachstack(c); ++ enqueuestack(c); ++ } ++ } ++ if (c){ ++ arrange(selmon); ++ //unfocus(f, 1); ++ focus(f); ++ restack(selmon); ++ } ++} ++ ++void + run(void) + { + XEvent ev; diff --git a/dwm-switchcol-6.1.diff b/dwm-switchcol-6.1.diff new file mode 100644 index 0000000..14c0c78 --- /dev/null +++ b/dwm-switchcol-6.1.diff @@ -0,0 +1,47 @@ +diff -urp dwm-6.1/dwm.c dwm-6.1-patched/dwm.c +--- dwm-6.1/dwm.c 2015-11-09 06:39:37.000000000 +0800 ++++ dwm-6.1-patched/dwm.c 2016-03-24 23:56:35.435047948 +0800 +@@ -206,6 +206,7 @@ static void setup(void); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void switchcol(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -1645,6 +1646,35 @@ spawn(const Arg *arg) + } + } + ++void ++switchcol(const Arg *arg) ++{ ++ Client *c, *t; ++ int col = 0; ++ int i; ++ ++ if (!selmon->sel) ++ return; ++ for (i = 0, c = nexttiled(selmon->clients); c ; ++ c = nexttiled(c->next), i++) { ++ if (c == selmon->sel) ++ col = (i + 1) > selmon->nmaster; ++ } ++ if (i <= selmon->nmaster) ++ return; ++ for (c = selmon->stack; c; c = c->snext) { ++ if (!ISVISIBLE(c)) ++ continue; ++ for (i = 0, t = nexttiled(selmon->clients); t && t != c; ++ t = nexttiled(t->next), i++); ++ if (t && (i + 1 > selmon->nmaster) != col) { ++ focus(c); ++ restack(selmon); ++ break; ++ } ++ } ++} ++ + void + tag(const Arg *arg) + { diff --git a/dwm-transfer-6.2.diff b/dwm-transfer-6.2.diff new file mode 100644 index 0000000..acad025 --- /dev/null +++ b/dwm-transfer-6.2.diff @@ -0,0 +1,77 @@ +From 57500f9154a3aa99f38f98d552915b8570b7cfdf Mon Sep 17 00:00:00 2001 +From: Miles Alan +Date: Sat, 25 Jan 2020 22:47:38 -0600 +Subject: [PATCH] Add transfer function which transfers tiled client between + the stack & master. Adjusts the nmaster variable accordingly (e.g. if moving + to master, nmaster++ and if moving to stack nmaster--). + +Default keybinding added to config.def.h is Mod+x +--- + config.def.h | 1 + + dwm.c | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..67ec8ae 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -70,6 +70,7 @@ static Key keys[] = { + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, ++ { MODKEY, XK_x, transfer, {0} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, +diff --git a/dwm.c b/dwm.c +index 4465af1..ada794b 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -213,6 +213,7 @@ static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); ++static void transfer(const Arg *arg); + static void unfocus(Client *c, int setfocus); + static void unmanage(Client *c, int destroyed); + static void unmapnotify(XEvent *e); +@@ -2147,3 +2148,36 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++void ++transfer(const Arg *arg) { ++ Client *c, *mtail = selmon->clients, *stail = NULL, *insertafter; ++ int transfertostack = 0, i, nmasterclients; ++ ++ for (i = 0, c = selmon->clients; c; c = c->next) { ++ if (!ISVISIBLE(c) || c->isfloating) continue; ++ if (selmon->sel == c) { transfertostack = i < selmon->nmaster && selmon->nmaster != 0; } ++ if (i < selmon->nmaster) { nmasterclients++; mtail = c; } ++ stail = c; ++ i++; ++ } ++ if (!selmon->sel || selmon->sel->isfloating || i == 0) { ++ return; ++ } else if (transfertostack) { ++ selmon->nmaster = MIN(i, selmon->nmaster) - 1; ++ insertafter = stail; ++ } else { ++ selmon->nmaster = selmon->nmaster + 1; ++ insertafter = mtail; ++ } ++ if (insertafter != selmon->sel) { ++ detach(selmon->sel); ++ if (selmon->nmaster == 1 && !transfertostack) { ++ attach(selmon->sel); // Head prepend case ++ } else { ++ selmon->sel->next = insertafter->next; ++ insertafter->next = selmon->sel; ++ } ++ } ++ arrange(selmon); ++} +-- +2.23.1 +