diff options
| -rw-r--r-- | .gitignore | 9 | ||||
| -rw-r--r-- | config.h | 139 | ||||
| -rw-r--r-- | dwm-colorbar-6.2.diff | 68 | ||||
| -rw-r--r-- | dwm-fullgaps-6.2.diff | 95 | ||||
| -rw-r--r-- | dwm-hide_vacant_tags-6.2.diff | 55 | ||||
| -rw-r--r-- | dwm-scratchpad-6.2.diff | 90 | ||||
| -rw-r--r-- | dwm-statuscmd-6.2.diff | 142 | ||||
| -rw-r--r-- | dwm-xrdb-6.2.diff | 188 | 
8 files changed, 786 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ef35fa6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +.idea +*.log +tmp/ + + +*.o +dwm +.ccls-cache diff --git a/config.h b/config.h new file mode 100644 index 0000000..6ed40be --- /dev/null +++ b/config.h @@ -0,0 +1,139 @@ +/* See LICENSE file for copyright and license details. */ + +#define true 1 +#define false 0 + +#define GTMask(X) 1 << (X - 1) + +/* appearance */ +static const unsigned int borderpx  = 10;       /* border pixel of windows */ +static const unsigned int snap      = 32;       /* snap pixel */ +static const unsigned int gappx     = 10;        /* gaps between windows */ +static const int showbar            = true;        /* 0 means no bar */ +static const int topbar             = false;        /* 0 means bottom bar */ +static const char *fonts[]          = { "IBM Plex Sans:size=11" }; +static const char dmenufont[]       = "monospace:size=10"; +static const char col_black[]       = "#161616"; +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 col_green[]       = "#0e3f05"; +static const char col_red[]         = "#910d01"; +static const char *colors[][3]      = { +	/* Scheme            fg         bg         border   */ +	[SchemeNorm]     = { col_gray3, col_gray1, col_gray2 }, +	[SchemeSel]      = { col_gray4, col_cyan,  col_green  }, +	[SchemeStatus]   = { col_gray3, col_gray1,  "#000000"  }, // Statusbar right {text,background,not used but cannot be empty} +	[SchemeTagsSel]  = { col_gray4, col_green,  "#000000"  }, // Tagbar left selected {text,background,not used but cannot be empty} +	[SchemeTagsNorm] = { col_gray3, col_gray1,  "#000000"  }, // Tagbar left unselected {text,background,not used but cannot be empty} +	[SchemeInfoSel]  = { col_gray4, col_black,  "#000000"  }, // infobar middle  selected {text,background,not used but cannot be empty} +	[SchemeInfoNorm] = { col_gray3, col_gray1,  "#000000"  }, // infobar middle  unselected {text,background,not used but cannot be empty} +}; + +/* tagging */ +static const char *tags[] = { "", "", "", "", "", "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 */ +	{ "Gimp",           NULL,       NULL,       0,            1,           -1 }, +	{ "Emacs",          NULL,       NULL,       GTMask(1),    0,           -1 }, +	{ "qutebrowser",    NULL,       NULL,       GTMask(2),    0,           -1 }, +	{ "mpv",            NULL,       NULL,       GTMask(3),    0,           -1 }, +	{ "media-term",     NULL,       NULL,       GTMask(3),    0,           -1 }, +	{ "Zathura",        NULL,       NULL,       GTMask(4),    0,           -1 }, +	{ "Dev",            NULL,       NULL,       GTMask(5),    0,           -1 }, +}; + +/* layout(s) */ +static const float mfact     = 0.5;    /* 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 Layout layouts[] = { +	/* symbol     arrange function */ +	{ "[T]=",      tile },    /* first entry is default */ +	{ "<F>=",      NULL },    /* no layout function means floating behavior */ +	{ "{M}",      monocle }, +}; + +/* key definitions */ +#define MODKEY Mod4Mask +#define HYPERKEY Mod3Mask +#define TAGKEYS(KEY,TAG) \ +	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \ +	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \ +	{ HYPERKEY,                     KEY,      view,           {.ui = 1 << TAG} }, \ +	{ HYPERKEY|ShiftMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \ +	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \ +	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static 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 scratchpadname[] = "scratchpad"; +static const char *scratchpadcmd[] = { "st", "-t", scratchpadname, NULL }; + +static char *statuscmds[] = { "notify-send Mouse$BUTTON" }; +static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; + +static Key keys[] = { +	/* modifier                     key        function        argument */ +	{ MODKEY,                       XK_b,      togglebar,      {0} }, +	{ MODKEY,                       XK_grave,  togglescratch,  {.v = scratchpadcmd } }, +	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } }, +	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } }, +	{ MODKEY,                       XK_comma,  setgaps,        {.i = -1} }, +	{ MODKEY,                       XK_period, setgaps,        {.i = +1 } }, +	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.01} }, +	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.01} }, +	{ MODKEY|ShiftMask,             XK_period, incnmaster,     {.i = +1 } }, +	{ MODKEY|ShiftMask,             XK_comma,  incnmaster,     {.i = -1 } }, +	{ MODKEY,                       XK_c,      zoom,           {0} }, +	{ MODKEY,                       XK_Tab,    view,           {0} }, +	{ HYPERKEY,                     XK_Tab,    view,           {0} }, +	{ MODKEY|ShiftMask,             XK_t,      setlayout,      {.v = &layouts[0]} }, +	{ MODKEY|ShiftMask,             XK_f,      setlayout,      {.v = &layouts[1]} }, +	{ MODKEY|ShiftMask,             XK_m,      setlayout,      {.v = &layouts[2]} }, +	{ MODKEY,                       XK_space,  setlayout,      {0} }, +	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} }, +	{ MODKEY,                       XK_i,      focusmon,       {.i = -1 } }, +	{ MODKEY,                       XK_d,      focusmon,       {.i = +1 } }, +	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } }, +	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } }, +	TAGKEYS(                        XK_1,                      0) +	TAGKEYS(                        XK_2,                      1) +	TAGKEYS(                        XK_3,                      2) +	TAGKEYS(                        XK_4,                      3) +	TAGKEYS(                        XK_5,                      4) +	TAGKEYS(                        XK_6,                      5) +	TAGKEYS(                        XK_7,                      6) +	TAGKEYS(                        XK_8,                      7) +	TAGKEYS(                        XK_9,                      8) +	{ MODKEY,                       XK_q,      killclient,     {0} }, +	{ MODKEY|ShiftMask,             XK_q,      quit,           {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} }, +	{ 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-colorbar-6.2.diff b/dwm-colorbar-6.2.diff new file mode 100644 index 0000000..91c067d --- /dev/null +++ b/dwm-colorbar-6.2.diff @@ -0,0 +1,68 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..a516645 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -16,6 +16,11 @@ static const char *colors[][3]      = { + 	/*               fg         bg         border   */ + 	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + 	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  }, ++	[SchemeStatus]  = { col_gray3, col_gray1,  "#000000"  }, // Statusbar right {text,background,not used but cannot be empty} ++	[SchemeTagsSel]  = { col_gray4, col_cyan,  "#000000"  }, // Tagbar left selected {text,background,not used but cannot be empty} ++    [SchemeTagsNorm]  = { col_gray3, col_gray1,  "#000000"  }, // Tagbar left unselected {text,background,not used but cannot be empty} ++    [SchemeInfoSel]  = { col_gray4, col_cyan,  "#000000"  }, // infobar middle  selected {text,background,not used but cannot be empty} ++    [SchemeInfoNorm]  = { col_gray3, col_gray1,  "#000000"  }, // infobar middle  unselected {text,background,not used but cannot be empty} + }; +  + /* tagging */ +diff --git a/dwm.c b/dwm.c +index 4465af1..0d1d2f7 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -59,7 +59,7 @@ +  + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +-enum { SchemeNorm, SchemeSel }; /* color schemes */ ++enum { SchemeNorm, SchemeSel, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* color schemes */ + enum { NetSupported, NetWMName, NetWMState, NetWMCheck, +        NetWMFullscreen, NetActiveWindow, NetWMWindowType, +        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +@@ -703,7 +703,7 @@ drawbar(Monitor *m) +  + 	/* draw status first so it can be overdrawn by tags later */ + 	if (m == selmon) { /* status is only drawn on selected monitor */ +-		drw_setscheme(drw, scheme[SchemeNorm]); ++		drw_setscheme(drw, scheme[SchemeStatus]); + 		sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ + 		drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); + 	} +@@ -716,7 +716,7 @@ drawbar(Monitor *m) + 	x = 0; + 	for (i = 0; i < LENGTH(tags); i++) { + 		w = TEXTW(tags[i]); +-		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); ++		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]); + 		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, +@@ -725,17 +725,17 @@ drawbar(Monitor *m) + 		x += w; + 	} + 	w = blw = TEXTW(m->ltsymbol); +-	drw_setscheme(drw, scheme[SchemeNorm]); ++	drw_setscheme(drw, scheme[SchemeTagsNorm]); + 	x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); +  + 	if ((w = m->ww - sw - x) > bh) { + 		if (m->sel) { +-			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); ++			drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]); + 			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + 			if (m->sel->isfloating) + 				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + 		} else { +-			drw_setscheme(drw, scheme[SchemeNorm]); ++			drw_setscheme(drw, scheme[SchemeInfoNorm]); + 			drw_rect(drw, x, 0, w, bh, 1, 1); + 		} + 	} diff --git a/dwm-fullgaps-6.2.diff b/dwm-fullgaps-6.2.diff new file mode 100644 index 0000000..7206aec --- /dev/null +++ b/dwm-fullgaps-6.2.diff @@ -0,0 +1,95 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..38d2f6c 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ +  + /* appearance */ + static const unsigned int borderpx  = 1;        /* border pixel of windows */ ++static const unsigned int gappx     = 5;        /* gaps between 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 */ +@@ -84,6 +85,9 @@ static Key keys[] = { + 	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } }, + 	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } }, + 	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } }, ++	{ MODKEY,                       XK_minus,  setgaps,        {.i = -1 } }, ++	{ MODKEY,                       XK_equal,  setgaps,        {.i = +1 } }, ++	{ MODKEY|ShiftMask,             XK_equal,  setgaps,        {.i = 0  } }, + 	TAGKEYS(                        XK_1,                      0) + 	TAGKEYS(                        XK_2,                      1) + 	TAGKEYS(                        XK_3,                      2) +diff --git a/dwm.c b/dwm.c +index 4465af1..4363627 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -119,6 +119,7 @@ struct Monitor { + 	int by;               /* bar geometry */ + 	int mx, my, mw, mh;   /* screen size */ + 	int wx, wy, ww, wh;   /* window area  */ ++	int gappx;            /* gaps between windows */ + 	unsigned int seltags; + 	unsigned int sellt; + 	unsigned int tagset[2]; +@@ -199,6 +200,7 @@ static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); + static void setfullscreen(Client *c, int fullscreen); ++static void setgaps(const Arg *arg); + static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); +@@ -638,6 +640,7 @@ createmon(void) + 	m->nmaster = nmaster; + 	m->showbar = showbar; + 	m->topbar = topbar; ++	m->gappx = gappx; + 	m->lt[0] = &layouts[0]; + 	m->lt[1] = &layouts[1 % LENGTH(layouts)]; + 	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); +@@ -1497,6 +1500,16 @@ setfullscreen(Client *c, int fullscreen) + 	} + } +  ++void ++setgaps(const Arg *arg) ++{ ++	if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) ++		selmon->gappx = 0; ++	else ++		selmon->gappx += arg->i; ++	arrange(selmon); ++} ++ + void + setlayout(const Arg *arg) + { +@@ -1683,16 +1696,16 @@ tile(Monitor *m) + 	if (n > m->nmaster) + 		mw = m->nmaster ? m->ww * m->mfact : 0; + 	else +-		mw = m->ww; +-	for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++		mw = m->ww - m->gappx; ++	for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + 		if (i < m->nmaster) { +-			h = (m->wh - my) / (MIN(n, m->nmaster) - i); +-			resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); +-			my += HEIGHT(c); ++			h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; ++			resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); ++			my += HEIGHT(c) + m->gappx; + 		} else { +-			h = (m->wh - ty) / (n - i); +-			resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); +-			ty += HEIGHT(c); ++			h = (m->wh - ty) / (n - i) - m->gappx; ++			resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); ++			ty += HEIGHT(c) + m->gappx; + 		} + } +  +--  +2.20.1 + diff --git a/dwm-hide_vacant_tags-6.2.diff b/dwm-hide_vacant_tags-6.2.diff new file mode 100644 index 0000000..a981b23 --- /dev/null +++ b/dwm-hide_vacant_tags-6.2.diff @@ -0,0 +1,55 @@ +diff --git a/dwm.c b/dwm.c +index 4465af1..c4aa3de 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -416,7 +416,7 @@ attachstack(Client *c) + void + buttonpress(XEvent *e) + { +-	unsigned int i, x, click; ++	unsigned int i, x, click, occ = 0; + 	Arg arg = {0}; + 	Client *c; + 	Monitor *m; +@@ -431,9 +431,14 @@ buttonpress(XEvent *e) + 	} + 	if (ev->window == selmon->barwin) { + 		i = x = 0; +-		do ++		for (c = m->clients; c; c = c->next) ++			occ |= c->tags == 255 ? 0 : 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; +@@ -709,19 +714,19 @@ drawbar(Monitor *m) + 	} +  + 	for (c = m->clients; c; c = c->next) { +-		occ |= c->tags; ++		occ |= c->tags == 255 ? 0 : c->tags; + 		if (c->isurgent) + 			urg |= c->tags; + 	} + 	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-scratchpad-6.2.diff b/dwm-scratchpad-6.2.diff new file mode 100644 index 0000000..2062263 --- /dev/null +++ b/dwm-scratchpad-6.2.diff @@ -0,0 +1,90 @@ +diff -up a/config.def.h b/config.def.h +--- a/config.def.h	2019-06-06 21:23:27.006661784 +0200 ++++ b/config.def.h	2019-06-20 15:05:59.083102462 +0200 +@@ -58,11 +58,14 @@ static const Layout layouts[] = { + 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 const char scratchpadname[] = "scratchpad"; ++static const char *scratchpadcmd[] = { "st", "-t", scratchpadname, "-g", "120x34", NULL }; +  + static Key keys[] = { + 	/* modifier                     key        function        argument */ + 	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } }, + 	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } }, ++	{ MODKEY,                       XK_grave,  togglescratch,  {.v = scratchpadcmd } }, + 	{ MODKEY,                       XK_b,      togglebar,      {0} }, + 	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } }, + 	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } }, +diff -up a/dwm.c b/dwm.c +--- a/dwm.c	2019-06-06 21:23:27.023328450 +0200 ++++ b/dwm.c	2019-06-20 15:07:01.089767947 +0200 +@@ -213,6 +213,7 @@ static void tagmon(const Arg *arg); + static void tile(Monitor *); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); ++static void togglescratch(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); + static void unfocus(Client *c, int setfocus); +@@ -273,6 +274,8 @@ static Window root, wmcheckwin; + /* configuration, allows nested code to access above variables */ + #include "config.h" +  ++static unsigned int scratchtag = 1 << LENGTH(tags); ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; +  +@@ -1052,6 +1055,14 @@ manage(Window w, XWindowAttributes *wa) + 		&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + 	c->bw = borderpx; +  ++	selmon->tagset[selmon->seltags] &= ~scratchtag; ++	if (!strcmp(c->name, scratchpadname)) { ++		c->mon->tagset[c->mon->seltags] |= c->tags = scratchtag; ++		c->isfloating = True; ++		c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); ++		c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); ++	} ++ + 	wc.border_width = c->bw; + 	XConfigureWindow(dpy, w, CWBorderWidth, &wc); + 	XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); +@@ -1661,6 +1672,7 @@ spawn(const Arg *arg) + { + 	if (arg->v == dmenucmd) + 		dmenumon[0] = '0' + selmon->num; ++	selmon->tagset[selmon->seltags] &= ~scratchtag; + 	if (fork() == 0) { + 		if (dpy) + 			close(ConnectionNumber(dpy)); +@@ -1748,6 +1760,28 @@ togglefloating(const Arg *arg) + } +  + void ++togglescratch(const Arg *arg) ++{ ++	Client *c; ++	unsigned int found = 0; ++ ++	for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next); ++	if (found) { ++		unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag; ++		if (newtagset) { ++			selmon->tagset[selmon->seltags] = newtagset; ++			focus(NULL); ++			arrange(selmon); ++		} ++		if (ISVISIBLE(c)) { ++			focus(c); ++			restack(selmon); ++		} ++	} else ++		spawn(arg); ++} ++ ++void + toggletag(const Arg *arg) + { + 	unsigned int newtags; diff --git a/dwm-statuscmd-6.2.diff b/dwm-statuscmd-6.2.diff new file mode 100644 index 0000000..c825749 --- /dev/null +++ b/dwm-statuscmd-6.2.diff @@ -0,0 +1,142 @@ +From 2761ad72b4b8a80e434e7eba1a24676119ab666d Mon Sep 17 00:00:00 2001 +From: Daniel Bylinka <daniel.bylinka@gmail.com> +Date: Sat, 18 Apr 2020 01:41:03 +0200 +Subject: [PATCH] statuscmd: run shell commands based on mouse button and + position when clicking statusbar + +--- + config.def.h |  8 +++++++- + dwm.c        | 47 ++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 51 insertions(+), 4 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..5cd7efa 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -59,6 +59,10 @@ 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 }; +  ++/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */ ++static char *statuscmds[] = { "notify-send Mouse$BUTTON" }; ++static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; ++ + static Key keys[] = { + 	/* modifier                     key        function        argument */ + 	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } }, +@@ -103,7 +107,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,        spawn,          {.v = statuscmd } }, ++	{ ClkStatusText,        0,              Button2,        spawn,          {.v = statuscmd } }, ++	{ ClkStatusText,        0,              Button3,        spawn,          {.v = statuscmd } }, + 	{ 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..d35d173 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); +@@ -237,6 +238,9 @@ static void zoom(const Arg *arg); + /* variables */ + static const char broken[] = "broken"; + static char stext[256]; ++static char rawstext[256]; ++static int statuscmdn; ++static char lastbutton[] = "-"; + static int screen; + static int sw, sh;           /* X display screen geometry width, height */ + static int bh, blw = 0;      /* bar geometry */ +@@ -421,6 +425,7 @@ buttonpress(XEvent *e) + 	Client *c; + 	Monitor *m; + 	XButtonPressedEvent *ev = &e->xbutton; ++	*lastbutton = '0' + ev->button; +  + 	click = ClkRootWin; + 	/* focus monitor if necessary */ +@@ -439,9 +444,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; ++			statuscmdn = 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; ++					if (ch <= LENGTH(statuscmds)) statuscmdn = ch - 1; ++				} ++			} ++		} else + 			click = ClkWinTitle; + 	} else if ((c = wintoclient(ev->window))) { + 		focus(c); +@@ -627,6 +649,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) + { +@@ -1641,6 +1676,10 @@ spawn(const Arg *arg) + { + 	if (arg->v == dmenucmd) + 		dmenumon[0] = '0' + selmon->num; ++	else if (arg->v == statuscmd) { ++		statuscmd[2] = statuscmds[statuscmdn]; ++		setenv("BUTTON", lastbutton, 1); ++	} + 	if (fork() == 0) { + 		if (dpy) + 			close(ConnectionNumber(dpy)); +@@ -1987,8 +2026,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); + } +  +--  +2.26.1 + diff --git a/dwm-xrdb-6.2.diff b/dwm-xrdb-6.2.diff new file mode 100644 index 0000000..4c5a53f --- /dev/null +++ b/dwm-xrdb-6.2.diff @@ -0,0 +1,188 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..5db7d05 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -7,15 +7,16 @@ static const int showbar            = 1;        /* 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  }, ++static char normbgcolor[]           = "#222222"; ++static char normbordercolor[]       = "#444444"; ++static char normfgcolor[]           = "#bbbbbb"; ++static char selfgcolor[]            = "#eeeeee"; ++static char selbordercolor[]        = "#005577"; ++static char selbgcolor[]            = "#005577"; ++static char *colors[][3] = { ++       /*               fg           bg           border   */ ++       [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, ++       [SchemeSel]  = { selfgcolor,  selbgcolor,  selbordercolor  }, + }; +  + /* tagging */ +@@ -56,7 +57,7 @@ static const Layout layouts[] = { +  + /* 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 *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; + static const char *termcmd[]  = { "st", NULL }; +  + static Key keys[] = { +@@ -84,6 +85,7 @@ static Key keys[] = { + 	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } }, + 	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } }, + 	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } }, ++	{ MODKEY,                       XK_F5,     xrdb,           {.v = NULL } }, + 	TAGKEYS(                        XK_1,                      0) + 	TAGKEYS(                        XK_2,                      1) + 	TAGKEYS(                        XK_3,                      2) +diff --git a/drw.c b/drw.c +index 8fd1ca4..e4968a0 100644 +--- a/drw.c ++++ b/drw.c +@@ -207,7 +207,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname) + /* Wrapper to create color schemes. The caller has to call free(3) on the +  * returned color scheme when done using it. */ + Clr * +-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) ++drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount) + { + 	size_t i; + 	Clr *ret; +diff --git a/drw.h b/drw.h +index 4bcd5ad..42b04ce 100644 +--- a/drw.h ++++ b/drw.h +@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in +  + /* Colorscheme abstraction */ + void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); ++Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount); +  + /* Cursor abstraction */ + Cur *drw_cur_create(Drw *drw, int shape); +diff --git a/dwm.c b/dwm.c +index 4465af1..7fa45c5 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -35,6 +35,7 @@ + #include <X11/Xatom.h> + #include <X11/Xlib.h> + #include <X11/Xproto.h> ++#include <X11/Xresource.h> + #include <X11/Xutil.h> + #ifdef XINERAMA + #include <X11/extensions/Xinerama.h> +@@ -56,6 +57,21 @@ + #define HEIGHT(X)               ((X)->h + 2 * (X)->bw) + #define TAGMASK                 ((1 << LENGTH(tags)) - 1) + #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad) ++#define XRDB_LOAD_COLOR(R,V)    if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ ++                                  if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ ++                                    int i = 1; \ ++                                    for (; i <= 6; i++) { \ ++                                      if (value.addr[i] < 48) break; \ ++                                      if (value.addr[i] > 57 && value.addr[i] < 65) break; \ ++                                      if (value.addr[i] > 70 && value.addr[i] < 97) break; \ ++                                      if (value.addr[i] > 102) break; \ ++                                    } \ ++                                    if (i == 7) { \ ++                                      strncpy(V, value.addr, 7); \ ++                                      V[7] = '\0'; \ ++                                    } \ ++                                  } \ ++                                } +  + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +@@ -177,6 +193,7 @@ static void grabkeys(void); + static void incnmaster(const Arg *arg); + static void keypress(XEvent *e); + static void killclient(const Arg *arg); ++static void loadxrdb(void); + static void manage(Window w, XWindowAttributes *wa); + static void mappingnotify(XEvent *e); + static void maprequest(XEvent *e); +@@ -232,6 +249,7 @@ static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); ++static void xrdb(const Arg *arg); + static void zoom(const Arg *arg); +  + /* variables */ +@@ -1014,6 +1032,37 @@ killclient(const Arg *arg) + 	} + } +  ++void ++loadxrdb() ++{ ++  Display *display; ++  char * resm; ++  XrmDatabase xrdb; ++  char *type; ++  XrmValue value; ++ ++  display = XOpenDisplay(NULL); ++ ++  if (display != NULL) { ++    resm = XResourceManagerString(display); ++ ++    if (resm != NULL) { ++      xrdb = XrmGetStringDatabase(resm); ++ ++      if (xrdb != NULL) { ++        XRDB_LOAD_COLOR("dwm.normbordercolor", normbordercolor); ++        XRDB_LOAD_COLOR("dwm.normbgcolor", normbgcolor); ++        XRDB_LOAD_COLOR("dwm.normfgcolor", normfgcolor); ++        XRDB_LOAD_COLOR("dwm.selbordercolor", selbordercolor); ++        XRDB_LOAD_COLOR("dwm.selbgcolor", selbgcolor); ++        XRDB_LOAD_COLOR("dwm.selfgcolor", selfgcolor); ++      } ++    } ++  } ++ ++  XCloseDisplay(display); ++} ++ + void + manage(Window w, XWindowAttributes *wa) + { +@@ -2110,6 +2159,17 @@ xerrorstart(Display *dpy, XErrorEvent *ee) + 	return -1; + } +  ++void ++xrdb(const Arg *arg) ++{ ++  loadxrdb(); ++  int i; ++  for (i = 0; i < LENGTH(colors); i++) ++                scheme[i] = drw_scm_create(drw, colors[i], 3); ++  focus(NULL); ++  arrange(NULL); ++} ++ + void + zoom(const Arg *arg) + { +@@ -2136,6 +2196,8 @@ main(int argc, char *argv[]) + 	if (!(dpy = XOpenDisplay(NULL))) + 		die("dwm: cannot open display"); + 	checkotherwm(); ++        XrmInitialize(); ++        loadxrdb(); + 	setup(); + #ifdef __OpenBSD__ + 	if (pledge("stdio rpath proc exec", NULL) == -1) | 
