first commit
This commit is contained in:
		
						commit
						2201fa3a52
					
				
					 21 changed files with 5137 additions and 0 deletions
				
			
		
							
								
								
									
										37
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | MIT/X Consortium License | ||||||
|  | 
 | ||||||
|  | © 2006-2019 Anselm R Garbe <anselm@garbe.ca> | ||||||
|  | © 2006-2009 Jukka Salmi <jukka at salmi dot ch> | ||||||
|  | © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> | ||||||
|  | © 2007-2011 Peter Hartlich <sgkkr at hartlich dot com> | ||||||
|  | © 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com> | ||||||
|  | © 2007-2009 Christof Musik <christof at sendfax dot de> | ||||||
|  | © 2007-2009 Premysl Hruby <dfenze at gmail dot com> | ||||||
|  | © 2007-2008 Enno Gottox Boland <gottox at s01 dot de> | ||||||
|  | © 2008 Martin Hurton <martin dot hurton at gmail dot com> | ||||||
|  | © 2008 Neale Pickett <neale dot woozle dot org> | ||||||
|  | © 2009 Mate Nagy <mnagy at port70 dot net> | ||||||
|  | © 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org> | ||||||
|  | © 2010-2012 Connor Lane Smith <cls@lubutu.com> | ||||||
|  | © 2011 Christoph Lohmann <20h@r-36.net> | ||||||
|  | © 2015-2016 Quentin Rameau <quinq@fifth.space> | ||||||
|  | © 2015-2016 Eric Pruitt <eric.pruitt@gmail.com> | ||||||
|  | © 2016-2017 Markus Teich <markus.teich@stusta.mhn.de> | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a | ||||||
|  | copy of this software and associated documentation files (the "Software"), | ||||||
|  | to deal in the Software without restriction, including without limitation | ||||||
|  | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||||
|  | and/or sell copies of the Software, and to permit persons to whom the | ||||||
|  | Software is furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in | ||||||
|  | all copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||||
|  | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||||
|  | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||||
|  | DEALINGS IN THE SOFTWARE. | ||||||
							
								
								
									
										51
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | # dwm - dynamic window manager
 | ||||||
|  | # See LICENSE file for copyright and license details.
 | ||||||
|  | 
 | ||||||
|  | include config.mk | ||||||
|  | 
 | ||||||
|  | SRC = drw.c dwm.c util.c | ||||||
|  | OBJ = ${SRC:.c=.o} | ||||||
|  | 
 | ||||||
|  | all: options dwm | ||||||
|  | 
 | ||||||
|  | options: | ||||||
|  | 	@echo dwm build options: | ||||||
|  | 	@echo "CFLAGS   = ${CFLAGS}" | ||||||
|  | 	@echo "LDFLAGS  = ${LDFLAGS}" | ||||||
|  | 	@echo "CC       = ${CC}" | ||||||
|  | 
 | ||||||
|  | .c.o: | ||||||
|  | 	${CC} -c ${CFLAGS} $< | ||||||
|  | 
 | ||||||
|  | ${OBJ}: config.h config.mk | ||||||
|  | 
 | ||||||
|  | config.h: | ||||||
|  | 	cp config.def.h $@ | ||||||
|  | 
 | ||||||
|  | dwm: ${OBJ} | ||||||
|  | 	${CC} -o $@ ${OBJ} ${LDFLAGS} | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz | ||||||
|  | 
 | ||||||
|  | dist: clean | ||||||
|  | 	mkdir -p dwm-${VERSION} | ||||||
|  | 	cp -R LICENSE Makefile README config.def.h config.mk\
 | ||||||
|  | 		dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} | ||||||
|  | 	tar -cf dwm-${VERSION}.tar dwm-${VERSION} | ||||||
|  | 	gzip dwm-${VERSION}.tar | ||||||
|  | 	rm -rf dwm-${VERSION} | ||||||
|  | 
 | ||||||
|  | install: all | ||||||
|  | 	mkdir -p ${DESTDIR}${PREFIX}/bin | ||||||
|  | 	cp -f dwm ${DESTDIR}${PREFIX}/bin | ||||||
|  | 	chmod 755 ${DESTDIR}${PREFIX}/bin/dwm | ||||||
|  | 	mkdir -p ${DESTDIR}${MANPREFIX}/man1 | ||||||
|  | 	sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 | ||||||
|  | 	chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 | ||||||
|  | 
 | ||||||
|  | uninstall: | ||||||
|  | 	rm -f ${DESTDIR}${PREFIX}/bin/dwm\
 | ||||||
|  | 		${DESTDIR}${MANPREFIX}/man1/dwm.1 | ||||||
|  | 
 | ||||||
|  | .PHONY: all options clean dist install uninstall | ||||||
							
								
								
									
										49
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | ||||||
|  | dwm - dynamic window manager | ||||||
|  | ============================ | ||||||
|  | dwm is an extremely fast, small, and dynamic window manager for X. | ||||||
|  | This is my build of dwm. It contains pactches and changes that work for me. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										151
									
								
								config.def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								config.def.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,151 @@ | ||||||
|  | /* 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 unsigned int gappih    = 20;       /* horiz inner gap between windows */ | ||||||
|  | static const unsigned int gappiv    = 10;       /* vert inner gap between windows */ | ||||||
|  | static const unsigned int gappoh    = 10;       /* horiz outer gap between windows and screen edge */ | ||||||
|  | static const unsigned int gappov    = 30;       /* vert outer gap between windows and screen edge */ | ||||||
|  | static       int smartgaps          = 0;        /* 1 means no outer gap when there is only one window */ | ||||||
|  | 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  }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* 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 */ | ||||||
|  | 	{ "Gimp",     NULL,       NULL,       0,            1,           -1 }, | ||||||
|  | 	{ "Firefox",  NULL,       NULL,       1 << 8,       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 */ | ||||||
|  | 
 | ||||||
|  | #define FORCE_VSPLIT 1  /* nrowgrid layout: force two clients to always split vertically */ | ||||||
|  | #include "vanitygaps.c" | ||||||
|  | 
 | ||||||
|  | static const Layout layouts[] = { | ||||||
|  | 	/* symbol     arrange function */ | ||||||
|  | 	{ "[]=",      tile },    /* first entry is default */ | ||||||
|  | 	{ "[M]",      monocle }, | ||||||
|  | 	{ "[@]",      spiral }, | ||||||
|  | 	{ "[\\]",     dwindle }, | ||||||
|  | 	{ "H[]",      deck }, | ||||||
|  | 	{ "TTT",      bstack }, | ||||||
|  | 	{ "===",      bstackhoriz }, | ||||||
|  | 	{ "HHH",      grid }, | ||||||
|  | 	{ "###",      nrowgrid }, | ||||||
|  | 	{ "---",      horizgrid }, | ||||||
|  | 	{ ":::",      gaplessgrid }, | ||||||
|  | 	{ "|M|",      centeredmaster }, | ||||||
|  | 	{ ">M>",      centeredfloatingmaster }, | ||||||
|  | 	{ "><>",      NULL },    /* no layout function means floating behavior */ | ||||||
|  | 	{ NULL,       NULL }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* key definitions */ | ||||||
|  | #define MODKEY Mod1Mask | ||||||
|  | #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 } } | ||||||
|  | 
 | ||||||
|  | /* 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_p,      spawn,          {.v = dmenucmd } }, | ||||||
|  | 	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } }, | ||||||
|  | 	{ MODKEY,                       XK_b,      togglebar,      {0} }, | ||||||
|  | 	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} }, | ||||||
|  | 	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} }, | ||||||
|  | 	{ MODKEY,                       XK_Return, zoom,           {0} }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_u,      incrgaps,       {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_u,      incrgaps,       {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_i,      incrigaps,      {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_i,      incrigaps,      {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_o,      incrogaps,      {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_o,      incrogaps,      {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_6,      incrihgaps,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_6,      incrihgaps,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_7,      incrivgaps,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_7,      incrivgaps,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_8,      incrohgaps,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_8,      incrohgaps,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_9,      incrovgaps,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_9,      incrovgaps,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY|Mod4Mask,              XK_0,      togglegaps,     {0} }, | ||||||
|  | 	{ MODKEY|Mod4Mask|ShiftMask,    XK_0,      defaultgaps,    {0} }, | ||||||
|  | 	{ MODKEY,                       XK_Tab,    view,           {0} }, | ||||||
|  | 	{ MODKEY|ShiftMask,             XK_c,      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_0,      view,           {.ui = ~0 } }, | ||||||
|  | 	{ MODKEY|ShiftMask,             XK_0,      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_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|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} }, | ||||||
|  | 	{ 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} }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
							
								
								
									
										152
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,152 @@ | ||||||
|  | /* 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            = 1;        /* 0 means no bar */ | ||||||
|  | static const int topbar             = 1;        /* 0 means bottom bar */ | ||||||
|  | static const unsigned int gappih    = 5;        /* horiz inner gap between windows */     | ||||||
|  | static const unsigned int gappiv    = 5;        /* vert inner gap between windows */     | ||||||
|  | static const unsigned int gappoh    = 5;        /* horiz outer gap between windows and screen edge */ | ||||||
|  | static const unsigned int gappov    = 5;        /* vert outer gap between windows and screen edge */ | ||||||
|  | static       int smartgaps          = 0;        /* 1 means no outer gap when there is only one window */ | ||||||
|  | static const char *fonts[]          = { "Roboto Mono:size=10", "Joypixels:size=10" }; | ||||||
|  | static const char dmenufont[]       = "Roboto Mono: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[]        = "#1c343c"; | ||||||
|  | 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 */ | ||||||
|  | 	{ "Gimp",     NULL,       NULL,       0,            1,           -1 }, | ||||||
|  | 	{ "Firefox",  NULL,       NULL,       1 << 8,       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 = 0;    /* 1 means respect size hints in tiled resizals */ | ||||||
|  | 
 | ||||||
|  | #define FORCE_VSPLIT 1  /* nrowgrid layout: force two clients to always split vertically */     | ||||||
|  | #include "vanitygaps.c" | ||||||
|  | 
 | ||||||
|  | static const Layout layouts[] = { | ||||||
|  |     /* symbol     arrange function */ | ||||||
|  |     { "[]=",      tile },    /* first entry is default */ | ||||||
|  |     { "[M]",      monocle }, | ||||||
|  |     { "[@]",      spiral }, | ||||||
|  |     { "[\\]",     dwindle }, | ||||||
|  |     { "H[]",      deck }, | ||||||
|  |     { "TTT",      bstack }, | ||||||
|  |     { "===",      bstackhoriz }, | ||||||
|  |     { "HHH",      grid }, | ||||||
|  |     { "###",      nrowgrid }, | ||||||
|  |     { "---",      horizgrid }, | ||||||
|  |     { ":::",      gaplessgrid }, | ||||||
|  |     { "|M|",      centeredmaster }, | ||||||
|  |     { ">M>",      centeredfloatingmaster }, | ||||||
|  |     { "><>",      NULL },    /* no layout function means floating behavior */ | ||||||
|  |     { NULL,       NULL }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* 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} }, | ||||||
|  | 
 | ||||||
|  | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
|  | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  | 
 | ||||||
|  | /* make audio keys work */ | ||||||
|  | #include <X11/XF86keysym.h> | ||||||
|  | 
 | ||||||
|  | /* 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 const char *vivaldi[]  = { "vivaldi-stable", NULL }; | ||||||
|  | static const char *passmenu[] = { "passmenu", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, "-l", "5", NULL }; | ||||||
|  | static const char *scrotwin[]  = { "sleep", "0.5", "&&", "scrot", "-s", NULL }; | ||||||
|  | static const char *manmenu[]  = { "manmenu", NULL }; | ||||||
|  | static const char *upvol[]   = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "+2%", NULL }; | ||||||
|  | static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "-2%", NULL }; | ||||||
|  | static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle", NULL }; | ||||||
|  | 
 | ||||||
|  | static Key keys[] = { | ||||||
|  | 	/* modifier                     key        function        argument */ | ||||||
|  | 	{ MODKEY,                       XK_d,      spawn,          {.v = dmenucmd } }, | ||||||
|  | 	{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } }, | ||||||
|  | 	{ MODKEY,                       XK_b,      togglebar,      {0} }, | ||||||
|  | 	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } }, | ||||||
|  | 	{ MODKEY,                       XK_o,      incnmaster,     {.i = -1 } }, | ||||||
|  | 	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} }, | ||||||
|  | 	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} }, | ||||||
|  | 	{ MODKEY,                       XK_v,      zoom,           {0} }, | ||||||
|  | 	{ MODKEY,                       XK_Tab,    view,           {0} }, | ||||||
|  | 	{ MODKEY|ShiftMask,             XK_q,      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_0,      view,           {.ui = ~0 } }, | ||||||
|  | 	{ MODKEY|ShiftMask,             XK_0,      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 } }, | ||||||
|  |     { MODKEY,                       XK_w,      spawn,          {.v = vivaldi } }, | ||||||
|  |     { MODKEY,                       XK_p,      spawn,          {.v = passmenu } }, | ||||||
|  |     { MODKEY,                       XK_z,      spawn,          {.v = scrotwin } }, | ||||||
|  |     { MODKEY,                       XK_c,      spawn,          {.v = manmenu } }, | ||||||
|  | 	{ MODKEY,                       XK_F12,    spawn,          {.v = upvol   } }, | ||||||
|  |     { MODKEY,                       XK_F11,    spawn,          {.v = downvol } }, | ||||||
|  | 	{ MODKEY,                       XK_F10,    spawn,          {.v = mutevol } }, | ||||||
|  | 	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|ShiftMask,             XK_u,      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} }, | ||||||
|  | 	{ 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} }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
							
								
								
									
										38
									
								
								config.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								config.mk
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | # dwm version
 | ||||||
|  | VERSION = 6.2 | ||||||
|  | 
 | ||||||
|  | # Customize below to fit your system
 | ||||||
|  | 
 | ||||||
|  | # paths
 | ||||||
|  | PREFIX = /usr/local | ||||||
|  | MANPREFIX = ${PREFIX}/share/man | ||||||
|  | 
 | ||||||
|  | X11INC = /usr/X11R6/include | ||||||
|  | X11LIB = /usr/X11R6/lib | ||||||
|  | 
 | ||||||
|  | # Xinerama, comment if you don't want it
 | ||||||
|  | XINERAMALIBS  = -lXinerama | ||||||
|  | XINERAMAFLAGS = -DXINERAMA | ||||||
|  | 
 | ||||||
|  | # freetype
 | ||||||
|  | FREETYPELIBS = -lfontconfig -lXft | ||||||
|  | FREETYPEINC = /usr/include/freetype2 | ||||||
|  | # OpenBSD (uncomment)
 | ||||||
|  | #FREETYPEINC = ${X11INC}/freetype2
 | ||||||
|  | 
 | ||||||
|  | # includes and libs
 | ||||||
|  | INCS = -I${X11INC} -I${FREETYPEINC} | ||||||
|  | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | ||||||
|  | 
 | ||||||
|  | # flags
 | ||||||
|  | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | ||||||
|  | #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
 | ||||||
|  | CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} | ||||||
|  | LDFLAGS  = ${LIBS} | ||||||
|  | 
 | ||||||
|  | # Solaris
 | ||||||
|  | #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
 | ||||||
|  | #LDFLAGS = ${LIBS}
 | ||||||
|  | 
 | ||||||
|  | # compiler and linker
 | ||||||
|  | CC = cc | ||||||
							
								
								
									
										422
									
								
								drw.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										422
									
								
								drw.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,422 @@ | ||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <X11/Xlib.h> | ||||||
|  | #include <X11/Xft/Xft.h> | ||||||
|  | 
 | ||||||
|  | #include "drw.h" | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | #define UTF_INVALID 0xFFFD | ||||||
|  | #define UTF_SIZ     4 | ||||||
|  | 
 | ||||||
|  | static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0}; | ||||||
|  | static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | ||||||
|  | static const long utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000}; | ||||||
|  | static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | ||||||
|  | 
 | ||||||
|  | static long | ||||||
|  | utf8decodebyte(const char c, size_t *i) | ||||||
|  | { | ||||||
|  | 	for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | ||||||
|  | 		if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | ||||||
|  | 			return (unsigned char)c & ~utfmask[*i]; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static size_t | ||||||
|  | utf8validate(long *u, size_t i) | ||||||
|  | { | ||||||
|  | 	if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | ||||||
|  | 		*u = UTF_INVALID; | ||||||
|  | 	for (i = 1; *u > utfmax[i]; ++i) | ||||||
|  | 		; | ||||||
|  | 	return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static size_t | ||||||
|  | utf8decode(const char *c, long *u, size_t clen) | ||||||
|  | { | ||||||
|  | 	size_t i, j, len, type; | ||||||
|  | 	long udecoded; | ||||||
|  | 
 | ||||||
|  | 	*u = UTF_INVALID; | ||||||
|  | 	if (!clen) | ||||||
|  | 		return 0; | ||||||
|  | 	udecoded = utf8decodebyte(c[0], &len); | ||||||
|  | 	if (!BETWEEN(len, 1, UTF_SIZ)) | ||||||
|  | 		return 1; | ||||||
|  | 	for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { | ||||||
|  | 		udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); | ||||||
|  | 		if (type) | ||||||
|  | 			return j; | ||||||
|  | 	} | ||||||
|  | 	if (j < len) | ||||||
|  | 		return 0; | ||||||
|  | 	*u = udecoded; | ||||||
|  | 	utf8validate(u, len); | ||||||
|  | 
 | ||||||
|  | 	return len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Drw * | ||||||
|  | drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) | ||||||
|  | { | ||||||
|  | 	Drw *drw = ecalloc(1, sizeof(Drw)); | ||||||
|  | 
 | ||||||
|  | 	drw->dpy = dpy; | ||||||
|  | 	drw->screen = screen; | ||||||
|  | 	drw->root = root; | ||||||
|  | 	drw->w = w; | ||||||
|  | 	drw->h = h; | ||||||
|  | 	drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); | ||||||
|  | 	drw->gc = XCreateGC(dpy, root, 0, NULL); | ||||||
|  | 	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); | ||||||
|  | 
 | ||||||
|  | 	return drw; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_resize(Drw *drw, unsigned int w, unsigned int h) | ||||||
|  | { | ||||||
|  | 	if (!drw) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	drw->w = w; | ||||||
|  | 	drw->h = h; | ||||||
|  | 	if (drw->drawable) | ||||||
|  | 		XFreePixmap(drw->dpy, drw->drawable); | ||||||
|  | 	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_free(Drw *drw) | ||||||
|  | { | ||||||
|  | 	XFreePixmap(drw->dpy, drw->drawable); | ||||||
|  | 	XFreeGC(drw->dpy, drw->gc); | ||||||
|  | 	free(drw); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* This function is an implementation detail. Library users should use
 | ||||||
|  |  * drw_fontset_create instead. | ||||||
|  |  */ | ||||||
|  | static Fnt * | ||||||
|  | xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) | ||||||
|  | { | ||||||
|  | 	Fnt *font; | ||||||
|  | 	XftFont *xfont = NULL; | ||||||
|  | 	FcPattern *pattern = NULL; | ||||||
|  | 
 | ||||||
|  | 	if (fontname) { | ||||||
|  | 		/* Using the pattern found at font->xfont->pattern does not yield the
 | ||||||
|  | 		 * same substitution results as using the pattern returned by | ||||||
|  | 		 * FcNameParse; using the latter results in the desired fallback | ||||||
|  | 		 * behaviour whereas the former just results in missing-character | ||||||
|  | 		 * rectangles being drawn, at least with some fonts. */ | ||||||
|  | 		if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { | ||||||
|  | 			fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 		if (!(pattern = FcNameParse((FcChar8 *) fontname))) { | ||||||
|  | 			fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); | ||||||
|  | 			XftFontClose(drw->dpy, xfont); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} else if (fontpattern) { | ||||||
|  | 		if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { | ||||||
|  | 			fprintf(stderr, "error, cannot load font from pattern.\n"); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		die("no font specified."); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	font = ecalloc(1, sizeof(Fnt)); | ||||||
|  | 	font->xfont = xfont; | ||||||
|  | 	font->pattern = pattern; | ||||||
|  | 	font->h = xfont->ascent + xfont->descent; | ||||||
|  | 	font->dpy = drw->dpy; | ||||||
|  | 
 | ||||||
|  | 	return font; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | xfont_free(Fnt *font) | ||||||
|  | { | ||||||
|  | 	if (!font) | ||||||
|  | 		return; | ||||||
|  | 	if (font->pattern) | ||||||
|  | 		FcPatternDestroy(font->pattern); | ||||||
|  | 	XftFontClose(font->dpy, font->xfont); | ||||||
|  | 	free(font); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Fnt* | ||||||
|  | drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) | ||||||
|  | { | ||||||
|  | 	Fnt *cur, *ret = NULL; | ||||||
|  | 	size_t i; | ||||||
|  | 
 | ||||||
|  | 	if (!drw || !fonts) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	for (i = 1; i <= fontcount; i++) { | ||||||
|  | 		if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { | ||||||
|  | 			cur->next = ret; | ||||||
|  | 			ret = cur; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return (drw->fonts = ret); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_fontset_free(Fnt *font) | ||||||
|  | { | ||||||
|  | 	if (font) { | ||||||
|  | 		drw_fontset_free(font->next); | ||||||
|  | 		xfont_free(font); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_clr_create(Drw *drw, Clr *dest, const char *clrname) | ||||||
|  | { | ||||||
|  | 	if (!drw || !dest || !clrname) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), | ||||||
|  | 	                       DefaultColormap(drw->dpy, drw->screen), | ||||||
|  | 	                       clrname, dest)) | ||||||
|  | 		die("error, cannot allocate color '%s'", 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) | ||||||
|  | { | ||||||
|  | 	size_t i; | ||||||
|  | 	Clr *ret; | ||||||
|  | 
 | ||||||
|  | 	/* need at least two colors for a scheme */ | ||||||
|  | 	if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < clrcount; i++) | ||||||
|  | 		drw_clr_create(drw, &ret[i], clrnames[i]); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_setfontset(Drw *drw, Fnt *set) | ||||||
|  | { | ||||||
|  | 	if (drw) | ||||||
|  | 		drw->fonts = set; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_setscheme(Drw *drw, Clr *scm) | ||||||
|  | { | ||||||
|  | 	if (drw) | ||||||
|  | 		drw->scheme = scm; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) | ||||||
|  | { | ||||||
|  | 	if (!drw || !drw->scheme) | ||||||
|  | 		return; | ||||||
|  | 	XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); | ||||||
|  | 	if (filled) | ||||||
|  | 		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | ||||||
|  | 	else | ||||||
|  | 		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) | ||||||
|  | { | ||||||
|  | 	char buf[1024]; | ||||||
|  | 	int ty; | ||||||
|  | 	unsigned int ew; | ||||||
|  | 	XftDraw *d = NULL; | ||||||
|  | 	Fnt *usedfont, *curfont, *nextfont; | ||||||
|  | 	size_t i, len; | ||||||
|  | 	int utf8strlen, utf8charlen, render = x || y || w || h; | ||||||
|  | 	long utf8codepoint = 0; | ||||||
|  | 	const char *utf8str; | ||||||
|  | 	FcCharSet *fccharset; | ||||||
|  | 	FcPattern *fcpattern; | ||||||
|  | 	FcPattern *match; | ||||||
|  | 	XftResult result; | ||||||
|  | 	int charexists = 0; | ||||||
|  | 
 | ||||||
|  | 	if (!drw || (render && !drw->scheme) || !text || !drw->fonts) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	if (!render) { | ||||||
|  | 		w = ~w; | ||||||
|  | 	} else { | ||||||
|  | 		XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); | ||||||
|  | 		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | ||||||
|  | 		d = XftDrawCreate(drw->dpy, drw->drawable, | ||||||
|  | 		                  DefaultVisual(drw->dpy, drw->screen), | ||||||
|  | 		                  DefaultColormap(drw->dpy, drw->screen)); | ||||||
|  | 		x += lpad; | ||||||
|  | 		w -= lpad; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	usedfont = drw->fonts; | ||||||
|  | 	while (1) { | ||||||
|  | 		utf8strlen = 0; | ||||||
|  | 		utf8str = text; | ||||||
|  | 		nextfont = NULL; | ||||||
|  | 		while (*text) { | ||||||
|  | 			utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); | ||||||
|  | 			for (curfont = drw->fonts; curfont; curfont = curfont->next) { | ||||||
|  | 				charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); | ||||||
|  | 				if (charexists) { | ||||||
|  | 					if (curfont == usedfont) { | ||||||
|  | 						utf8strlen += utf8charlen; | ||||||
|  | 						text += utf8charlen; | ||||||
|  | 					} else { | ||||||
|  | 						nextfont = curfont; | ||||||
|  | 					} | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!charexists || nextfont) | ||||||
|  | 				break; | ||||||
|  | 			else | ||||||
|  | 				charexists = 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (utf8strlen) { | ||||||
|  | 			drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); | ||||||
|  | 			/* shorten text if necessary */ | ||||||
|  | 			for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) | ||||||
|  | 				drw_font_getexts(usedfont, utf8str, len, &ew, NULL); | ||||||
|  | 
 | ||||||
|  | 			if (len) { | ||||||
|  | 				memcpy(buf, utf8str, len); | ||||||
|  | 				buf[len] = '\0'; | ||||||
|  | 				if (len < utf8strlen) | ||||||
|  | 					for (i = len; i && i > len - 3; buf[--i] = '.') | ||||||
|  | 						; /* NOP */ | ||||||
|  | 
 | ||||||
|  | 				if (render) { | ||||||
|  | 					ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; | ||||||
|  | 					XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], | ||||||
|  | 					                  usedfont->xfont, x, ty, (XftChar8 *)buf, len); | ||||||
|  | 				} | ||||||
|  | 				x += ew; | ||||||
|  | 				w -= ew; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!*text) { | ||||||
|  | 			break; | ||||||
|  | 		} else if (nextfont) { | ||||||
|  | 			charexists = 0; | ||||||
|  | 			usedfont = nextfont; | ||||||
|  | 		} else { | ||||||
|  | 			/* Regardless of whether or not a fallback font is found, the
 | ||||||
|  | 			 * character must be drawn. */ | ||||||
|  | 			charexists = 1; | ||||||
|  | 
 | ||||||
|  | 			fccharset = FcCharSetCreate(); | ||||||
|  | 			FcCharSetAddChar(fccharset, utf8codepoint); | ||||||
|  | 
 | ||||||
|  | 			if (!drw->fonts->pattern) { | ||||||
|  | 				/* Refer to the comment in xfont_create for more information. */ | ||||||
|  | 				die("the first font in the cache must be loaded from a font string."); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			fcpattern = FcPatternDuplicate(drw->fonts->pattern); | ||||||
|  | 			FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); | ||||||
|  | 			FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); | ||||||
|  | 			FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); | ||||||
|  | 
 | ||||||
|  | 			FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); | ||||||
|  | 			FcDefaultSubstitute(fcpattern); | ||||||
|  | 			match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); | ||||||
|  | 
 | ||||||
|  | 			FcCharSetDestroy(fccharset); | ||||||
|  | 			FcPatternDestroy(fcpattern); | ||||||
|  | 
 | ||||||
|  | 			if (match) { | ||||||
|  | 				usedfont = xfont_create(drw, NULL, match); | ||||||
|  | 				if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { | ||||||
|  | 					for (curfont = drw->fonts; curfont->next; curfont = curfont->next) | ||||||
|  | 						; /* NOP */ | ||||||
|  | 					curfont->next = usedfont; | ||||||
|  | 				} else { | ||||||
|  | 					xfont_free(usedfont); | ||||||
|  | 					usedfont = drw->fonts; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if (d) | ||||||
|  | 		XftDrawDestroy(d); | ||||||
|  | 
 | ||||||
|  | 	return x + (render ? w : 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) | ||||||
|  | { | ||||||
|  | 	if (!drw) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); | ||||||
|  | 	XSync(drw->dpy, False); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned int | ||||||
|  | drw_fontset_getwidth(Drw *drw, const char *text) | ||||||
|  | { | ||||||
|  | 	if (!drw || !drw->fonts || !text) | ||||||
|  | 		return 0; | ||||||
|  | 	return drw_text(drw, 0, 0, 0, 0, 0, text, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) | ||||||
|  | { | ||||||
|  | 	XGlyphInfo ext; | ||||||
|  | 
 | ||||||
|  | 	if (!font || !text) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); | ||||||
|  | 	if (w) | ||||||
|  | 		*w = ext.xOff; | ||||||
|  | 	if (h) | ||||||
|  | 		*h = font->h; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Cur * | ||||||
|  | drw_cur_create(Drw *drw, int shape) | ||||||
|  | { | ||||||
|  | 	Cur *cur; | ||||||
|  | 
 | ||||||
|  | 	if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	cur->cursor = XCreateFontCursor(drw->dpy, shape); | ||||||
|  | 
 | ||||||
|  | 	return cur; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | drw_cur_free(Drw *drw, Cur *cursor) | ||||||
|  | { | ||||||
|  | 	if (!cursor) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	XFreeCursor(drw->dpy, cursor->cursor); | ||||||
|  | 	free(cursor); | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								drw.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								drw.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | ||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Cursor cursor; | ||||||
|  | } Cur; | ||||||
|  | 
 | ||||||
|  | typedef struct Fnt { | ||||||
|  | 	Display *dpy; | ||||||
|  | 	unsigned int h; | ||||||
|  | 	XftFont *xfont; | ||||||
|  | 	FcPattern *pattern; | ||||||
|  | 	struct Fnt *next; | ||||||
|  | } Fnt; | ||||||
|  | 
 | ||||||
|  | enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ | ||||||
|  | typedef XftColor Clr; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	unsigned int w, h; | ||||||
|  | 	Display *dpy; | ||||||
|  | 	int screen; | ||||||
|  | 	Window root; | ||||||
|  | 	Drawable drawable; | ||||||
|  | 	GC gc; | ||||||
|  | 	Clr *scheme; | ||||||
|  | 	Fnt *fonts; | ||||||
|  | } Drw; | ||||||
|  | 
 | ||||||
|  | /* Drawable abstraction */ | ||||||
|  | Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); | ||||||
|  | void drw_resize(Drw *drw, unsigned int w, unsigned int h); | ||||||
|  | void drw_free(Drw *drw); | ||||||
|  | 
 | ||||||
|  | /* Fnt abstraction */ | ||||||
|  | Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); | ||||||
|  | void drw_fontset_free(Fnt* set); | ||||||
|  | unsigned int drw_fontset_getwidth(Drw *drw, const char *text); | ||||||
|  | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); | ||||||
|  | 
 | ||||||
|  | /* 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); | ||||||
|  | 
 | ||||||
|  | /* Cursor abstraction */ | ||||||
|  | Cur *drw_cur_create(Drw *drw, int shape); | ||||||
|  | void drw_cur_free(Drw *drw, Cur *cursor); | ||||||
|  | 
 | ||||||
|  | /* Drawing context manipulation */ | ||||||
|  | void drw_setfontset(Drw *drw, Fnt *set); | ||||||
|  | void drw_setscheme(Drw *drw, Clr *scm); | ||||||
|  | 
 | ||||||
|  | /* Drawing functions */ | ||||||
|  | void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); | ||||||
|  | int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); | ||||||
|  | 
 | ||||||
|  | /* Map functions */ | ||||||
|  | void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); | ||||||
							
								
								
									
										
											BIN
										
									
								
								drw.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								drw.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								dwm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dwm
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										971
									
								
								dwm-vanitygaps-6.2.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										971
									
								
								dwm-vanitygaps-6.2.diff
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,971 @@ | ||||||
|  | From 9709d08daa290c8c7319571cd9e6ef4ec40e7683 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: bakkeby <bakkeby@gmail.com> | ||||||
|  | Date: Wed, 6 May 2020 17:21:25 +0200 | ||||||
|  | Subject: [PATCH] vanitygaps - adds gaps to layouts | ||||||
|  | 
 | ||||||
|  | This patch differentiates between inner and outer gaps as well as | ||||||
|  | horizontal and vertical gaps. | ||||||
|  | 
 | ||||||
|  | The logic of these layouts also aims to be pixel perfect by ensuring | ||||||
|  | an even split of the available space and re-distributing the remainder | ||||||
|  | among the available clients. | ||||||
|  | ---
 | ||||||
|  |  config.def.h |  38 ++- | ||||||
|  |  dwm.c        |  35 +-- | ||||||
|  |  vanitygaps.c | 809 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  3 files changed, 854 insertions(+), 28 deletions(-) | ||||||
|  |  create mode 100644 vanitygaps.c | ||||||
|  | 
 | ||||||
|  | diff --git a/config.def.h b/config.def.h
 | ||||||
|  | index 1c0b587..a886863 100644
 | ||||||
|  | --- a/config.def.h
 | ||||||
|  | +++ b/config.def.h
 | ||||||
|  | @@ -3,6 +3,11 @@
 | ||||||
|  |  /* appearance */ | ||||||
|  |  static const unsigned int borderpx  = 1;        /* border pixel of windows */ | ||||||
|  |  static const unsigned int snap      = 32;       /* snap pixel */ | ||||||
|  | +static const unsigned int gappih    = 20;       /* horiz inner gap between windows */
 | ||||||
|  | +static const unsigned int gappiv    = 10;       /* vert inner gap between windows */
 | ||||||
|  | +static const unsigned int gappoh    = 10;       /* horiz outer gap between windows and screen edge */
 | ||||||
|  | +static const unsigned int gappov    = 30;       /* vert outer gap between windows and screen edge */
 | ||||||
|  | +static       int smartgaps          = 0;        /* 1 means no outer gap when there is only one window */
 | ||||||
|  |  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" }; | ||||||
|  | @@ -36,11 +41,26 @@ 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 */ | ||||||
|  |   | ||||||
|  | +#define FORCE_VSPLIT 1  /* nrowgrid layout: force two clients to always split vertically */
 | ||||||
|  | +#include "vanitygaps.c"
 | ||||||
|  | +
 | ||||||
|  |  static const Layout layouts[] = { | ||||||
|  |  	/* symbol     arrange function */ | ||||||
|  |  	{ "[]=",      tile },    /* first entry is default */ | ||||||
|  | -	{ "><>",      NULL },    /* no layout function means floating behavior */
 | ||||||
|  |  	{ "[M]",      monocle }, | ||||||
|  | +	{ "[@]",      spiral },
 | ||||||
|  | +	{ "[\\]",     dwindle },
 | ||||||
|  | +	{ "H[]",      deck },
 | ||||||
|  | +	{ "TTT",      bstack },
 | ||||||
|  | +	{ "===",      bstackhoriz },
 | ||||||
|  | +	{ "HHH",      grid },
 | ||||||
|  | +	{ "###",      nrowgrid },
 | ||||||
|  | +	{ "---",      horizgrid },
 | ||||||
|  | +	{ ":::",      gaplessgrid },
 | ||||||
|  | +	{ "|M|",      centeredmaster },
 | ||||||
|  | +	{ ">M>",      centeredfloatingmaster },
 | ||||||
|  | +	{ "><>",      NULL },    /* no layout function means floating behavior */
 | ||||||
|  | +	{ NULL,       NULL },
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* key definitions */ | ||||||
|  | @@ -71,6 +91,22 @@ static Key keys[] = {
 | ||||||
|  |  	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} }, | ||||||
|  |  	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} }, | ||||||
|  |  	{ MODKEY,                       XK_Return, zoom,           {0} }, | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_u,      incrgaps,       {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_u,      incrgaps,       {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_i,      incrigaps,      {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_i,      incrigaps,      {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_o,      incrogaps,      {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_o,      incrogaps,      {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_6,      incrihgaps,     {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_6,      incrihgaps,     {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_7,      incrivgaps,     {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_7,      incrivgaps,     {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_8,      incrohgaps,     {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_8,      incrohgaps,     {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_9,      incrovgaps,     {.i = +1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_9,      incrovgaps,     {.i = -1 } },
 | ||||||
|  | +	{ MODKEY|Mod4Mask,              XK_0,      togglegaps,     {0} },
 | ||||||
|  | +	{ MODKEY|Mod4Mask|ShiftMask,    XK_0,      defaultgaps,    {0} },
 | ||||||
|  |  	{ MODKEY,                       XK_Tab,    view,           {0} }, | ||||||
|  |  	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} }, | ||||||
|  |  	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} }, | ||||||
|  | diff --git a/dwm.c b/dwm.c
 | ||||||
|  | index 4465af1..c3b2d82 100644
 | ||||||
|  | --- a/dwm.c
 | ||||||
|  | +++ b/dwm.c
 | ||||||
|  | @@ -119,6 +119,10 @@ struct Monitor {
 | ||||||
|  |  	int by;               /* bar geometry */ | ||||||
|  |  	int mx, my, mw, mh;   /* screen size */ | ||||||
|  |  	int wx, wy, ww, wh;   /* window area  */ | ||||||
|  | +	int gappih;           /* horizontal gap between windows */
 | ||||||
|  | +	int gappiv;           /* vertical gap between windows */
 | ||||||
|  | +	int gappoh;           /* horizontal outer gaps */
 | ||||||
|  | +	int gappov;           /* vertical outer gaps */
 | ||||||
|  |  	unsigned int seltags; | ||||||
|  |  	unsigned int sellt; | ||||||
|  |  	unsigned int tagset[2]; | ||||||
|  | @@ -208,7 +212,6 @@ static void sigchld(int unused);
 | ||||||
|  |  static void spawn(const Arg *arg); | ||||||
|  |  static void tag(const Arg *arg); | ||||||
|  |  static void tagmon(const Arg *arg); | ||||||
|  | -static void tile(Monitor *);
 | ||||||
|  |  static void togglebar(const Arg *arg); | ||||||
|  |  static void togglefloating(const Arg *arg); | ||||||
|  |  static void toggletag(const Arg *arg); | ||||||
|  | @@ -638,6 +641,10 @@ createmon(void)
 | ||||||
|  |  	m->nmaster = nmaster; | ||||||
|  |  	m->showbar = showbar; | ||||||
|  |  	m->topbar = topbar; | ||||||
|  | +	m->gappih = gappih;
 | ||||||
|  | +	m->gappiv = gappiv;
 | ||||||
|  | +	m->gappoh = gappoh;
 | ||||||
|  | +	m->gappov = gappov;
 | ||||||
|  |  	m->lt[0] = &layouts[0]; | ||||||
|  |  	m->lt[1] = &layouts[1 % LENGTH(layouts)]; | ||||||
|  |  	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); | ||||||
|  | @@ -1670,32 +1677,6 @@ tagmon(const Arg *arg)
 | ||||||
|  |  	sendmon(selmon->sel, dirtomon(arg->i)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void
 | ||||||
|  | -tile(Monitor *m)
 | ||||||
|  | -{
 | ||||||
|  | -	unsigned int i, n, h, mw, my, ty;
 | ||||||
|  | -	Client *c;
 | ||||||
|  | -
 | ||||||
|  | -	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
 | ||||||
|  | -	if (n == 0)
 | ||||||
|  | -		return;
 | ||||||
|  | -
 | ||||||
|  | -	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++)
 | ||||||
|  | -		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);
 | ||||||
|  | -		} 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);
 | ||||||
|  | -		}
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  |  void | ||||||
|  |  togglebar(const Arg *arg) | ||||||
|  |  { | ||||||
|  | diff --git a/vanitygaps.c b/vanitygaps.c
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000..3f31593
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/vanitygaps.c
 | ||||||
|  | @@ -0,0 +1,809 @@
 | ||||||
|  | +/* Key binding functions */
 | ||||||
|  | +static void defaultgaps(const Arg *arg);
 | ||||||
|  | +static void incrgaps(const Arg *arg);
 | ||||||
|  | +static void incrigaps(const Arg *arg);
 | ||||||
|  | +static void incrogaps(const Arg *arg);
 | ||||||
|  | +static void incrohgaps(const Arg *arg);
 | ||||||
|  | +static void incrovgaps(const Arg *arg);
 | ||||||
|  | +static void incrihgaps(const Arg *arg);
 | ||||||
|  | +static void incrivgaps(const Arg *arg);
 | ||||||
|  | +static void togglegaps(const Arg *arg);
 | ||||||
|  | +/* Layouts (delete the ones you do not need) */
 | ||||||
|  | +static void bstack(Monitor *m);
 | ||||||
|  | +static void bstackhoriz(Monitor *m);
 | ||||||
|  | +static void centeredmaster(Monitor *m);
 | ||||||
|  | +static void centeredfloatingmaster(Monitor *m);
 | ||||||
|  | +static void deck(Monitor *m);
 | ||||||
|  | +static void dwindle(Monitor *m);
 | ||||||
|  | +static void fibonacci(Monitor *m, int s);
 | ||||||
|  | +static void grid(Monitor *m);
 | ||||||
|  | +static void nrowgrid(Monitor *m);
 | ||||||
|  | +static void spiral(Monitor *m);
 | ||||||
|  | +static void tile(Monitor *m);
 | ||||||
|  | +/* Internals */
 | ||||||
|  | +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
 | ||||||
|  | +static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
 | ||||||
|  | +static void setgaps(int oh, int ov, int ih, int iv);
 | ||||||
|  | +
 | ||||||
|  | +/* Settings */
 | ||||||
|  | +#if !PERTAG_PATCH
 | ||||||
|  | +static int enablegaps = 1;
 | ||||||
|  | +#endif // PERTAG_PATCH
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +setgaps(int oh, int ov, int ih, int iv)
 | ||||||
|  | +{
 | ||||||
|  | +	if (oh < 0) oh = 0;
 | ||||||
|  | +	if (ov < 0) ov = 0;
 | ||||||
|  | +	if (ih < 0) ih = 0;
 | ||||||
|  | +	if (iv < 0) iv = 0;
 | ||||||
|  | +
 | ||||||
|  | +	selmon->gappoh = oh;
 | ||||||
|  | +	selmon->gappov = ov;
 | ||||||
|  | +	selmon->gappih = ih;
 | ||||||
|  | +	selmon->gappiv = iv;
 | ||||||
|  | +	arrange(selmon);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +togglegaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	#if PERTAG_PATCH
 | ||||||
|  | +	selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
 | ||||||
|  | +	#else
 | ||||||
|  | +	enablegaps = !enablegaps;
 | ||||||
|  | +	#endif // PERTAG_PATCH
 | ||||||
|  | +	arrange(NULL);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +defaultgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(gappoh, gappov, gappih, gappiv);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh + arg->i,
 | ||||||
|  | +		selmon->gappov + arg->i,
 | ||||||
|  | +		selmon->gappih + arg->i,
 | ||||||
|  | +		selmon->gappiv + arg->i
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrigaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh,
 | ||||||
|  | +		selmon->gappov,
 | ||||||
|  | +		selmon->gappih + arg->i,
 | ||||||
|  | +		selmon->gappiv + arg->i
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrogaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh + arg->i,
 | ||||||
|  | +		selmon->gappov + arg->i,
 | ||||||
|  | +		selmon->gappih,
 | ||||||
|  | +		selmon->gappiv
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrohgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh + arg->i,
 | ||||||
|  | +		selmon->gappov,
 | ||||||
|  | +		selmon->gappih,
 | ||||||
|  | +		selmon->gappiv
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrovgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh,
 | ||||||
|  | +		selmon->gappov + arg->i,
 | ||||||
|  | +		selmon->gappih,
 | ||||||
|  | +		selmon->gappiv
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrihgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh,
 | ||||||
|  | +		selmon->gappov,
 | ||||||
|  | +		selmon->gappih + arg->i,
 | ||||||
|  | +		selmon->gappiv
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +incrivgaps(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	setgaps(
 | ||||||
|  | +		selmon->gappoh,
 | ||||||
|  | +		selmon->gappov,
 | ||||||
|  | +		selmon->gappih,
 | ||||||
|  | +		selmon->gappiv + arg->i
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int n, oe, ie;
 | ||||||
|  | +	#if PERTAG_PATCH
 | ||||||
|  | +	oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
 | ||||||
|  | +	#else
 | ||||||
|  | +	oe = ie = enablegaps;
 | ||||||
|  | +	#endif // PERTAG_PATCH
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
 | ||||||
|  | +	if (smartgaps && n == 1) {
 | ||||||
|  | +		oe = 0; // outer gaps disabled when only one client
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	*oh = m->gappoh*oe; // outer horizontal gap
 | ||||||
|  | +	*ov = m->gappov*oe; // outer vertical gap
 | ||||||
|  | +	*ih = m->gappih*ie; // inner horizontal gap
 | ||||||
|  | +	*iv = m->gappiv*ie; // inner vertical gap
 | ||||||
|  | +	*nc = n;            // number of clients
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int n;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mtotal = 0, stotal = 0;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
 | ||||||
|  | +	mfacts = MIN(n, m->nmaster);
 | ||||||
|  | +	sfacts = n - m->nmaster;
 | ||||||
|  | +
 | ||||||
|  | +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
 | ||||||
|  | +		if (n < m->nmaster)
 | ||||||
|  | +			mtotal += msize / mfacts;
 | ||||||
|  | +		else
 | ||||||
|  | +			stotal += ssize / sfacts;
 | ||||||
|  | +
 | ||||||
|  | +	*mf = mfacts; // total factor of master area
 | ||||||
|  | +	*sf = sfacts; // total factor of stack area
 | ||||||
|  | +	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
 | ||||||
|  | +	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/***
 | ||||||
|  | + * Layouts
 | ||||||
|  | + */
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Bottomstack layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/bottomstack/
 | ||||||
|  | + */
 | ||||||
|  | +static void
 | ||||||
|  | +bstack(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mrest, srest;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	sh = mh = m->wh - 2*oh;
 | ||||||
|  | +	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
 | ||||||
|  | +	sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		sh = (mh - ih) * (1 - m->mfact);
 | ||||||
|  | +		mh = mh - ih - sh;
 | ||||||
|  | +		sx = mx;
 | ||||||
|  | +		sy = my + mh + ih;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
 | ||||||
|  | +		if (i < m->nmaster) {
 | ||||||
|  | +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
 | ||||||
|  | +			mx += WIDTH(c) + iv;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
 | ||||||
|  | +			sx += WIDTH(c) + iv;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void
 | ||||||
|  | +bstackhoriz(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mrest, srest;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	mh = m->wh - 2*oh;
 | ||||||
|  | +	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
 | ||||||
|  | +	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
 | ||||||
|  | +	sw = m->ww - 2*ov;
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		sh = (mh - ih) * (1 - m->mfact);
 | ||||||
|  | +		mh = mh - ih - sh;
 | ||||||
|  | +		sy = my + mh + ih;
 | ||||||
|  | +		sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
 | ||||||
|  | +		if (i < m->nmaster) {
 | ||||||
|  | +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
 | ||||||
|  | +			mx += WIDTH(c) + iv;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +			sy += HEIGHT(c) + ih;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Centred master layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/centeredmaster/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +centeredmaster(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int lx = 0, ly = 0, lw = 0, lh = 0;
 | ||||||
|  | +	int rx = 0, ry = 0, rw = 0, rh = 0;
 | ||||||
|  | +	float mfacts = 0, lfacts = 0, rfacts = 0;
 | ||||||
|  | +	int mtotal = 0, ltotal = 0, rtotal = 0;
 | ||||||
|  | +	int mrest = 0, lrest = 0, rrest = 0;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	/* initialize areas */
 | ||||||
|  | +	mx = m->wx + ov;
 | ||||||
|  | +	my = m->wy + oh;
 | ||||||
|  | +	mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
 | ||||||
|  | +	mw = m->ww - 2*ov;
 | ||||||
|  | +	lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
 | ||||||
|  | +	rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		/* go mfact box in the center if more than nmaster clients */
 | ||||||
|  | +		if (n - m->nmaster > 1) {
 | ||||||
|  | +			/* ||<-S->|<---M--->|<-S->|| */
 | ||||||
|  | +			mw = (m->ww - 2*ov - 2*iv) * m->mfact;
 | ||||||
|  | +			lw = (m->ww - mw - 2*ov - 2*iv) / 2;
 | ||||||
|  | +			rw = (m->ww - mw - 2*ov - 2*iv) - lw;
 | ||||||
|  | +			mx += lw + iv;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			/* ||<---M--->|<-S->|| */
 | ||||||
|  | +			mw = (mw - iv) * m->mfact;
 | ||||||
|  | +			lw = 0;
 | ||||||
|  | +			rw = m->ww - mw - iv - 2*ov;
 | ||||||
|  | +		}
 | ||||||
|  | +		lx = m->wx + ov;
 | ||||||
|  | +		ly = m->wy + oh;
 | ||||||
|  | +		rx = mx + mw + iv;
 | ||||||
|  | +		ry = m->wy + oh;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* calculate facts */
 | ||||||
|  | +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
 | ||||||
|  | +		if (!m->nmaster || n < m->nmaster)
 | ||||||
|  | +			mfacts += 1;
 | ||||||
|  | +		else if ((n - m->nmaster) % 2)
 | ||||||
|  | +			lfacts += 1; // total factor of left hand stack area
 | ||||||
|  | +		else
 | ||||||
|  | +			rfacts += 1; // total factor of right hand stack area
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
 | ||||||
|  | +		if (!m->nmaster || n < m->nmaster)
 | ||||||
|  | +			mtotal += mh / mfacts;
 | ||||||
|  | +		else if ((n - m->nmaster) % 2)
 | ||||||
|  | +			ltotal += lh / lfacts;
 | ||||||
|  | +		else
 | ||||||
|  | +			rtotal += rh / rfacts;
 | ||||||
|  | +
 | ||||||
|  | +	mrest = mh - mtotal;
 | ||||||
|  | +	lrest = lh - ltotal;
 | ||||||
|  | +	rrest = rh - rtotal;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
 | ||||||
|  | +		if (!m->nmaster || i < m->nmaster) {
 | ||||||
|  | +			/* nmaster clients are stacked vertically, in the center of the screen */
 | ||||||
|  | +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +			my += HEIGHT(c) + ih;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			/* stack clients are stacked vertically */
 | ||||||
|  | +			if ((i - m->nmaster) % 2 ) {
 | ||||||
|  | +				resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +				ly += HEIGHT(c) + ih;
 | ||||||
|  | +			} else {
 | ||||||
|  | +				resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +				ry += HEIGHT(c) + ih;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +centeredfloatingmaster(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	float mivf = 1.0; // master inner vertical gap factor
 | ||||||
|  | +	int oh, ov, ih, iv, mrest, srest;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	sh = mh = m->wh - 2*oh;
 | ||||||
|  | +	mw = m->ww - 2*ov - iv*(n - 1);
 | ||||||
|  | +	sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		mivf = 0.8;
 | ||||||
|  | +		/* go mfact box in the center if more than nmaster clients */
 | ||||||
|  | +		if (m->ww > m->wh) {
 | ||||||
|  | +			mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
 | ||||||
|  | +			mh = m->wh * 0.9;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
 | ||||||
|  | +			mh = m->wh * m->mfact;
 | ||||||
|  | +		}
 | ||||||
|  | +		mx = m->wx + (m->ww - mw) / 2;
 | ||||||
|  | +		my = m->wy + (m->wh - mh - 2*oh) / 2;
 | ||||||
|  | +
 | ||||||
|  | +		sx = m->wx + ov;
 | ||||||
|  | +		sy = m->wy + oh;
 | ||||||
|  | +		sh = m->wh - 2*oh;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
 | ||||||
|  | +		if (i < m->nmaster) {
 | ||||||
|  | +			/* nmaster clients are stacked horizontally, in the center of the screen */
 | ||||||
|  | +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
 | ||||||
|  | +			mx += WIDTH(c) + iv*mivf;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			/* stack clients are stacked horizontally */
 | ||||||
|  | +			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
 | ||||||
|  | +			sx += WIDTH(c) + iv;
 | ||||||
|  | +		}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Deck layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/deck/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +deck(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mrest, srest;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
 | ||||||
|  | +	sw = mw = m->ww - 2*ov;
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		sw = (mw - iv) * (1 - m->mfact);
 | ||||||
|  | +		mw = mw - iv - sw;
 | ||||||
|  | +		sx = mx + mw + iv;
 | ||||||
|  | +		sh = m->wh - 2*oh;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
 | ||||||
|  | +
 | ||||||
|  | +	if (n - m->nmaster > 0) /* override layout symbol */
 | ||||||
|  | +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
 | ||||||
|  | +		if (i < m->nmaster) {
 | ||||||
|  | +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +			my += HEIGHT(c) + ih;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
 | ||||||
|  | +		}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Fibonacci layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/fibonacci/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +fibonacci(Monitor *m, int s)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int nx, ny, nw, nh;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int nv, hrest = 0, wrest = 0, r = 1;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	nx = m->wx + ov;
 | ||||||
|  | +	ny = m->wy + oh;
 | ||||||
|  | +	nw = m->ww - 2*ov;
 | ||||||
|  | +	nh = m->wh - 2*oh;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
 | ||||||
|  | +		if (r) {
 | ||||||
|  | +			if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
 | ||||||
|  | +			   || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
 | ||||||
|  | +				r = 0;
 | ||||||
|  | +			}
 | ||||||
|  | +			if (r && i < n - 1) {
 | ||||||
|  | +				if (i % 2) {
 | ||||||
|  | +					nv = (nh - ih) / 2;
 | ||||||
|  | +					hrest = nh - 2*nv - ih;
 | ||||||
|  | +					nh = nv;
 | ||||||
|  | +				} else {
 | ||||||
|  | +					nv = (nw - iv) / 2;
 | ||||||
|  | +					wrest = nw - 2*nv - iv;
 | ||||||
|  | +					nw = nv;
 | ||||||
|  | +				}
 | ||||||
|  | +
 | ||||||
|  | +				if ((i % 4) == 2 && !s)
 | ||||||
|  | +					nx += nw + iv;
 | ||||||
|  | +				else if ((i % 4) == 3 && !s)
 | ||||||
|  | +					ny += nh + ih;
 | ||||||
|  | +			}
 | ||||||
|  | +
 | ||||||
|  | +			if ((i % 4) == 0) {
 | ||||||
|  | +				if (s) {
 | ||||||
|  | +					ny += nh + ih;
 | ||||||
|  | +					nh += hrest;
 | ||||||
|  | +				}
 | ||||||
|  | +				else {
 | ||||||
|  | +					nh -= hrest;
 | ||||||
|  | +					ny -= nh + ih;
 | ||||||
|  | +				}
 | ||||||
|  | +			}
 | ||||||
|  | +			else if ((i % 4) == 1) {
 | ||||||
|  | +				nx += nw + iv;
 | ||||||
|  | +				nw += wrest;
 | ||||||
|  | +			}
 | ||||||
|  | +			else if ((i % 4) == 2) {
 | ||||||
|  | +				ny += nh + ih;
 | ||||||
|  | +				nh += hrest;
 | ||||||
|  | +				if (i < n - 1)
 | ||||||
|  | +					nw += wrest;
 | ||||||
|  | +			}
 | ||||||
|  | +			else if ((i % 4) == 3) {
 | ||||||
|  | +				if (s) {
 | ||||||
|  | +					nx += nw + iv;
 | ||||||
|  | +					nw -= wrest;
 | ||||||
|  | +				} else {
 | ||||||
|  | +					nw -= wrest;
 | ||||||
|  | +					nx -= nw + iv;
 | ||||||
|  | +					nh += hrest;
 | ||||||
|  | +				}
 | ||||||
|  | +			}
 | ||||||
|  | +			if (i == 0)	{
 | ||||||
|  | +				if (n != 1) {
 | ||||||
|  | +					nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
 | ||||||
|  | +					wrest = 0;
 | ||||||
|  | +				}
 | ||||||
|  | +				ny = m->wy + oh;
 | ||||||
|  | +			}
 | ||||||
|  | +			else if (i == 1)
 | ||||||
|  | +				nw = m->ww - nw - iv - 2*ov;
 | ||||||
|  | +			i++;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +dwindle(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	fibonacci(m, 1);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +spiral(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	fibonacci(m, 0);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Gappless grid layout + gaps (ironically)
 | ||||||
|  | + * https://dwm.suckless.org/patches/gaplessgrid/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +gaplessgrid(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	/* grid dimensions */
 | ||||||
|  | +	for (cols = 0; cols <= n/2; cols++)
 | ||||||
|  | +		if (cols*cols >= n)
 | ||||||
|  | +			break;
 | ||||||
|  | +	if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
 | ||||||
|  | +		cols = 2;
 | ||||||
|  | +	rows = n/cols;
 | ||||||
|  | +	cn = rn = 0; // reset column no, row no, client count
 | ||||||
|  | +
 | ||||||
|  | +	ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
 | ||||||
|  | +	cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
 | ||||||
|  | +	rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
 | ||||||
|  | +	crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
 | ||||||
|  | +	x = m->wx + ov;
 | ||||||
|  | +	y = m->wy + oh;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
 | ||||||
|  | +		if (i/rows + 1 > cols - n%cols) {
 | ||||||
|  | +			rows = n/cols + 1;
 | ||||||
|  | +			ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
 | ||||||
|  | +			rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
 | ||||||
|  | +		}
 | ||||||
|  | +		resize(c,
 | ||||||
|  | +			x,
 | ||||||
|  | +			y + rn*(ch + ih) + MIN(rn, rrest),
 | ||||||
|  | +			cw + (cn < crest ? 1 : 0) - 2*c->bw,
 | ||||||
|  | +			ch + (rn < rrest ? 1 : 0) - 2*c->bw,
 | ||||||
|  | +			0);
 | ||||||
|  | +		rn++;
 | ||||||
|  | +		if (rn >= rows) {
 | ||||||
|  | +			rn = 0;
 | ||||||
|  | +			x += cw + ih + (cn < crest ? 1 : 0);
 | ||||||
|  | +			cn++;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Gridmode layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/gridmode/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +grid(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +
 | ||||||
|  | +	/* grid dimensions */
 | ||||||
|  | +	for (rows = 0; rows <= n/2; rows++)
 | ||||||
|  | +		if (rows*rows >= n)
 | ||||||
|  | +			break;
 | ||||||
|  | +	cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
 | ||||||
|  | +
 | ||||||
|  | +	/* window geoms (cell height/width) */
 | ||||||
|  | +	ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
 | ||||||
|  | +	cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
 | ||||||
|  | +	chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
 | ||||||
|  | +	cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
 | ||||||
|  | +		cc = i / rows;
 | ||||||
|  | +		cr = i % rows;
 | ||||||
|  | +		cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
 | ||||||
|  | +		cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
 | ||||||
|  | +		resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Horizontal grid layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/horizgrid/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +horizgrid(Monitor *m) {
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +	unsigned int n, i;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	int ntop, nbottom = 1;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mrest, srest;
 | ||||||
|  | +
 | ||||||
|  | +	/* Count windows */
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	if (n <= 2)
 | ||||||
|  | +		ntop = n;
 | ||||||
|  | +	else {
 | ||||||
|  | +		ntop = n / 2;
 | ||||||
|  | +		nbottom = n - ntop;
 | ||||||
|  | +	}
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	sh = mh = m->wh - 2*oh;
 | ||||||
|  | +	sw = mw = m->ww - 2*ov;
 | ||||||
|  | +
 | ||||||
|  | +	if (n > ntop) {
 | ||||||
|  | +		sh = (mh - ih) / 2;
 | ||||||
|  | +		mh = mh - ih - sh;
 | ||||||
|  | +		sy = my + mh + ih;
 | ||||||
|  | +		mw = m->ww - 2*ov - iv * (ntop - 1);
 | ||||||
|  | +		sw = m->ww - 2*ov - iv * (nbottom - 1);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	mfacts = ntop;
 | ||||||
|  | +	sfacts = nbottom;
 | ||||||
|  | +	mrest = mw - (mw / ntop) * ntop;
 | ||||||
|  | +	srest = sw - (sw / nbottom) * nbottom;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
 | ||||||
|  | +		if (i < ntop) {
 | ||||||
|  | +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
 | ||||||
|  | +			mx += WIDTH(c) + iv;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
 | ||||||
|  | +			sx += WIDTH(c) + iv;
 | ||||||
|  | +		}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * nrowgrid layout + gaps
 | ||||||
|  | + * https://dwm.suckless.org/patches/nrowgrid/
 | ||||||
|  | + */
 | ||||||
|  | +void
 | ||||||
|  | +nrowgrid(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int n;
 | ||||||
|  | +	int ri = 0, ci = 0;  /* counters */
 | ||||||
|  | +	int oh, ov, ih, iv;                         /* vanitygap settings */
 | ||||||
|  | +	unsigned int cx, cy, cw, ch;                /* client geometry */
 | ||||||
|  | +	unsigned int uw = 0, uh = 0, uc = 0;        /* utilization trackers */
 | ||||||
|  | +	unsigned int cols, rows = m->nmaster + 1;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	/* count clients */
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +
 | ||||||
|  | +	/* nothing to do here */
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	/* force 2 clients to always split vertically */
 | ||||||
|  | +	if (FORCE_VSPLIT && n == 2)
 | ||||||
|  | +		rows = 1;
 | ||||||
|  | +
 | ||||||
|  | +	/* never allow empty rows */
 | ||||||
|  | +	if (n < rows)
 | ||||||
|  | +		rows = n;
 | ||||||
|  | +
 | ||||||
|  | +	/* define first row */
 | ||||||
|  | +	cols = n / rows;
 | ||||||
|  | +	uc = cols;
 | ||||||
|  | +	cy = m->wy + oh;
 | ||||||
|  | +	ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
 | ||||||
|  | +	uh = ch;
 | ||||||
|  | +
 | ||||||
|  | +	for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
 | ||||||
|  | +		if (ci == cols) {
 | ||||||
|  | +			uw = 0;
 | ||||||
|  | +			ci = 0;
 | ||||||
|  | +			ri++;
 | ||||||
|  | +
 | ||||||
|  | +			/* next row */
 | ||||||
|  | +			cols = (n - uc) / (rows - ri);
 | ||||||
|  | +			uc += cols;
 | ||||||
|  | +			cy = m->wy + oh + uh + ih;
 | ||||||
|  | +			uh += ch + ih;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		cx = m->wx + ov + uw;
 | ||||||
|  | +		cw = (m->ww - 2*ov - uw) / (cols - ci);
 | ||||||
|  | +		uw += cw + iv;
 | ||||||
|  | +
 | ||||||
|  | +		resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * Default tile layout + gaps
 | ||||||
|  | + */
 | ||||||
|  | +static void
 | ||||||
|  | +tile(Monitor *m)
 | ||||||
|  | +{
 | ||||||
|  | +	unsigned int i, n;
 | ||||||
|  | +	int oh, ov, ih, iv;
 | ||||||
|  | +	int mx = 0, my = 0, mh = 0, mw = 0;
 | ||||||
|  | +	int sx = 0, sy = 0, sh = 0, sw = 0;
 | ||||||
|  | +	float mfacts, sfacts;
 | ||||||
|  | +	int mrest, srest;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +
 | ||||||
|  | +	getgaps(m, &oh, &ov, &ih, &iv, &n);
 | ||||||
|  | +	if (n == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	sx = mx = m->wx + ov;
 | ||||||
|  | +	sy = my = m->wy + oh;
 | ||||||
|  | +	mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
 | ||||||
|  | +	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
 | ||||||
|  | +	sw = mw = m->ww - 2*ov;
 | ||||||
|  | +
 | ||||||
|  | +	if (m->nmaster && n > m->nmaster) {
 | ||||||
|  | +		sw = (mw - iv) * (1 - m->mfact);
 | ||||||
|  | +		mw = mw - iv - sw;
 | ||||||
|  | +		sx = mx + mw + iv;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
 | ||||||
|  | +		if (i < m->nmaster) {
 | ||||||
|  | +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +			my += HEIGHT(c) + ih;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
 | ||||||
|  | +			sy += HEIGHT(c) + ih;
 | ||||||
|  | +		}
 | ||||||
|  | +}
 | ||||||
|  | \ No newline at end of file | ||||||
|  | -- 
 | ||||||
|  | 2.19.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										176
									
								
								dwm.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								dwm.1
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,176 @@ | ||||||
|  | .TH DWM 1 dwm\-VERSION | ||||||
|  | .SH NAME | ||||||
|  | dwm \- dynamic window manager | ||||||
|  | .SH SYNOPSIS | ||||||
|  | .B dwm | ||||||
|  | .RB [ \-v ] | ||||||
|  | .SH DESCRIPTION | ||||||
|  | dwm is a dynamic window manager for X. It manages windows in tiled, monocle | ||||||
|  | and floating layouts. Either layout can be applied dynamically, optimising the | ||||||
|  | environment for the application in use and the task performed. | ||||||
|  | .P | ||||||
|  | In tiled layouts windows are managed in a master and stacking area. The master | ||||||
|  | area on the left contains one window by default, and the stacking area on the | ||||||
|  | right contains all other windows. The number of master area windows can be | ||||||
|  | adjusted from zero to an arbitrary number. In monocle layout all windows are | ||||||
|  | maximised to the screen size. In floating layout windows can be resized and | ||||||
|  | moved freely. Dialog windows are always managed floating, regardless of the | ||||||
|  | layout applied. | ||||||
|  | .P | ||||||
|  | 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. | ||||||
|  | .P | ||||||
|  | dwm draws a small border around windows to indicate the focus state. | ||||||
|  | .SH OPTIONS | ||||||
|  | .TP | ||||||
|  | .B \-v | ||||||
|  | prints version information to standard output, then exits. | ||||||
|  | .SH USAGE | ||||||
|  | .SS Status bar | ||||||
|  | .TP | ||||||
|  | .B X root window name | ||||||
|  | is read and displayed in the status text area. It can be set with the | ||||||
|  | .BR xsetroot (1) | ||||||
|  | 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. | ||||||
|  | .TP | ||||||
|  | .B Button3 | ||||||
|  | click on a tag label adds/removes all windows with that tag to/from the view. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Button1 | ||||||
|  | click on a tag label applies that tag to the focused window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Button3 | ||||||
|  | click on a tag label adds/removes that tag to/from the focused window. | ||||||
|  | .SS Keyboard commands | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-Return | ||||||
|  | Start | ||||||
|  | .BR st(1). | ||||||
|  | .TP | ||||||
|  | .B Mod1\-p | ||||||
|  | Spawn | ||||||
|  | .BR dmenu(1) | ||||||
|  | for launching other programs. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-, | ||||||
|  | Focus previous screen, if any. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-. | ||||||
|  | Focus next screen, if any. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-, | ||||||
|  | Send focused window to previous screen, if any. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-. | ||||||
|  | Send focused window to next screen, if any. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-b | ||||||
|  | Toggles bar on and off. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-t | ||||||
|  | Sets tiled layout. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-f | ||||||
|  | Sets floating layout. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-m | ||||||
|  | Sets monocle layout. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-space | ||||||
|  | Toggles between current and previous layout. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-j | ||||||
|  | Focus next window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-k | ||||||
|  | Focus previous window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-i | ||||||
|  | Increase number of windows in master area. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-d | ||||||
|  | Decrease number of windows in master area. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-l | ||||||
|  | Increase master area size. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-h | ||||||
|  | Decrease master area size. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Return | ||||||
|  | Zooms/cycles focused window to/from master area (tiled layouts only). | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-c | ||||||
|  | Close focused window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-space | ||||||
|  | Toggle focused window between tiled and floating state. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Tab | ||||||
|  | Toggles to the previously selected tags. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-[1..n] | ||||||
|  | Apply nth tag to focused window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-0 | ||||||
|  | Apply all tags to focused window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Control\-Shift\-[1..n] | ||||||
|  | Add/remove nth tag to/from focused window. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-[1..n] | ||||||
|  | View all windows with nth tag. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-0 | ||||||
|  | View all windows with any tag. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Control\-[1..n] | ||||||
|  | Add/remove all windows with nth tag to/from the view. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Shift\-q | ||||||
|  | Quit dwm. | ||||||
|  | .SS Mouse commands | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Button1 | ||||||
|  | Move focused window while dragging. Tiled windows will be toggled to the floating state. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Button2 | ||||||
|  | Toggles focused window between floating and tiled state. | ||||||
|  | .TP | ||||||
|  | .B Mod1\-Button3 | ||||||
|  | Resize focused window while dragging. Tiled windows will be toggled to the floating state. | ||||||
|  | .SH CUSTOMIZATION | ||||||
|  | dwm is customized by creating a custom config.h and (re)compiling the source | ||||||
|  | code. This keeps it fast, secure and simple. | ||||||
|  | .SH SEE ALSO | ||||||
|  | .BR dmenu (1), | ||||||
|  | .BR st (1) | ||||||
|  | .SH ISSUES | ||||||
|  | Java applications which use the XToolkit/XAWT backend may draw grey windows | ||||||
|  | only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early | ||||||
|  | JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds | ||||||
|  | are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the | ||||||
|  | environment variable | ||||||
|  | .BR AWT_TOOLKIT=MToolkit | ||||||
|  | (to use the older Motif backend instead) or running | ||||||
|  | .B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D | ||||||
|  | or | ||||||
|  | .B wmname LG3D | ||||||
|  | (to pretend that a non-reparenting window manager is running that the | ||||||
|  | XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable | ||||||
|  | .BR _JAVA_AWT_WM_NONREPARENTING=1 . | ||||||
|  | .SH BUGS | ||||||
|  | Send all bug reports with a patch to hackers@suckless.org. | ||||||
							
								
								
									
										
											BIN
										
									
								
								dwm.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dwm.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								dwm.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dwm.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 373 B | 
							
								
								
									
										9
									
								
								make
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								make
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | Script started on 2020-08-02 23:17:32-05:00 [TERM="st-256color" TTY="/dev/pts/2" COLUMNS="114" LINES="57"] | ||||||
|  | usage: sudo -h | -K | -k | -V | ||||||
|  | usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user] | ||||||
|  | usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command] | ||||||
|  | usage: sudo [-AbEHknPS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] | ||||||
|  |             [<command>] | ||||||
|  | usage: sudo -e [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ... | ||||||
|  | 
 | ||||||
|  | Script done on 2020-08-02 23:17:32-05:00 [COMMAND_EXIT_CODE="1"] | ||||||
							
								
								
									
										42
									
								
								transient.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								transient.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | /* cc transient.c -o transient -lX11 */ | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <X11/Xlib.h> | ||||||
|  | #include <X11/Xutil.h> | ||||||
|  | 
 | ||||||
|  | int main(void) { | ||||||
|  | 	Display *d; | ||||||
|  | 	Window r, f, t = None; | ||||||
|  | 	XSizeHints h; | ||||||
|  | 	XEvent e; | ||||||
|  | 
 | ||||||
|  | 	d = XOpenDisplay(NULL); | ||||||
|  | 	if (!d) | ||||||
|  | 		exit(1); | ||||||
|  | 	r = DefaultRootWindow(d); | ||||||
|  | 
 | ||||||
|  | 	f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); | ||||||
|  | 	h.min_width = h.max_width = h.min_height = h.max_height = 400; | ||||||
|  | 	h.flags = PMinSize | PMaxSize; | ||||||
|  | 	XSetWMNormalHints(d, f, &h); | ||||||
|  | 	XStoreName(d, f, "floating"); | ||||||
|  | 	XMapWindow(d, f); | ||||||
|  | 
 | ||||||
|  | 	XSelectInput(d, f, ExposureMask); | ||||||
|  | 	while (1) { | ||||||
|  | 		XNextEvent(d, &e); | ||||||
|  | 
 | ||||||
|  | 		if (t == None) { | ||||||
|  | 			sleep(5); | ||||||
|  | 			t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); | ||||||
|  | 			XSetTransientForHint(d, t, f); | ||||||
|  | 			XStoreName(d, t, "transient"); | ||||||
|  | 			XMapWindow(d, t); | ||||||
|  | 			XSelectInput(d, t, ExposureMask); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	XCloseDisplay(d); | ||||||
|  | 	exit(0); | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								util.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								util.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | void * | ||||||
|  | ecalloc(size_t nmemb, size_t size) | ||||||
|  | { | ||||||
|  | 	void *p; | ||||||
|  | 
 | ||||||
|  | 	if (!(p = calloc(nmemb, size))) | ||||||
|  | 		die("calloc:"); | ||||||
|  | 	return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | die(const char *fmt, ...) { | ||||||
|  | 	va_list ap; | ||||||
|  | 
 | ||||||
|  | 	va_start(ap, fmt); | ||||||
|  | 	vfprintf(stderr, fmt, ap); | ||||||
|  | 	va_end(ap); | ||||||
|  | 
 | ||||||
|  | 	if (fmt[0] && fmt[strlen(fmt)-1] == ':') { | ||||||
|  | 		fputc(' ', stderr); | ||||||
|  | 		perror(NULL); | ||||||
|  | 	} else { | ||||||
|  | 		fputc('\n', stderr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								util.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								util.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | 
 | ||||||
|  | #define MAX(A, B)               ((A) > (B) ? (A) : (B)) | ||||||
|  | #define MIN(A, B)               ((A) < (B) ? (A) : (B)) | ||||||
|  | #define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B)) | ||||||
|  | 
 | ||||||
|  | void die(const char *fmt, ...); | ||||||
|  | void *ecalloc(size_t nmemb, size_t size); | ||||||
							
								
								
									
										
											BIN
										
									
								
								util.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								util.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										809
									
								
								vanitygaps.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										809
									
								
								vanitygaps.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,809 @@ | ||||||
|  | /* Key binding functions */ | ||||||
|  | static void defaultgaps(const Arg *arg); | ||||||
|  | static void incrgaps(const Arg *arg); | ||||||
|  | static void incrigaps(const Arg *arg); | ||||||
|  | static void incrogaps(const Arg *arg); | ||||||
|  | static void incrohgaps(const Arg *arg); | ||||||
|  | static void incrovgaps(const Arg *arg); | ||||||
|  | static void incrihgaps(const Arg *arg); | ||||||
|  | static void incrivgaps(const Arg *arg); | ||||||
|  | static void togglegaps(const Arg *arg); | ||||||
|  | /* Layouts (delete the ones you do not need) */ | ||||||
|  | static void bstack(Monitor *m); | ||||||
|  | static void bstackhoriz(Monitor *m); | ||||||
|  | static void centeredmaster(Monitor *m); | ||||||
|  | static void centeredfloatingmaster(Monitor *m); | ||||||
|  | static void deck(Monitor *m); | ||||||
|  | static void dwindle(Monitor *m); | ||||||
|  | static void fibonacci(Monitor *m, int s); | ||||||
|  | static void grid(Monitor *m); | ||||||
|  | static void nrowgrid(Monitor *m); | ||||||
|  | static void spiral(Monitor *m); | ||||||
|  | static void tile(Monitor *m); | ||||||
|  | /* Internals */ | ||||||
|  | static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); | ||||||
|  | static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); | ||||||
|  | static void setgaps(int oh, int ov, int ih, int iv); | ||||||
|  | 
 | ||||||
|  | /* Settings */ | ||||||
|  | #if !PERTAG_PATCH | ||||||
|  | static int enablegaps = 1; | ||||||
|  | #endif // PERTAG_PATCH
 | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | setgaps(int oh, int ov, int ih, int iv) | ||||||
|  | { | ||||||
|  | 	if (oh < 0) oh = 0; | ||||||
|  | 	if (ov < 0) ov = 0; | ||||||
|  | 	if (ih < 0) ih = 0; | ||||||
|  | 	if (iv < 0) iv = 0; | ||||||
|  | 
 | ||||||
|  | 	selmon->gappoh = oh; | ||||||
|  | 	selmon->gappov = ov; | ||||||
|  | 	selmon->gappih = ih; | ||||||
|  | 	selmon->gappiv = iv; | ||||||
|  | 	arrange(selmon); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | togglegaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	#if PERTAG_PATCH | ||||||
|  | 	selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; | ||||||
|  | 	#else | ||||||
|  | 	enablegaps = !enablegaps; | ||||||
|  | 	#endif // PERTAG_PATCH
 | ||||||
|  | 	arrange(NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | defaultgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps(gappoh, gappov, gappih, gappiv); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh + arg->i, | ||||||
|  | 		selmon->gappov + arg->i, | ||||||
|  | 		selmon->gappih + arg->i, | ||||||
|  | 		selmon->gappiv + arg->i | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrigaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh, | ||||||
|  | 		selmon->gappov, | ||||||
|  | 		selmon->gappih + arg->i, | ||||||
|  | 		selmon->gappiv + arg->i | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrogaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh + arg->i, | ||||||
|  | 		selmon->gappov + arg->i, | ||||||
|  | 		selmon->gappih, | ||||||
|  | 		selmon->gappiv | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrohgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh + arg->i, | ||||||
|  | 		selmon->gappov, | ||||||
|  | 		selmon->gappih, | ||||||
|  | 		selmon->gappiv | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrovgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh, | ||||||
|  | 		selmon->gappov + arg->i, | ||||||
|  | 		selmon->gappih, | ||||||
|  | 		selmon->gappiv | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrihgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh, | ||||||
|  | 		selmon->gappov, | ||||||
|  | 		selmon->gappih + arg->i, | ||||||
|  | 		selmon->gappiv | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | incrivgaps(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	setgaps( | ||||||
|  | 		selmon->gappoh, | ||||||
|  | 		selmon->gappov, | ||||||
|  | 		selmon->gappih, | ||||||
|  | 		selmon->gappiv + arg->i | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) | ||||||
|  | { | ||||||
|  | 	unsigned int n, oe, ie; | ||||||
|  | 	#if PERTAG_PATCH | ||||||
|  | 	oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; | ||||||
|  | 	#else | ||||||
|  | 	oe = ie = enablegaps; | ||||||
|  | 	#endif // PERTAG_PATCH
 | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); | ||||||
|  | 	if (smartgaps && n == 1) { | ||||||
|  | 		oe = 0; // outer gaps disabled when only one client
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*oh = m->gappoh*oe; // outer horizontal gap
 | ||||||
|  | 	*ov = m->gappov*oe; // outer vertical gap
 | ||||||
|  | 	*ih = m->gappih*ie; // inner horizontal gap
 | ||||||
|  | 	*iv = m->gappiv*ie; // inner vertical gap
 | ||||||
|  | 	*nc = n;            // number of clients
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) | ||||||
|  | { | ||||||
|  | 	unsigned int n; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mtotal = 0, stotal = 0; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); | ||||||
|  | 	mfacts = MIN(n, m->nmaster); | ||||||
|  | 	sfacts = n - m->nmaster; | ||||||
|  | 
 | ||||||
|  | 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) | ||||||
|  | 		if (n < m->nmaster) | ||||||
|  | 			mtotal += msize / mfacts; | ||||||
|  | 		else | ||||||
|  | 			stotal += ssize / sfacts; | ||||||
|  | 
 | ||||||
|  | 	*mf = mfacts; // total factor of master area
 | ||||||
|  | 	*sf = sfacts; // total factor of stack area
 | ||||||
|  | 	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
 | ||||||
|  | 	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /***
 | ||||||
|  |  * Layouts | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Bottomstack layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/bottomstack/
 | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | bstack(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mrest, srest; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	sh = mh = m->wh - 2*oh; | ||||||
|  | 	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); | ||||||
|  | 	sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		sh = (mh - ih) * (1 - m->mfact); | ||||||
|  | 		mh = mh - ih - sh; | ||||||
|  | 		sx = mx; | ||||||
|  | 		sy = my + mh + ih; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { | ||||||
|  | 		if (i < m->nmaster) { | ||||||
|  | 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); | ||||||
|  | 			mx += WIDTH(c) + iv; | ||||||
|  | 		} else { | ||||||
|  | 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); | ||||||
|  | 			sx += WIDTH(c) + iv; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | bstackhoriz(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mrest, srest; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	mh = m->wh - 2*oh; | ||||||
|  | 	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); | ||||||
|  | 	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); | ||||||
|  | 	sw = m->ww - 2*ov; | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		sh = (mh - ih) * (1 - m->mfact); | ||||||
|  | 		mh = mh - ih - sh; | ||||||
|  | 		sy = my + mh + ih; | ||||||
|  | 		sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { | ||||||
|  | 		if (i < m->nmaster) { | ||||||
|  | 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); | ||||||
|  | 			mx += WIDTH(c) + iv; | ||||||
|  | 		} else { | ||||||
|  | 			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 			sy += HEIGHT(c) + ih; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Centred master layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/centeredmaster/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | centeredmaster(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int lx = 0, ly = 0, lw = 0, lh = 0; | ||||||
|  | 	int rx = 0, ry = 0, rw = 0, rh = 0; | ||||||
|  | 	float mfacts = 0, lfacts = 0, rfacts = 0; | ||||||
|  | 	int mtotal = 0, ltotal = 0, rtotal = 0; | ||||||
|  | 	int mrest = 0, lrest = 0, rrest = 0; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	/* initialize areas */ | ||||||
|  | 	mx = m->wx + ov; | ||||||
|  | 	my = m->wy + oh; | ||||||
|  | 	mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); | ||||||
|  | 	mw = m->ww - 2*ov; | ||||||
|  | 	lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); | ||||||
|  | 	rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		/* go mfact box in the center if more than nmaster clients */ | ||||||
|  | 		if (n - m->nmaster > 1) { | ||||||
|  | 			/* ||<-S->|<---M--->|<-S->|| */ | ||||||
|  | 			mw = (m->ww - 2*ov - 2*iv) * m->mfact; | ||||||
|  | 			lw = (m->ww - mw - 2*ov - 2*iv) / 2; | ||||||
|  | 			rw = (m->ww - mw - 2*ov - 2*iv) - lw; | ||||||
|  | 			mx += lw + iv; | ||||||
|  | 		} else { | ||||||
|  | 			/* ||<---M--->|<-S->|| */ | ||||||
|  | 			mw = (mw - iv) * m->mfact; | ||||||
|  | 			lw = 0; | ||||||
|  | 			rw = m->ww - mw - iv - 2*ov; | ||||||
|  | 		} | ||||||
|  | 		lx = m->wx + ov; | ||||||
|  | 		ly = m->wy + oh; | ||||||
|  | 		rx = mx + mw + iv; | ||||||
|  | 		ry = m->wy + oh; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* calculate facts */ | ||||||
|  | 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { | ||||||
|  | 		if (!m->nmaster || n < m->nmaster) | ||||||
|  | 			mfacts += 1; | ||||||
|  | 		else if ((n - m->nmaster) % 2) | ||||||
|  | 			lfacts += 1; // total factor of left hand stack area
 | ||||||
|  | 		else | ||||||
|  | 			rfacts += 1; // total factor of right hand stack area
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) | ||||||
|  | 		if (!m->nmaster || n < m->nmaster) | ||||||
|  | 			mtotal += mh / mfacts; | ||||||
|  | 		else if ((n - m->nmaster) % 2) | ||||||
|  | 			ltotal += lh / lfacts; | ||||||
|  | 		else | ||||||
|  | 			rtotal += rh / rfacts; | ||||||
|  | 
 | ||||||
|  | 	mrest = mh - mtotal; | ||||||
|  | 	lrest = lh - ltotal; | ||||||
|  | 	rrest = rh - rtotal; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { | ||||||
|  | 		if (!m->nmaster || i < m->nmaster) { | ||||||
|  | 			/* nmaster clients are stacked vertically, in the center of the screen */ | ||||||
|  | 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 			my += HEIGHT(c) + ih; | ||||||
|  | 		} else { | ||||||
|  | 			/* stack clients are stacked vertically */ | ||||||
|  | 			if ((i - m->nmaster) % 2 ) { | ||||||
|  | 				resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 				ly += HEIGHT(c) + ih; | ||||||
|  | 			} else { | ||||||
|  | 				resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 				ry += HEIGHT(c) + ih; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | centeredfloatingmaster(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	float mivf = 1.0; // master inner vertical gap factor
 | ||||||
|  | 	int oh, ov, ih, iv, mrest, srest; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	sh = mh = m->wh - 2*oh; | ||||||
|  | 	mw = m->ww - 2*ov - iv*(n - 1); | ||||||
|  | 	sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		mivf = 0.8; | ||||||
|  | 		/* go mfact box in the center if more than nmaster clients */ | ||||||
|  | 		if (m->ww > m->wh) { | ||||||
|  | 			mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); | ||||||
|  | 			mh = m->wh * 0.9; | ||||||
|  | 		} else { | ||||||
|  | 			mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); | ||||||
|  | 			mh = m->wh * m->mfact; | ||||||
|  | 		} | ||||||
|  | 		mx = m->wx + (m->ww - mw) / 2; | ||||||
|  | 		my = m->wy + (m->wh - mh - 2*oh) / 2; | ||||||
|  | 
 | ||||||
|  | 		sx = m->wx + ov; | ||||||
|  | 		sy = m->wy + oh; | ||||||
|  | 		sh = m->wh - 2*oh; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | ||||||
|  | 		if (i < m->nmaster) { | ||||||
|  | 			/* nmaster clients are stacked horizontally, in the center of the screen */ | ||||||
|  | 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); | ||||||
|  | 			mx += WIDTH(c) + iv*mivf; | ||||||
|  | 		} else { | ||||||
|  | 			/* stack clients are stacked horizontally */ | ||||||
|  | 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); | ||||||
|  | 			sx += WIDTH(c) + iv; | ||||||
|  | 		} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Deck layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/deck/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | deck(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mrest, srest; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); | ||||||
|  | 	sw = mw = m->ww - 2*ov; | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		sw = (mw - iv) * (1 - m->mfact); | ||||||
|  | 		mw = mw - iv - sw; | ||||||
|  | 		sx = mx + mw + iv; | ||||||
|  | 		sh = m->wh - 2*oh; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); | ||||||
|  | 
 | ||||||
|  | 	if (n - m->nmaster > 0) /* override layout symbol */ | ||||||
|  | 		snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | ||||||
|  | 		if (i < m->nmaster) { | ||||||
|  | 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 			my += HEIGHT(c) + ih; | ||||||
|  | 		} else { | ||||||
|  | 			resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); | ||||||
|  | 		} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Fibonacci layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/fibonacci/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | fibonacci(Monitor *m, int s) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int nx, ny, nw, nh; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int nv, hrest = 0, wrest = 0, r = 1; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	nx = m->wx + ov; | ||||||
|  | 	ny = m->wy + oh; | ||||||
|  | 	nw = m->ww - 2*ov; | ||||||
|  | 	nh = m->wh - 2*oh; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { | ||||||
|  | 		if (r) { | ||||||
|  | 			if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) | ||||||
|  | 			   || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { | ||||||
|  | 				r = 0; | ||||||
|  | 			} | ||||||
|  | 			if (r && i < n - 1) { | ||||||
|  | 				if (i % 2) { | ||||||
|  | 					nv = (nh - ih) / 2; | ||||||
|  | 					hrest = nh - 2*nv - ih; | ||||||
|  | 					nh = nv; | ||||||
|  | 				} else { | ||||||
|  | 					nv = (nw - iv) / 2; | ||||||
|  | 					wrest = nw - 2*nv - iv; | ||||||
|  | 					nw = nv; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if ((i % 4) == 2 && !s) | ||||||
|  | 					nx += nw + iv; | ||||||
|  | 				else if ((i % 4) == 3 && !s) | ||||||
|  | 					ny += nh + ih; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if ((i % 4) == 0) { | ||||||
|  | 				if (s) { | ||||||
|  | 					ny += nh + ih; | ||||||
|  | 					nh += hrest; | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					nh -= hrest; | ||||||
|  | 					ny -= nh + ih; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			else if ((i % 4) == 1) { | ||||||
|  | 				nx += nw + iv; | ||||||
|  | 				nw += wrest; | ||||||
|  | 			} | ||||||
|  | 			else if ((i % 4) == 2) { | ||||||
|  | 				ny += nh + ih; | ||||||
|  | 				nh += hrest; | ||||||
|  | 				if (i < n - 1) | ||||||
|  | 					nw += wrest; | ||||||
|  | 			} | ||||||
|  | 			else if ((i % 4) == 3) { | ||||||
|  | 				if (s) { | ||||||
|  | 					nx += nw + iv; | ||||||
|  | 					nw -= wrest; | ||||||
|  | 				} else { | ||||||
|  | 					nw -= wrest; | ||||||
|  | 					nx -= nw + iv; | ||||||
|  | 					nh += hrest; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if (i == 0)	{ | ||||||
|  | 				if (n != 1) { | ||||||
|  | 					nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); | ||||||
|  | 					wrest = 0; | ||||||
|  | 				} | ||||||
|  | 				ny = m->wy + oh; | ||||||
|  | 			} | ||||||
|  | 			else if (i == 1) | ||||||
|  | 				nw = m->ww - nw - iv - 2*ov; | ||||||
|  | 			i++; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | dwindle(Monitor *m) | ||||||
|  | { | ||||||
|  | 	fibonacci(m, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | spiral(Monitor *m) | ||||||
|  | { | ||||||
|  | 	fibonacci(m, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Gappless grid layout + gaps (ironically) | ||||||
|  |  * https://dwm.suckless.org/patches/gaplessgrid/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | gaplessgrid(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
 | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	/* grid dimensions */ | ||||||
|  | 	for (cols = 0; cols <= n/2; cols++) | ||||||
|  | 		if (cols*cols >= n) | ||||||
|  | 			break; | ||||||
|  | 	if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ | ||||||
|  | 		cols = 2; | ||||||
|  | 	rows = n/cols; | ||||||
|  | 	cn = rn = 0; // reset column no, row no, client count
 | ||||||
|  | 
 | ||||||
|  | 	ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; | ||||||
|  | 	cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; | ||||||
|  | 	rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; | ||||||
|  | 	crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; | ||||||
|  | 	x = m->wx + ov; | ||||||
|  | 	y = m->wy + oh; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { | ||||||
|  | 		if (i/rows + 1 > cols - n%cols) { | ||||||
|  | 			rows = n/cols + 1; | ||||||
|  | 			ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; | ||||||
|  | 			rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; | ||||||
|  | 		} | ||||||
|  | 		resize(c, | ||||||
|  | 			x, | ||||||
|  | 			y + rn*(ch + ih) + MIN(rn, rrest), | ||||||
|  | 			cw + (cn < crest ? 1 : 0) - 2*c->bw, | ||||||
|  | 			ch + (rn < rrest ? 1 : 0) - 2*c->bw, | ||||||
|  | 			0); | ||||||
|  | 		rn++; | ||||||
|  | 		if (rn >= rows) { | ||||||
|  | 			rn = 0; | ||||||
|  | 			x += cw + ih + (cn < crest ? 1 : 0); | ||||||
|  | 			cn++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Gridmode layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/gridmode/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | grid(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 
 | ||||||
|  | 	/* grid dimensions */ | ||||||
|  | 	for (rows = 0; rows <= n/2; rows++) | ||||||
|  | 		if (rows*rows >= n) | ||||||
|  | 			break; | ||||||
|  | 	cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; | ||||||
|  | 
 | ||||||
|  | 	/* window geoms (cell height/width) */ | ||||||
|  | 	ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); | ||||||
|  | 	cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); | ||||||
|  | 	chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; | ||||||
|  | 	cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { | ||||||
|  | 		cc = i / rows; | ||||||
|  | 		cr = i % rows; | ||||||
|  | 		cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); | ||||||
|  | 		cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); | ||||||
|  | 		resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Horizontal grid layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/horizgrid/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | horizgrid(Monitor *m) { | ||||||
|  | 	Client *c; | ||||||
|  | 	unsigned int n, i; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	int ntop, nbottom = 1; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mrest, srest; | ||||||
|  | 
 | ||||||
|  | 	/* Count windows */ | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (n <= 2) | ||||||
|  | 		ntop = n; | ||||||
|  | 	else { | ||||||
|  | 		ntop = n / 2; | ||||||
|  | 		nbottom = n - ntop; | ||||||
|  | 	} | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	sh = mh = m->wh - 2*oh; | ||||||
|  | 	sw = mw = m->ww - 2*ov; | ||||||
|  | 
 | ||||||
|  | 	if (n > ntop) { | ||||||
|  | 		sh = (mh - ih) / 2; | ||||||
|  | 		mh = mh - ih - sh; | ||||||
|  | 		sy = my + mh + ih; | ||||||
|  | 		mw = m->ww - 2*ov - iv * (ntop - 1); | ||||||
|  | 		sw = m->ww - 2*ov - iv * (nbottom - 1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	mfacts = ntop; | ||||||
|  | 	sfacts = nbottom; | ||||||
|  | 	mrest = mw - (mw / ntop) * ntop; | ||||||
|  | 	srest = sw - (sw / nbottom) * nbottom; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | ||||||
|  | 		if (i < ntop) { | ||||||
|  | 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); | ||||||
|  | 			mx += WIDTH(c) + iv; | ||||||
|  | 		} else { | ||||||
|  | 			resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); | ||||||
|  | 			sx += WIDTH(c) + iv; | ||||||
|  | 		} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * nrowgrid layout + gaps | ||||||
|  |  * https://dwm.suckless.org/patches/nrowgrid/
 | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | nrowgrid(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int n; | ||||||
|  | 	int ri = 0, ci = 0;  /* counters */ | ||||||
|  | 	int oh, ov, ih, iv;                         /* vanitygap settings */ | ||||||
|  | 	unsigned int cx, cy, cw, ch;                /* client geometry */ | ||||||
|  | 	unsigned int uw = 0, uh = 0, uc = 0;        /* utilization trackers */ | ||||||
|  | 	unsigned int cols, rows = m->nmaster + 1; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	/* count clients */ | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 
 | ||||||
|  | 	/* nothing to do here */ | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	/* force 2 clients to always split vertically */ | ||||||
|  | 	if (FORCE_VSPLIT && n == 2) | ||||||
|  | 		rows = 1; | ||||||
|  | 
 | ||||||
|  | 	/* never allow empty rows */ | ||||||
|  | 	if (n < rows) | ||||||
|  | 		rows = n; | ||||||
|  | 
 | ||||||
|  | 	/* define first row */ | ||||||
|  | 	cols = n / rows; | ||||||
|  | 	uc = cols; | ||||||
|  | 	cy = m->wy + oh; | ||||||
|  | 	ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; | ||||||
|  | 	uh = ch; | ||||||
|  | 
 | ||||||
|  | 	for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) { | ||||||
|  | 		if (ci == cols) { | ||||||
|  | 			uw = 0; | ||||||
|  | 			ci = 0; | ||||||
|  | 			ri++; | ||||||
|  | 
 | ||||||
|  | 			/* next row */ | ||||||
|  | 			cols = (n - uc) / (rows - ri); | ||||||
|  | 			uc += cols; | ||||||
|  | 			cy = m->wy + oh + uh + ih; | ||||||
|  | 			uh += ch + ih; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		cx = m->wx + ov + uw; | ||||||
|  | 		cw = (m->ww - 2*ov - uw) / (cols - ci); | ||||||
|  | 		uw += cw + iv; | ||||||
|  | 
 | ||||||
|  | 		resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Default tile layout + gaps | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | tile(Monitor *m) | ||||||
|  | { | ||||||
|  | 	unsigned int i, n; | ||||||
|  | 	int oh, ov, ih, iv; | ||||||
|  | 	int mx = 0, my = 0, mh = 0, mw = 0; | ||||||
|  | 	int sx = 0, sy = 0, sh = 0, sw = 0; | ||||||
|  | 	float mfacts, sfacts; | ||||||
|  | 	int mrest, srest; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	getgaps(m, &oh, &ov, &ih, &iv, &n); | ||||||
|  | 	if (n == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	sx = mx = m->wx + ov; | ||||||
|  | 	sy = my = m->wy + oh; | ||||||
|  | 	mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); | ||||||
|  | 	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); | ||||||
|  | 	sw = mw = m->ww - 2*ov; | ||||||
|  | 
 | ||||||
|  | 	if (m->nmaster && n > m->nmaster) { | ||||||
|  | 		sw = (mw - iv) * (1 - m->mfact); | ||||||
|  | 		mw = mw - iv - sw; | ||||||
|  | 		sx = mx + mw + iv; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | ||||||
|  | 		if (i < m->nmaster) { | ||||||
|  | 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 			my += HEIGHT(c) + ih; | ||||||
|  | 		} else { | ||||||
|  | 			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); | ||||||
|  | 			sy += HEIGHT(c) + ih; | ||||||
|  | 		} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue