├── LICENSE ├── Makefile ├── README.md ├── config.def.h ├── config.def.h.orig ├── config.def.h.rej ├── config.h ├── config.mk ├── drw.c ├── drw.h ├── drw.o ├── dwm ├── dwm.1 ├── dwm.c ├── dwm.c.orig ├── dwm.c.rej ├── dwm.o ├── dwm.png ├── movestack.c ├── patches ├── dwm-actualfullscreen-20211013-cb3f58a.diff ├── dwm-alwayscenter-20200625-f04cac6.diff ├── dwm-cfacts-vanitygaps-6.4_combo.diff ├── dwm-movestack-20211115-a786211.diff ├── dwm-pertag_with_sel-20231003-9f88553.diff ├── dwm-resizehere-20230824-e81f17d.diff ├── dwm-setborderpx-6.2.diff ├── dwm-status2d-6.3.diff ├── dwm-statusallmons-6.2.diff ├── dwm-tiledmove-20231210-b731.diff └── dwm-unfloatvisible-6.2.diff ├── screenshots ├── 1.png ├── 2.png └── 3.png ├── themes └── mhtheme.h ├── transient.c ├── unfloat.c ├── util.c ├── util.h ├── util.o └── vanitygaps.c /LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2006-2019 Anselm R Garbe 4 | © 2006-2009 Jukka Salmi 5 | © 2006-2007 Sander van Dijk 6 | © 2007-2011 Peter Hartlich 7 | © 2007-2009 Szabolcs Nagy 8 | © 2007-2009 Christof Musik 9 | © 2007-2009 Premysl Hruby 10 | © 2007-2008 Enno Gottox Boland 11 | © 2008 Martin Hurton 12 | © 2008 Neale Pickett 13 | © 2009 Mate Nagy 14 | © 2010-2016 Hiltjo Posthuma 15 | © 2010-2012 Connor Lane Smith 16 | © 2011 Christoph Lohmann <20h@r-36.net> 17 | © 2015-2016 Quentin Rameau 18 | © 2015-2016 Eric Pruitt 19 | © 2016-2017 Markus Teich 20 | © 2020-2022 Chris Down 21 | 22 | Permission is hereby granted, free of charge, to any person obtaining a 23 | copy of this software and associated documentation files (the "Software"), 24 | to deal in the Software without restriction, including without limitation 25 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 26 | and/or sell copies of the Software, and to permit persons to whom the 27 | Software is furnished to do so, subject to the following conditions: 28 | 29 | The above copyright notice and this permission notice shall be included in 30 | all copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 35 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 37 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 38 | DEALINGS IN THE SOFTWARE. 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # dwm - dynamic window manager 2 | # See LICENSE file for copyright and license details. 3 | 4 | include config.mk 5 | 6 | SRC = drw.c dwm.c util.c 7 | OBJ = ${SRC:.c=.o} 8 | 9 | all: dwm 10 | 11 | .c.o: 12 | ${CC} -c ${CFLAGS} $< 13 | 14 | ${OBJ}: config.h config.mk 15 | 16 | config.h: 17 | cp config.def.h $@ 18 | 19 | dwm: ${OBJ} 20 | ${CC} -o $@ ${OBJ} ${LDFLAGS} 21 | 22 | clean: 23 | rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz 24 | 25 | dist: clean 26 | mkdir -p dwm-${VERSION} 27 | cp -R LICENSE Makefile README config.def.h config.mk\ 28 | dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} 29 | tar -cf dwm-${VERSION}.tar dwm-${VERSION} 30 | gzip dwm-${VERSION}.tar 31 | rm -rf dwm-${VERSION} 32 | 33 | install: all 34 | mkdir -p ${DESTDIR}${PREFIX}/bin 35 | cp -f dwm ${DESTDIR}${PREFIX}/bin 36 | chmod 755 ${DESTDIR}${PREFIX}/bin/dwm 37 | mkdir -p ${DESTDIR}${MANPREFIX}/man1 38 | sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 39 | chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 40 | 41 | uninstall: 42 | rm -f ${DESTDIR}${PREFIX}/bin/dwm\ 43 | ${DESTDIR}${MANPREFIX}/man1/dwm.1 44 | 45 | .PHONY: all clean dist install uninstall 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dwm-rev1 2 | 3 | This is a revision of my build of dwm. It is built off of `dwm-6.5`. I made this because my previous build of dwm was a little bit buggy and I decided it would be better to leave it as is, and make a completely new build of dwm in a seperate repo, which is what this is. 4 | 5 | ## patches 6 | 7 | - `movestack` https://dwm.suckless.org/patches/movestack 8 | - makes it so that MOD+J & MOD+K moves windows up & down the stack (better than stacker) 9 | - `resizehere` https://dwm.suckless.org/patches/resizehere 10 | - prevents mouse from warping to bottom right corner when resizing window 11 | - `vanitygaps` https://dwm.suckless.org/patches/vanitygaps 12 | - provides adjustable gaps with keybinds and more layouts 13 | - `statusallmons` https://dwm.suckless.org/patches/statusallmons 14 | - makes it so that status bar gets updated on all monitors instead of just the focused one 15 | - `pertag` https://dwm.suckless.org/patches/pertag 16 | - preserves mfact and other stuff per tag 17 | - `tiledmove` https://dwm.suckless.org/patches/tiledmove 18 | - makes it so MOD+lmb allows windows to stay tiled while moving them 19 | - `unfloatvisible` https://dwm.suckless.org/patches/unfloatvisible 20 | - make floating window tiled again with MOD+Z 21 | - `status2d` https://dwm.suckless.org/patches/status2d 22 | - add color support and more to dwm status bar 23 | - `setborderpx` https://dwm.suckless.org/patches/setborderpx 24 | - make it so that MOD+{ & MOD+} decrease and increase the border width 25 | - `alwayscenter` https://dwm.suckless.org/patches/alwayscenter 26 | - makes it so that floating windows always start centered instead of in the top-left corner, also changed it to take into account the height of the bar 27 | - `actualfullscreen` https://dwm.suckless.org/patches/actualfullscreen 28 | - make its so that MOD+f makes window fullscreen 29 | 30 | ## quick-start 31 | 32 | to get started run these commands: 33 | 34 | ``` 35 | git clone https://github.com/maxhu08/dwm-rev1 36 | cd dwm-rev1 37 | sudo make clean install 38 | ``` 39 | 40 | then add this to your `~/.xinitrc` 41 | 42 | ``` 43 | exec dwm 44 | ``` 45 | 46 | ## showcase 47 | 48 | ![1](./screenshots/1.png) 49 | 50 | ![2](./screenshots/2.png) 51 | 52 | ![3](./screenshots/3.png) 53 | -------------------------------------------------------------------------------- /config.def.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | /* See LICENSE file for copyright and license details. */ 3 | 4 | /* appearance */ 5 | static const unsigned int borderpx = 2; // border pixel of windows 6 | static const unsigned int snap = 32; // snap pixel 7 | static const unsigned int gappih = 0; // horiz inner gap between windows 8 | static const unsigned int gappiv = 0; // vert inner gap between windows 9 | static const unsigned int gappoh = 0; // horiz outer gap between windows and screen edge 10 | static const unsigned int gappov = 0; // vert outer gap between windows and screen edge 11 | static int smartgaps = 0; // 1 means no outer gap when there is only one window 12 | static const int showbar = 1; // 0 means no bar 13 | static const int topbar = 1; // 0 means bottom bar 14 | static const char *fonts[] = { "Jetbrains Mono NerdFont:size=12:style=Bold", "monospace:size=12" }; 15 | static const char dmenufont[] = "Jetbrains Mono NerdFont:size=12:style=Bold"; 16 | #include "themes/mhtheme.h" 17 | static const char *colors[][3] = { 18 | /* fg bg border */ 19 | [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 20 | [SchemeSel] = { col_gray4, col_accnt, col_accnt }, 21 | }; 22 | 23 | /* tagging */ 24 | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 25 | 26 | static const Rule rules[] = { 27 | /* xprop(1): 28 | * WM_CLASS(STRING) = instance, class 29 | * WM_NAME(STRING) = title 30 | */ 31 | /* class instance title tags mask isfloating monitor */ 32 | { "Gimp", NULL, NULL, 0, 1, -1 }, 33 | { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, 34 | }; 35 | 36 | /* layout(s) */ 37 | static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */ 38 | static const int nmaster = 1; /* number of clients in master area */ 39 | static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ 40 | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 41 | 42 | #define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ 43 | #include "vanitygaps.c" 44 | #include "unfloat.c" 45 | 46 | static const Layout layouts[] = { 47 | /* symbol arrange function */ 48 | { "[]=", tile }, /* first entry is default */ 49 | { "[M]", monocle }, 50 | { "[@]", spiral }, 51 | { "[\\]", dwindle }, 52 | { "H[]", deck }, 53 | { "TTT", bstack }, 54 | { "===", bstackhoriz }, 55 | { "HHH", grid }, 56 | { "###", nrowgrid }, 57 | { "---", horizgrid }, 58 | { ":::", gaplessgrid }, 59 | { "|M|", centeredmaster }, 60 | { ">M>", centeredfloatingmaster }, 61 | { "><>", NULL }, /* no layout function means floating behavior */ 62 | { NULL, NULL }, 63 | }; 64 | 65 | /* key definitions */ 66 | #define MODKEY Mod4Mask 67 | #define ALTKEY Mod1Mask 68 | #define TAGKEYS(KEY,TAG) \ 69 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 70 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 71 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 72 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 73 | 74 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 75 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 76 | 77 | /* commands */ 78 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 79 | static const char *dmenucmd[] = { "dmenu_run", "-c", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_accnt, "-sf", col_gray4, NULL }; 80 | static const char *termcmd[] = { "kitty", NULL }; 81 | 82 | #include "movestack.c" 83 | static const Key keys[] = { 84 | /* modifier key function argument */ 85 | { MODKEY, XK_r, spawn, {.v = dmenucmd } }, // open app launcher MOD+r 86 | { MODKEY, XK_Return, spawn, {.v = termcmd } }, // spawn terminal MOD+return 87 | { MODKEY, XK_s, spawn, SHCMD("exec ~/.hidden/scripts/screenshot_multimon.sh") }, // screenshot MOD+s (requires script in ~/Dev/scripts/screenshot.sh) 88 | { MODKEY|ShiftMask, XK_s, spawn, SHCMD("exec ~/.hidden/scripts/screenshot_crop.sh") }, // screenshot MOD+S (requires script in ~/Dev/scripts/screenshot_crop.sh) 89 | { MODKEY|ShiftMask, XK_equal, spawn, SHCMD("exec ~/.hidden/scripts/emoji_picker.sh") }, // pick emoji MOD++ (requires script in ~/Dev/scripts/emoji_picker.sh) 90 | { MODKEY, XK_e, spawn, SHCMD("exec nemo") }, // open file manager (nemo) MOD+e 91 | { MODKEY, XK_b, togglebar, {0} }, // show hide bar MOD+b 92 | { MODKEY|ALTKEY|ShiftMask, XK_l, spawn, SHCMD("exec slock") }, // lockscreen MOD+ALT+L 93 | { MODKEY, XK_j, focusstack, {.i = +1 } }, // focus window up stack MOD+J 94 | { MODKEY, XK_k, focusstack, {.i = -1 } }, // focus window down stack MOD+K 95 | { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, // move window up stack MOD+J 96 | { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, // move window down stack MOD+K 97 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, // increase windows in master stack MOD+i 98 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, // decrease windows in master stack MOD+d 99 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, // adjust mfact MOD+h 100 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, // adjust mfact MOD+l 101 | { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, // adjust cfact MOD+H 102 | { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, // adjust cfact MOD+L 103 | { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, // adjust cfact MOD+O 104 | { MODKEY, XK_Return, zoom, {0} }, // MOD+Return 105 | { MODKEY|ALTKEY, XK_u, incrgaps, {.i = +10 } }, // adjust gaps MOD+ALT+u 106 | { MODKEY|ALTKEY|ShiftMask, XK_u, incrgaps, {.i = -10 } }, // adjust gaps MOD+ALT+U 107 | { MODKEY|ShiftMask, XK_bracketleft, setborderpx, {.i = -2 } }, // increase border width MOD+{ 108 | { MODKEY|ShiftMask, XK_bracketright, setborderpx, {.i = +2 } }, // decrease border width MOD+} 109 | { MODKEY, XK_Tab, view, {0} }, // tab tag MOD+Tab 110 | { MODKEY, XK_c, killclient, {0} }, // close window MOD+c 111 | { MODKEY, XK_f, togglefullscr, {0} }, // toggle actualfullscreen MOD+f 112 | { MODKEY|ShiftMask, XK_z, unfloatvisible, {.v = &layouts[0]} }, // make floating window tiled MOD+Z 113 | { MODKEY|ALTKEY, XK_1, setlayout, {.v = &layouts[0]} }, // change layout to tile MOD+ALT+1 114 | { MODKEY|ALTKEY, XK_2, setlayout, {.v = &layouts[13]} }, // change layout to float MOD+ALT+2 115 | { MODKEY|ALTKEY, XK_3, setlayout, {.v = &layouts[1]} }, // change layout to monocle MOD+ALT+3 116 | { MODKEY|ALTKEY, XK_4, setlayout, {.v = &layouts[11]} }, // change layout to centeredmaster MOD+ALT+4 117 | { MODKEY|ALTKEY, XK_5, setlayout, {.v = &layouts[5]} }, // change layout to bstac MOD+ALT+5 118 | { MODKEY|ALTKEY, XK_6, setlayout, {.v = &layouts[7]} }, // change layout to grid MOD+ALT+6 119 | { MODKEY|ALTKEY, XK_7, setlayout, {.v = &layouts[2]} }, // change layout to spiral MOD+ALT+7 120 | // { MODKEY, XK_0, view, {.ui = ~0 } }, // view all windows MOD+0 121 | // { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, // make window on all tags MOD+SHIFT+0 122 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, // move window to monitor MOD+, 123 | { MODKEY, XK_period, focusmon, {.i = +1 } }, // move window to monitor MOD+. 124 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, // move window to monitor MOD+SHIFT+, 125 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, // move window to monitor MOD+SHIFT+. 126 | TAGKEYS( XK_1, 0) // change tag MOD+[1-9] 127 | TAGKEYS( XK_2, 1) 128 | TAGKEYS( XK_3, 2) 129 | TAGKEYS( XK_4, 3) 130 | TAGKEYS( XK_5, 4) 131 | TAGKEYS( XK_6, 5) 132 | TAGKEYS( XK_7, 6) 133 | TAGKEYS( XK_8, 7) 134 | TAGKEYS( XK_9, 8) 135 | { MODKEY|ShiftMask, XK_BackSpace, quit, {0} }, // quit dwm MOD+SHIFT+backspace 136 | }; 137 | 138 | 139 | /* button definitions */ 140 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 141 | static const Button buttons[] = { 142 | /* click event mask button function argument */ 143 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 144 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 145 | { ClkWinTitle, 0, Button2, zoom, {0} }, 146 | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 147 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 148 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 149 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 150 | { ClkTagBar, 0, Button1, view, {0} }, 151 | { ClkTagBar, 0, Button3, toggleview, {0} }, 152 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 153 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 154 | }; 155 | -------------------------------------------------------------------------------- /config.def.h.orig: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | /* See LICENSE file for copyright and license details. */ 3 | 4 | /* appearance */ 5 | static const unsigned int borderpx = 2; // border pixel of windows 6 | static const unsigned int snap = 32; // snap pixel 7 | static const unsigned int gappih = 0; // horiz inner gap between windows 8 | static const unsigned int gappiv = 0; // vert inner gap between windows 9 | static const unsigned int gappoh = 0; // horiz outer gap between windows and screen edge 10 | static const unsigned int gappov = 0; // vert outer gap between windows and screen edge 11 | static int smartgaps = 0; // 1 means no outer gap when there is only one window 12 | static const int showbar = 1; // 0 means no bar 13 | static const int topbar = 1; // 0 means bottom bar 14 | static const char *fonts[] = { "Jetbrains Mono NerdFont:size=12:style=Bold", "monospace:size=12" }; 15 | static const char dmenufont[] = "Jetbrains Mono NerdFont:size=12:style=Bold"; 16 | #include "themes/mhtheme.h" 17 | static const char *colors[][3] = { 18 | /* fg bg border */ 19 | [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 20 | [SchemeSel] = { col_gray4, col_accnt, col_accnt }, 21 | }; 22 | 23 | /* tagging */ 24 | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 25 | 26 | static const Rule rules[] = { 27 | /* xprop(1): 28 | * WM_CLASS(STRING) = instance, class 29 | * WM_NAME(STRING) = title 30 | */ 31 | /* class instance title tags mask isfloating monitor */ 32 | { "Gimp", NULL, NULL, 0, 1, -1 }, 33 | { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, 34 | }; 35 | 36 | /* layout(s) */ 37 | static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */ 38 | static const int nmaster = 1; /* number of clients in master area */ 39 | static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ 40 | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 41 | 42 | #define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ 43 | #include "vanitygaps.c" 44 | #include "unfloat.c" 45 | 46 | static const Layout layouts[] = { 47 | /* symbol arrange function */ 48 | { "[]=", tile }, /* first entry is default */ 49 | { "[M]", monocle }, 50 | { "[@]", spiral }, 51 | { "[\\]", dwindle }, 52 | { "H[]", deck }, 53 | { "TTT", bstack }, 54 | { "===", bstackhoriz }, 55 | { "HHH", grid }, 56 | { "###", nrowgrid }, 57 | { "---", horizgrid }, 58 | { ":::", gaplessgrid }, 59 | { "|M|", centeredmaster }, 60 | { ">M>", centeredfloatingmaster }, 61 | { "><>", NULL }, /* no layout function means floating behavior */ 62 | { NULL, NULL }, 63 | }; 64 | 65 | /* key definitions */ 66 | #define MODKEY Mod4Mask 67 | #define ALTKEY Mod1Mask 68 | #define TAGKEYS(KEY,TAG) \ 69 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 70 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 71 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 72 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 73 | 74 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 75 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 76 | 77 | /* commands */ 78 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 79 | static const char *dmenucmd[] = { "dmenu_run", "-c", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_accnt, "-sf", col_gray4, NULL }; 80 | static const char *termcmd[] = { "kitty", NULL }; 81 | 82 | #include "movestack.c" 83 | static const Key keys[] = { 84 | /* modifier key function argument */ 85 | { MODKEY, XK_r, spawn, {.v = dmenucmd } }, // open app launcher MOD+r 86 | { MODKEY, XK_Return, spawn, {.v = termcmd } }, // spawn terminal MOD+return 87 | { MODKEY, XK_s, spawn, SHCMD("exec ~/Dev/scripts/screenshot.sh") }, // screenshot MOD+s (requires script in ~/Dev/scripts/screenshot.sh) 88 | { MODKEY|ShiftMask, XK_s, spawn, SHCMD("flameshot gui") }, // screenshot MOD+S (requires script in ~/Dev/scripts/screenshot_crop.sh) 89 | { MODKEY, XK_e, spawn, SHCMD("exec nemo") }, // open file manager (nemo) MOD+e 90 | { MODKEY, XK_b, togglebar, {0} }, // show hide bar MOD+b 91 | { MODKEY|ALTKEY|ShiftMask, XK_l, spawn, SHCMD("exec slock") }, // lockscreen MOD+ALT+L 92 | { MODKEY, XK_j, focusstack, {.i = +1 } }, // focus window up stack MOD+J 93 | { MODKEY, XK_k, focusstack, {.i = -1 } }, // focus window down stack MOD+K 94 | { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, // move window up stack MOD+J 95 | { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, // move window down stack MOD+K 96 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, // increase windows in master stack MOD+i 97 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, // decrease windows in master stack MOD+d 98 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, // adjust mfact MOD+h 99 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, // adjust mfact MOD+l 100 | { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, // adjust cfact MOD+H 101 | { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, // adjust cfact MOD+L 102 | { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, // adjust cfact MOD+O 103 | { MODKEY, XK_Return, zoom, {0} }, // MOD+Return 104 | { MODKEY|ALTKEY, XK_u, incrgaps, {.i = +10 } }, // adjust gaps MOD+ALT+u 105 | { MODKEY|ALTKEY|ShiftMask, XK_u, incrgaps, {.i = -10 } }, // adjust gaps MOD+ALT+U 106 | { MODKEY|ShiftMask, XK_bracketleft, setborderpx, {.i = -2 } }, // increase border width MOD+{ 107 | { MODKEY|ShiftMask, XK_bracketright, setborderpx, {.i = +2 } }, // decrease border width MOD+} 108 | { MODKEY, XK_Tab, view, {0} }, // tab tag MOD+Tab 109 | { MODKEY, XK_c, killclient, {0} }, // close window MOD+c 110 | { MODKEY|ShiftMask, XK_z, unfloatvisible, {.v = &layouts[0]} }, // make floating window tiled MOD+Z 111 | { MODKEY|ALTKEY, XK_1, setlayout, {.v = &layouts[0]} }, // change layout to tile MOD+ALT+1 112 | { MODKEY|ALTKEY, XK_2, setlayout, {.v = &layouts[13]} }, // change layout to float MOD+ALT+2 113 | { MODKEY|ALTKEY, XK_3, setlayout, {.v = &layouts[1]} }, // change layout to monocle MOD+ALT+3 114 | { MODKEY|ALTKEY, XK_4, setlayout, {.v = &layouts[11]} }, // change layout to centeredmaster MOD+ALT+4 115 | { MODKEY|ALTKEY, XK_5, setlayout, {.v = &layouts[5]} }, // change layout to bstac MOD+ALT+5 116 | { MODKEY|ALTKEY, XK_6, setlayout, {.v = &layouts[7]} }, // change layout to grid MOD+ALT+6 117 | { MODKEY|ALTKEY, XK_7, setlayout, {.v = &layouts[2]} }, // change layout to spiral MOD+ALT+7 118 | { MODKEY, XK_0, view, {.ui = ~0 } }, // view all windows MOD+0 119 | { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, // make window on all tags MOD+SHIFT+0 120 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, // move window to monitor MOD+, 121 | { MODKEY, XK_period, focusmon, {.i = +1 } }, // move window to monitor MOD+. 122 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, // move window to monitor MOD+SHIFT+, 123 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, // move window to monitor MOD+SHIFT+. 124 | TAGKEYS( XK_1, 0) // change tag MOD+[1-9] 125 | TAGKEYS( XK_2, 1) 126 | TAGKEYS( XK_3, 2) 127 | TAGKEYS( XK_4, 3) 128 | TAGKEYS( XK_5, 4) 129 | TAGKEYS( XK_6, 5) 130 | TAGKEYS( XK_7, 6) 131 | TAGKEYS( XK_8, 7) 132 | TAGKEYS( XK_9, 8) 133 | { MODKEY|ShiftMask, XK_BackSpace, quit, {0} }, // quit dwm MOD+SHIFT+backspace 134 | }; 135 | 136 | 137 | /* button definitions */ 138 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 139 | static const Button buttons[] = { 140 | /* click event mask button function argument */ 141 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 142 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 143 | { ClkWinTitle, 0, Button2, zoom, {0} }, 144 | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 145 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 146 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 147 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 148 | { ClkTagBar, 0, Button1, view, {0} }, 149 | { ClkTagBar, 0, Button3, toggleview, {0} }, 150 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 151 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 152 | }; 153 | -------------------------------------------------------------------------------- /config.def.h.rej: -------------------------------------------------------------------------------- 1 | --- config.def.h 2 | +++ config.def.h 3 | @@ -78,6 +78,7 @@ static Key keys[] = { 4 | { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 5 | { MODKEY, XK_space, setlayout, {0} }, 6 | { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, 7 | + { MODKEY|ShiftMask, XK_f, togglefullscr, {0} }, 8 | { MODKEY, XK_0, view, {.ui = ~0 } }, 9 | { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, 10 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, 11 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | /* See LICENSE file for copyright and license details. */ 3 | 4 | /* appearance */ 5 | static const unsigned int borderpx = 2; // border pixel of windows 6 | static const unsigned int snap = 32; // snap pixel 7 | static const unsigned int gappih = 0; // horiz inner gap between windows 8 | static const unsigned int gappiv = 0; // vert inner gap between windows 9 | static const unsigned int gappoh = 0; // horiz outer gap between windows and screen edge 10 | static const unsigned int gappov = 0; // vert outer gap between windows and screen edge 11 | static int smartgaps = 0; // 1 means no outer gap when there is only one window 12 | static const int showbar = 0; // 0 means no bar ! CHANGED FROM DEFAULT 13 | static const int topbar = 1; // 0 means bottom bar 14 | static const char *fonts[] = { "Jetbrains Mono NerdFont:size=12:style=Bold", "monospace:size=12" }; 15 | static const char dmenufont[] = "Jetbrains Mono NerdFont:size=12:style=Bold"; 16 | #include "themes/mhtheme.h" 17 | static const char *colors[][3] = { 18 | /* fg bg border */ 19 | [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 20 | [SchemeSel] = { col_gray4, col_accnt, col_accnt }, 21 | }; 22 | 23 | /* tagging */ 24 | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 25 | 26 | static const Rule rules[] = { 27 | /* xprop(1): 28 | * WM_CLASS(STRING) = instance, class 29 | * WM_NAME(STRING) = title 30 | */ 31 | /* class instance title tags mask isfloating monitor */ 32 | { "Gimp", NULL, NULL, 0, 1, -1 }, 33 | { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, 34 | }; 35 | 36 | /* layout(s) */ 37 | static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */ 38 | static const int nmaster = 1; /* number of clients in master area */ 39 | static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ 40 | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 41 | 42 | #define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ 43 | #include "vanitygaps.c" 44 | #include "unfloat.c" 45 | 46 | static const Layout layouts[] = { 47 | /* symbol arrange function */ 48 | { "[]=", tile }, /* first entry is default */ 49 | { "[M]", monocle }, 50 | { "[@]", spiral }, 51 | { "[\\]", dwindle }, 52 | { "H[]", deck }, 53 | { "TTT", bstack }, 54 | { "===", bstackhoriz }, 55 | { "HHH", grid }, 56 | { "###", nrowgrid }, 57 | { "---", horizgrid }, 58 | { ":::", gaplessgrid }, 59 | { "|M|", centeredmaster }, 60 | { ">M>", centeredfloatingmaster }, 61 | { "><>", NULL }, /* no layout function means floating behavior */ 62 | { NULL, NULL }, 63 | }; 64 | 65 | /* key definitions */ 66 | #define MODKEY Mod4Mask 67 | #define ALTKEY Mod1Mask 68 | #define TAGKEYS(KEY,TAG) \ 69 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 70 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 71 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 72 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 73 | 74 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 75 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 76 | 77 | /* commands */ 78 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 79 | static const char *dmenucmd[] = { "dmenu_run", "-c", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_accnt, "-sf", col_gray4, NULL }; 80 | static const char *termcmd[] = { "kitty", NULL }; 81 | 82 | #include "movestack.c" 83 | static const Key keys[] = { 84 | /* modifier key function argument */ 85 | { MODKEY, XK_r, spawn, {.v = dmenucmd } }, // open app launcher MOD+r 86 | { MODKEY, XK_Return, spawn, {.v = termcmd } }, // spawn terminal MOD+return 87 | { MODKEY, XK_s, spawn, SHCMD("exec ~/.hidden/scripts/screenshot_multimon.sh") }, // screenshot MOD+s (requires script in ~/Dev/scripts/screenshot.sh) 88 | { MODKEY|ShiftMask, XK_s, spawn, SHCMD("exec ~/.hidden/scripts/screenshot_crop.sh") }, // screenshot MOD+S (requires script in ~/Dev/scripts/screenshot_crop.sh) 89 | { MODKEY|ShiftMask, XK_equal, spawn, SHCMD("exec ~/.hidden/scripts/emoji_picker.sh") }, // pick emoji MOD++ (requires script in ~/Dev/scripts/emoji_picker.sh) 90 | { MODKEY, XK_e, spawn, SHCMD("exec nemo") }, // open file manager (nemo) MOD+e 91 | { MODKEY, XK_b, togglebar, {0} }, // show hide bar MOD+b 92 | { MODKEY|ALTKEY|ShiftMask, XK_l, spawn, SHCMD("exec slock") }, // lockscreen MOD+ALT+L 93 | { MODKEY, XK_j, focusstack, {.i = +1 } }, // focus window up stack MOD+J 94 | { MODKEY, XK_k, focusstack, {.i = -1 } }, // focus window down stack MOD+K 95 | { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, // move window up stack MOD+J 96 | { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, // move window down stack MOD+K 97 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, // increase windows in master stack MOD+i 98 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, // decrease windows in master stack MOD+d 99 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, // adjust mfact MOD+h 100 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, // adjust mfact MOD+l 101 | { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, // adjust cfact MOD+H 102 | { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, // adjust cfact MOD+L 103 | { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, // adjust cfact MOD+O 104 | { MODKEY, XK_Return, zoom, {0} }, // MOD+Return 105 | { MODKEY|ALTKEY, XK_u, incrgaps, {.i = +10 } }, // adjust gaps MOD+ALT+u 106 | { MODKEY|ALTKEY|ShiftMask, XK_u, incrgaps, {.i = -10 } }, // adjust gaps MOD+ALT+U 107 | { MODKEY|ShiftMask, XK_bracketleft, setborderpx, {.i = -2 } }, // increase border width MOD+{ 108 | { MODKEY|ShiftMask, XK_bracketright, setborderpx, {.i = +2 } }, // decrease border width MOD+} 109 | { MODKEY, XK_Tab, view, {0} }, // tab tag MOD+Tab 110 | { MODKEY, XK_c, killclient, {0} }, // close window MOD+c 111 | { MODKEY, XK_f, togglefullscr, {0} }, // toggle actualfullscreen MOD+f 112 | { MODKEY|ShiftMask, XK_z, unfloatvisible, {.v = &layouts[0]} }, // make floating window tiled MOD+Z 113 | { MODKEY|ALTKEY, XK_1, setlayout, {.v = &layouts[0]} }, // change layout to tile MOD+ALT+1 114 | { MODKEY|ALTKEY, XK_2, setlayout, {.v = &layouts[13]} }, // change layout to float MOD+ALT+2 115 | { MODKEY|ALTKEY, XK_3, setlayout, {.v = &layouts[1]} }, // change layout to monocle MOD+ALT+3 116 | { MODKEY|ALTKEY, XK_4, setlayout, {.v = &layouts[11]} }, // change layout to centeredmaster MOD+ALT+4 117 | { MODKEY|ALTKEY, XK_5, setlayout, {.v = &layouts[5]} }, // change layout to bstac MOD+ALT+5 118 | { MODKEY|ALTKEY, XK_6, setlayout, {.v = &layouts[7]} }, // change layout to grid MOD+ALT+6 119 | { MODKEY|ALTKEY, XK_7, setlayout, {.v = &layouts[2]} }, // change layout to spiral MOD+ALT+7 120 | // { MODKEY, XK_0, view, {.ui = ~0 } }, // view all windows MOD+0 121 | // { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, // make window on all tags MOD+SHIFT+0 122 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, // move window to monitor MOD+, 123 | { MODKEY, XK_period, focusmon, {.i = +1 } }, // move window to monitor MOD+. 124 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, // move window to monitor MOD+SHIFT+, 125 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, // move window to monitor MOD+SHIFT+. 126 | TAGKEYS( XK_1, 0) // change tag MOD+[1-9] 127 | TAGKEYS( XK_2, 1) 128 | TAGKEYS( XK_3, 2) 129 | TAGKEYS( XK_4, 3) 130 | TAGKEYS( XK_5, 4) 131 | TAGKEYS( XK_6, 5) 132 | TAGKEYS( XK_7, 6) 133 | TAGKEYS( XK_8, 7) 134 | TAGKEYS( XK_9, 8) 135 | { MODKEY|ShiftMask, XK_BackSpace, quit, {0} }, // quit dwm MOD+SHIFT+backspace 136 | }; 137 | 138 | 139 | /* button definitions */ 140 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 141 | static const Button buttons[] = { 142 | /* click event mask button function argument */ 143 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 144 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 145 | { ClkWinTitle, 0, Button2, zoom, {0} }, 146 | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 147 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 148 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 149 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 150 | { ClkTagBar, 0, Button1, view, {0} }, 151 | { ClkTagBar, 0, Button3, toggleview, {0} }, 152 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 153 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 154 | }; 155 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | # dwm version 2 | VERSION = 6.5 3 | 4 | # Customize below to fit your system 5 | 6 | # paths 7 | PREFIX = /usr/local 8 | MANPREFIX = ${PREFIX}/share/man 9 | 10 | X11INC = /usr/X11R6/include 11 | X11LIB = /usr/X11R6/lib 12 | 13 | # Xinerama, comment if you don't want it 14 | XINERAMALIBS = -lXinerama 15 | XINERAMAFLAGS = -DXINERAMA 16 | 17 | # freetype 18 | FREETYPELIBS = -lfontconfig -lXft 19 | FREETYPEINC = /usr/include/freetype2 20 | # OpenBSD (uncomment) 21 | #FREETYPEINC = ${X11INC}/freetype2 22 | #MANPREFIX = ${PREFIX}/man 23 | 24 | # includes and libs 25 | INCS = -I${X11INC} -I${FREETYPEINC} 26 | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} 27 | 28 | # flags 29 | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 30 | #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} 31 | CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} 32 | LDFLAGS = ${LIBS} 33 | 34 | # Solaris 35 | #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" 36 | #LDFLAGS = ${LIBS} 37 | 38 | # compiler and linker 39 | CC = cc 40 | -------------------------------------------------------------------------------- /drw.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "drw.h" 9 | #include "util.h" 10 | 11 | #define UTF_INVALID 0xFFFD 12 | #define UTF_SIZ 4 13 | 14 | static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; 15 | static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 16 | 0xF8}; 17 | static const long utfmin[UTF_SIZ + 1] = {0, 0, 0x80, 0x800, 0x10000}; 18 | static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 19 | 0x10FFFF}; 20 | 21 | static long utf8decodebyte(const char c, size_t *i) { 22 | for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) 23 | if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) 24 | return (unsigned char)c & ~utfmask[*i]; 25 | return 0; 26 | } 27 | 28 | static size_t utf8validate(long *u, size_t i) { 29 | if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) 30 | *u = UTF_INVALID; 31 | for (i = 1; *u > utfmax[i]; ++i) 32 | ; 33 | return i; 34 | } 35 | 36 | static size_t utf8decode(const char *c, long *u, size_t clen) { 37 | size_t i, j, len, type; 38 | long udecoded; 39 | 40 | *u = UTF_INVALID; 41 | if (!clen) 42 | return 0; 43 | udecoded = utf8decodebyte(c[0], &len); 44 | if (!BETWEEN(len, 1, UTF_SIZ)) 45 | return 1; 46 | for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { 47 | udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); 48 | if (type) 49 | return j; 50 | } 51 | if (j < len) 52 | return 0; 53 | *u = udecoded; 54 | utf8validate(u, len); 55 | 56 | return len; 57 | } 58 | 59 | Drw *drw_create(Display *dpy, int screen, Window root, unsigned int w, 60 | unsigned int h) { 61 | Drw *drw = ecalloc(1, sizeof(Drw)); 62 | 63 | drw->dpy = dpy; 64 | drw->screen = screen; 65 | drw->root = root; 66 | drw->w = w; 67 | drw->h = h; 68 | drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); 69 | drw->gc = XCreateGC(dpy, root, 0, NULL); 70 | XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); 71 | 72 | return drw; 73 | } 74 | 75 | void drw_resize(Drw *drw, unsigned int w, unsigned int h) { 76 | if (!drw) 77 | return; 78 | 79 | drw->w = w; 80 | drw->h = h; 81 | if (drw->drawable) 82 | XFreePixmap(drw->dpy, drw->drawable); 83 | drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, 84 | DefaultDepth(drw->dpy, drw->screen)); 85 | } 86 | 87 | void drw_free(Drw *drw) { 88 | XFreePixmap(drw->dpy, drw->drawable); 89 | XFreeGC(drw->dpy, drw->gc); 90 | drw_fontset_free(drw->fonts); 91 | free(drw); 92 | } 93 | 94 | /* This function is an implementation detail. Library users should use 95 | * drw_fontset_create instead. 96 | */ 97 | static Fnt *xfont_create(Drw *drw, const char *fontname, 98 | FcPattern *fontpattern) { 99 | Fnt *font; 100 | XftFont *xfont = NULL; 101 | FcPattern *pattern = NULL; 102 | 103 | if (fontname) { 104 | /* Using the pattern found at font->xfont->pattern does not yield the 105 | * same substitution results as using the pattern returned by 106 | * FcNameParse; using the latter results in the desired fallback 107 | * behaviour whereas the former just results in missing-character 108 | * rectangles being drawn, at least with some fonts. */ 109 | if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { 110 | fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); 111 | return NULL; 112 | } 113 | if (!(pattern = FcNameParse((FcChar8 *)fontname))) { 114 | fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", 115 | fontname); 116 | XftFontClose(drw->dpy, xfont); 117 | return NULL; 118 | } 119 | } else if (fontpattern) { 120 | if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { 121 | fprintf(stderr, "error, cannot load font from pattern.\n"); 122 | return NULL; 123 | } 124 | } else { 125 | die("no font specified."); 126 | } 127 | 128 | font = ecalloc(1, sizeof(Fnt)); 129 | font->xfont = xfont; 130 | font->pattern = pattern; 131 | font->h = xfont->ascent + xfont->descent; 132 | font->dpy = drw->dpy; 133 | 134 | return font; 135 | } 136 | 137 | static void xfont_free(Fnt *font) { 138 | if (!font) 139 | return; 140 | if (font->pattern) 141 | FcPatternDestroy(font->pattern); 142 | XftFontClose(font->dpy, font->xfont); 143 | free(font); 144 | } 145 | 146 | Fnt *drw_fontset_create(Drw *drw, const char *fonts[], size_t fontcount) { 147 | Fnt *cur, *ret = NULL; 148 | size_t i; 149 | 150 | if (!drw || !fonts) 151 | return NULL; 152 | 153 | for (i = 1; i <= fontcount; i++) { 154 | if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { 155 | cur->next = ret; 156 | ret = cur; 157 | } 158 | } 159 | return (drw->fonts = ret); 160 | } 161 | 162 | void drw_fontset_free(Fnt *font) { 163 | if (font) { 164 | drw_fontset_free(font->next); 165 | xfont_free(font); 166 | } 167 | } 168 | 169 | void drw_clr_create(Drw *drw, Clr *dest, const char *clrname) { 170 | if (!drw || !dest || !clrname) 171 | return; 172 | 173 | if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), 174 | DefaultColormap(drw->dpy, drw->screen), clrname, dest)) 175 | die("error, cannot allocate color '%s'", clrname); 176 | 177 | dest->pixel |= 0xff << 24; 178 | } 179 | 180 | /* Wrapper to create color schemes. The caller has to call free(3) on the 181 | * returned color scheme when done using it. */ 182 | Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) { 183 | size_t i; 184 | Clr *ret; 185 | 186 | /* need at least two colors for a scheme */ 187 | if (!drw || !clrnames || clrcount < 2 || 188 | !(ret = ecalloc(clrcount, sizeof(XftColor)))) 189 | return NULL; 190 | 191 | for (i = 0; i < clrcount; i++) 192 | drw_clr_create(drw, &ret[i], clrnames[i]); 193 | return ret; 194 | } 195 | 196 | void drw_setfontset(Drw *drw, Fnt *set) { 197 | if (drw) 198 | drw->fonts = set; 199 | } 200 | 201 | void drw_setscheme(Drw *drw, Clr *scm) { 202 | if (drw) 203 | drw->scheme = scm; 204 | } 205 | 206 | void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, 207 | int filled, int invert) { 208 | if (!drw || !drw->scheme) 209 | return; 210 | XSetForeground(drw->dpy, drw->gc, 211 | invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); 212 | if (filled) 213 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 214 | else 215 | XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); 216 | } 217 | 218 | int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, 219 | unsigned int lpad, const char *text, int invert) { 220 | int i, ty, ellipsis_x = 0; 221 | unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; 222 | XftDraw *d = NULL; 223 | Fnt *usedfont, *curfont, *nextfont; 224 | int utf8strlen, utf8charlen, render = x || y || w || h; 225 | long utf8codepoint = 0; 226 | const char *utf8str; 227 | FcCharSet *fccharset; 228 | FcPattern *fcpattern; 229 | FcPattern *match; 230 | XftResult result; 231 | int charexists = 0, overflow = 0; 232 | /* keep track of a couple codepoints for which we have no match. */ 233 | enum { nomatches_len = 64 }; 234 | static struct { 235 | long codepoint[nomatches_len]; 236 | unsigned int idx; 237 | } nomatches; 238 | static unsigned int ellipsis_width = 0; 239 | 240 | if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) 241 | return 0; 242 | 243 | if (!render) { 244 | w = invert ? invert : ~invert; 245 | } else { 246 | XSetForeground(drw->dpy, drw->gc, 247 | drw->scheme[invert ? ColFg : ColBg].pixel); 248 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 249 | d = XftDrawCreate(drw->dpy, drw->drawable, 250 | DefaultVisual(drw->dpy, drw->screen), 251 | DefaultColormap(drw->dpy, drw->screen)); 252 | x += lpad; 253 | w -= lpad; 254 | } 255 | 256 | usedfont = drw->fonts; 257 | if (!ellipsis_width && render) 258 | ellipsis_width = drw_fontset_getwidth(drw, "..."); 259 | while (1) { 260 | ew = ellipsis_len = utf8strlen = 0; 261 | utf8str = text; 262 | nextfont = NULL; 263 | while (*text) { 264 | utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); 265 | for (curfont = drw->fonts; curfont; curfont = curfont->next) { 266 | charexists = charexists || 267 | XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); 268 | if (charexists) { 269 | drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); 270 | if (ew + ellipsis_width <= w) { 271 | /* keep track where the ellipsis still fits */ 272 | ellipsis_x = x + ew; 273 | ellipsis_w = w - ew; 274 | ellipsis_len = utf8strlen; 275 | } 276 | 277 | if (ew + tmpw > w) { 278 | overflow = 1; 279 | /* called from drw_fontset_getwidth_clamp(): 280 | * it wants the width AFTER the overflow 281 | */ 282 | if (!render) 283 | x += tmpw; 284 | else 285 | utf8strlen = ellipsis_len; 286 | } else if (curfont == usedfont) { 287 | utf8strlen += utf8charlen; 288 | text += utf8charlen; 289 | ew += tmpw; 290 | } else { 291 | nextfont = curfont; 292 | } 293 | break; 294 | } 295 | } 296 | 297 | if (overflow || !charexists || nextfont) 298 | break; 299 | else 300 | charexists = 0; 301 | } 302 | 303 | if (utf8strlen) { 304 | if (render) { 305 | ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; 306 | XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], 307 | usedfont->xfont, x, ty, (XftChar8 *)utf8str, 308 | utf8strlen); 309 | } 310 | x += ew; 311 | w -= ew; 312 | } 313 | if (render && overflow) 314 | drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); 315 | 316 | if (!*text || overflow) { 317 | break; 318 | } else if (nextfont) { 319 | charexists = 0; 320 | usedfont = nextfont; 321 | } else { 322 | /* Regardless of whether or not a fallback font is found, the 323 | * character must be drawn. */ 324 | charexists = 1; 325 | 326 | for (i = 0; i < nomatches_len; ++i) { 327 | /* avoid calling XftFontMatch if we know we won't find a match */ 328 | if (utf8codepoint == nomatches.codepoint[i]) 329 | goto no_match; 330 | } 331 | 332 | fccharset = FcCharSetCreate(); 333 | FcCharSetAddChar(fccharset, utf8codepoint); 334 | 335 | if (!drw->fonts->pattern) { 336 | /* Refer to the comment in xfont_create for more information. */ 337 | die("the first font in the cache must be loaded from a font string."); 338 | } 339 | 340 | fcpattern = FcPatternDuplicate(drw->fonts->pattern); 341 | FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); 342 | FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); 343 | 344 | FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); 345 | FcDefaultSubstitute(fcpattern); 346 | match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); 347 | 348 | FcCharSetDestroy(fccharset); 349 | FcPatternDestroy(fcpattern); 350 | 351 | if (match) { 352 | usedfont = xfont_create(drw, NULL, match); 353 | if (usedfont && 354 | XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { 355 | for (curfont = drw->fonts; curfont->next; curfont = curfont->next) 356 | ; /* NOP */ 357 | curfont->next = usedfont; 358 | } else { 359 | xfont_free(usedfont); 360 | nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; 361 | no_match: 362 | usedfont = drw->fonts; 363 | } 364 | } 365 | } 366 | } 367 | if (d) 368 | XftDrawDestroy(d); 369 | 370 | return x + (render ? w : 0); 371 | } 372 | 373 | void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, 374 | unsigned int h) { 375 | if (!drw) 376 | return; 377 | 378 | XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); 379 | XSync(drw->dpy, False); 380 | } 381 | 382 | unsigned int drw_fontset_getwidth(Drw *drw, const char *text) { 383 | if (!drw || !drw->fonts || !text) 384 | return 0; 385 | return drw_text(drw, 0, 0, 0, 0, 0, text, 0); 386 | } 387 | 388 | unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, 389 | unsigned int n) { 390 | unsigned int tmp = 0; 391 | if (drw && drw->fonts && text && n) 392 | tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); 393 | return MIN(n, tmp); 394 | } 395 | 396 | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, 397 | unsigned int *w, unsigned int *h) { 398 | XGlyphInfo ext; 399 | 400 | if (!font || !text) 401 | return; 402 | 403 | XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); 404 | if (w) 405 | *w = ext.xOff; 406 | if (h) 407 | *h = font->h; 408 | } 409 | 410 | Cur *drw_cur_create(Drw *drw, int shape) { 411 | Cur *cur; 412 | 413 | if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) 414 | return NULL; 415 | 416 | cur->cursor = XCreateFontCursor(drw->dpy, shape); 417 | 418 | return cur; 419 | } 420 | 421 | void drw_cur_free(Drw *drw, Cur *cursor) { 422 | if (!cursor) 423 | return; 424 | 425 | XFreeCursor(drw->dpy, cursor->cursor); 426 | free(cursor); 427 | } 428 | -------------------------------------------------------------------------------- /drw.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | typedef struct { 4 | Cursor cursor; 5 | } Cur; 6 | 7 | typedef struct Fnt { 8 | Display *dpy; 9 | unsigned int h; 10 | XftFont *xfont; 11 | FcPattern *pattern; 12 | struct Fnt *next; 13 | } Fnt; 14 | 15 | enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ 16 | typedef XftColor Clr; 17 | 18 | typedef struct { 19 | unsigned int w, h; 20 | Display *dpy; 21 | int screen; 22 | Window root; 23 | Drawable drawable; 24 | GC gc; 25 | Clr *scheme; 26 | Fnt *fonts; 27 | } Drw; 28 | 29 | /* Drawable abstraction */ 30 | Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); 31 | void drw_resize(Drw *drw, unsigned int w, unsigned int h); 32 | void drw_free(Drw *drw); 33 | 34 | /* Fnt abstraction */ 35 | Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); 36 | void drw_fontset_free(Fnt* set); 37 | unsigned int drw_fontset_getwidth(Drw *drw, const char *text); 38 | unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); 39 | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); 40 | 41 | /* Colorscheme abstraction */ 42 | void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); 43 | Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); 44 | 45 | /* Cursor abstraction */ 46 | Cur *drw_cur_create(Drw *drw, int shape); 47 | void drw_cur_free(Drw *drw, Cur *cursor); 48 | 49 | /* Drawing context manipulation */ 50 | void drw_setfontset(Drw *drw, Fnt *set); 51 | void drw_setscheme(Drw *drw, Clr *scm); 52 | 53 | /* Drawing functions */ 54 | void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); 55 | int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); 56 | 57 | /* Map functions */ 58 | void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); 59 | -------------------------------------------------------------------------------- /drw.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/drw.o -------------------------------------------------------------------------------- /dwm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/dwm -------------------------------------------------------------------------------- /dwm.1: -------------------------------------------------------------------------------- 1 | .TH DWM 1 dwm\-VERSION 2 | .SH NAME 3 | dwm \- dynamic window manager 4 | .SH SYNOPSIS 5 | .B dwm 6 | .RB [ \-v ] 7 | .SH DESCRIPTION 8 | dwm is a dynamic window manager for X. It manages windows in tiled, monocle 9 | and floating layouts. Either layout can be applied dynamically, optimising the 10 | environment for the application in use and the task performed. 11 | .P 12 | In tiled layouts windows are managed in a master and stacking area. The master 13 | area on the left contains one window by default, and the stacking area on the 14 | right contains all other windows. The number of master area windows can be 15 | adjusted from zero to an arbitrary number. In monocle layout all windows are 16 | maximised to the screen size. In floating layout windows can be resized and 17 | moved freely. Dialog windows are always managed floating, regardless of the 18 | layout applied. 19 | .P 20 | Windows are grouped by tags. Each window can be tagged with one or multiple 21 | tags. Selecting certain tags displays all windows with these tags. 22 | .P 23 | Each screen contains a small status bar which displays all available tags, the 24 | layout, the title of the focused window, and the text read from the root window 25 | name property, if the screen is focused. A floating window is indicated with an 26 | empty square and a maximised floating window is indicated with a filled square 27 | before the windows title. The selected tags are indicated with a different 28 | color. The tags of the focused window are indicated with a filled square in the 29 | top left corner. The tags which are applied to one or more windows are 30 | indicated with an empty square in the top left corner. 31 | .P 32 | dwm draws a small border around windows to indicate the focus state. 33 | .SH OPTIONS 34 | .TP 35 | .B \-v 36 | prints version information to stderr, then exits. 37 | .SH USAGE 38 | .SS Status bar 39 | .TP 40 | .B X root window name 41 | is read and displayed in the status text area. It can be set with the 42 | .BR xsetroot (1) 43 | command. 44 | .TP 45 | .B Button1 46 | click on a tag label to display all windows with that tag, click on the layout 47 | label toggles between tiled and floating layout. 48 | .TP 49 | .B Button3 50 | click on a tag label adds/removes all windows with that tag to/from the view. 51 | .TP 52 | .B Mod1\-Button1 53 | click on a tag label applies that tag to the focused window. 54 | .TP 55 | .B Mod1\-Button3 56 | click on a tag label adds/removes that tag to/from the focused window. 57 | .SS Keyboard commands 58 | .TP 59 | .B Mod1\-Shift\-Return 60 | Start 61 | .BR st(1). 62 | .TP 63 | .B Mod1\-p 64 | Spawn 65 | .BR dmenu(1) 66 | for launching other programs. 67 | .TP 68 | .B Mod1\-, 69 | Focus previous screen, if any. 70 | .TP 71 | .B Mod1\-. 72 | Focus next screen, if any. 73 | .TP 74 | .B Mod1\-Shift\-, 75 | Send focused window to previous screen, if any. 76 | .TP 77 | .B Mod1\-Shift\-. 78 | Send focused window to next screen, if any. 79 | .TP 80 | .B Mod1\-b 81 | Toggles bar on and off. 82 | .TP 83 | .B Mod1\-t 84 | Sets tiled layout. 85 | .TP 86 | .B Mod1\-f 87 | Sets floating layout. 88 | .TP 89 | .B Mod1\-m 90 | Sets monocle layout. 91 | .TP 92 | .B Mod1\-space 93 | Toggles between current and previous layout. 94 | .TP 95 | .B Mod1\-j 96 | Focus next window. 97 | .TP 98 | .B Mod1\-k 99 | Focus previous window. 100 | .TP 101 | .B Mod1\-i 102 | Increase number of windows in master area. 103 | .TP 104 | .B Mod1\-d 105 | Decrease number of windows in master area. 106 | .TP 107 | .B Mod1\-l 108 | Increase master area size. 109 | .TP 110 | .B Mod1\-h 111 | Decrease master area size. 112 | .TP 113 | .B Mod1\-Return 114 | Zooms/cycles focused window to/from master area (tiled layouts only). 115 | .TP 116 | .B Mod1\-Shift\-c 117 | Close focused window. 118 | .TP 119 | .B Mod1\-Shift\-f 120 | Toggle fullscreen for focused window. 121 | .TP 122 | .B Mod1\-Shift\-space 123 | Toggle focused window between tiled and floating state. 124 | .TP 125 | .B Mod1\-Tab 126 | Toggles to the previously selected tags. 127 | .TP 128 | .B Mod1\-Shift\-[1..n] 129 | Apply nth tag to focused window. 130 | .TP 131 | .B Mod1\-Shift\-0 132 | Apply all tags to focused window. 133 | .TP 134 | .B Mod1\-Control\-Shift\-[1..n] 135 | Add/remove nth tag to/from focused window. 136 | .TP 137 | .B Mod1\-[1..n] 138 | View all windows with nth tag. 139 | .TP 140 | .B Mod1\-0 141 | View all windows with any tag. 142 | .TP 143 | .B Mod1\-Control\-[1..n] 144 | Add/remove all windows with nth tag to/from the view. 145 | .TP 146 | .B Mod1\-Shift\-q 147 | Quit dwm. 148 | .SS Mouse commands 149 | .TP 150 | .B Mod1\-Button1 151 | Move focused window while dragging. Tiled windows will be toggled to the floating state. 152 | .TP 153 | .B Mod1\-Button2 154 | Toggles focused window between floating and tiled state. 155 | .TP 156 | .B Mod1\-Button3 157 | Resize focused window while dragging. Tiled windows will be toggled to the floating state. 158 | .SH CUSTOMIZATION 159 | dwm is customized by creating a custom config.h and (re)compiling the source 160 | code. This keeps it fast, secure and simple. 161 | .SH SEE ALSO 162 | .BR dmenu (1), 163 | .BR st (1) 164 | .SH ISSUES 165 | Java applications which use the XToolkit/XAWT backend may draw grey windows 166 | only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early 167 | JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds 168 | are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the 169 | environment variable 170 | .BR AWT_TOOLKIT=MToolkit 171 | (to use the older Motif backend instead) or running 172 | .B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D 173 | or 174 | .B wmname LG3D 175 | (to pretend that a non-reparenting window manager is running that the 176 | XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable 177 | .BR _JAVA_AWT_WM_NONREPARENTING=1 . 178 | .SH BUGS 179 | Send all bug reports with a patch to hackers@suckless.org. 180 | -------------------------------------------------------------------------------- /dwm.c.rej: -------------------------------------------------------------------------------- 1 | --- dwm.c 2 | +++ dwm.c 3 | @@ -1720,6 +1721,13 @@ togglefloating(const Arg *arg) 4 | arrange(selmon); 5 | } 6 | 7 | +void 8 | +togglefullscr(const Arg *arg) 9 | +{ 10 | + if(selmon->sel) 11 | + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); 12 | +} 13 | + 14 | void 15 | toggletag(const Arg *arg) 16 | { 17 | -------------------------------------------------------------------------------- /dwm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/dwm.o -------------------------------------------------------------------------------- /dwm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/dwm.png -------------------------------------------------------------------------------- /movestack.c: -------------------------------------------------------------------------------- 1 | void 2 | movestack(const Arg *arg) { 3 | Client *c = NULL, *p = NULL, *pc = NULL, *i; 4 | 5 | if(arg->i > 0) { 6 | /* find the client after selmon->sel */ 7 | for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 8 | if(!c) 9 | for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 10 | 11 | } 12 | else { 13 | /* find the client before selmon->sel */ 14 | for(i = selmon->clients; i != selmon->sel; i = i->next) 15 | if(ISVISIBLE(i) && !i->isfloating) 16 | c = i; 17 | if(!c) 18 | for(; i; i = i->next) 19 | if(ISVISIBLE(i) && !i->isfloating) 20 | c = i; 21 | } 22 | /* find the client before selmon->sel and c */ 23 | for(i = selmon->clients; i && (!p || !pc); i = i->next) { 24 | if(i->next == selmon->sel) 25 | p = i; 26 | if(i->next == c) 27 | pc = i; 28 | } 29 | 30 | /* swap c and selmon->sel selmon->clients in the selmon->clients list */ 31 | if(c && c != selmon->sel) { 32 | Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; 33 | selmon->sel->next = c->next==selmon->sel?c:c->next; 34 | c->next = temp; 35 | 36 | if(p && p != c) 37 | p->next = c; 38 | if(pc && pc != selmon->sel) 39 | pc->next = selmon->sel; 40 | 41 | if(selmon->sel == selmon->clients) 42 | selmon->clients = c; 43 | else if(c == selmon->clients) 44 | selmon->clients = selmon->sel; 45 | 46 | arrange(selmon); 47 | } 48 | } -------------------------------------------------------------------------------- /patches/dwm-actualfullscreen-20211013-cb3f58a.diff: -------------------------------------------------------------------------------- 1 | From eea13010ffc3983392857ee1e3804e3aa1064d7a Mon Sep 17 00:00:00 2001 2 | From: Soenke Lambert 3 | Date: Wed, 13 Oct 2021 18:21:09 +0200 4 | Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f] 5 | 6 | This actually fullscreens a window, instead of just hiding the statusbar 7 | and applying the monocle layout. 8 | --- 9 | config.def.h | 1 + 10 | dwm.1 | 3 +++ 11 | dwm.c | 8 ++++++++ 12 | 3 files changed, 12 insertions(+) 13 | 14 | diff --git a/config.def.h b/config.def.h 15 | index 1c0b587..8cd3204 100644 16 | --- a/config.def.h 17 | +++ b/config.def.h 18 | @@ -78,6 +78,7 @@ static Key keys[] = { 19 | { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 20 | { MODKEY, XK_space, setlayout, {0} }, 21 | { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, 22 | + { MODKEY|ShiftMask, XK_f, togglefullscr, {0} }, 23 | { MODKEY, XK_0, view, {.ui = ~0 } }, 24 | { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, 25 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, 26 | diff --git a/dwm.1 b/dwm.1 27 | index 13b3729..a368d05 100644 28 | --- a/dwm.1 29 | +++ b/dwm.1 30 | @@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only). 31 | .B Mod1\-Shift\-c 32 | Close focused window. 33 | .TP 34 | +.B Mod1\-Shift\-f 35 | +Toggle fullscreen for focused window. 36 | +.TP 37 | .B Mod1\-Shift\-space 38 | Toggle focused window between tiled and floating state. 39 | .TP 40 | diff --git a/dwm.c b/dwm.c 41 | index 4465af1..c1b899a 100644 42 | --- a/dwm.c 43 | +++ b/dwm.c 44 | @@ -211,6 +211,7 @@ static void tagmon(const Arg *arg); 45 | static void tile(Monitor *); 46 | static void togglebar(const Arg *arg); 47 | static void togglefloating(const Arg *arg); 48 | +static void togglefullscr(const Arg *arg); 49 | static void toggletag(const Arg *arg); 50 | static void toggleview(const Arg *arg); 51 | static void unfocus(Client *c, int setfocus); 52 | @@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg) 53 | arrange(selmon); 54 | } 55 | 56 | +void 57 | +togglefullscr(const Arg *arg) 58 | +{ 59 | + if(selmon->sel) 60 | + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); 61 | +} 62 | + 63 | void 64 | toggletag(const Arg *arg) 65 | { 66 | -- 67 | 2.30.2 68 | 69 | -------------------------------------------------------------------------------- /patches/dwm-alwayscenter-20200625-f04cac6.diff: -------------------------------------------------------------------------------- 1 | diff -up dwm/dwm.c dwmmod/dwm.c 2 | --- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300 3 | +++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300 4 | @@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa) 5 | updatewindowtype(c); 6 | updatesizehints(c); 7 | updatewmhints(c); 8 | + c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; 9 | + c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; 10 | XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); 11 | grabbuttons(c, 0); 12 | if (!c->isfloating) 13 | -------------------------------------------------------------------------------- /patches/dwm-cfacts-vanitygaps-6.4_combo.diff: -------------------------------------------------------------------------------- 1 | diff --git a/config.def.h b/config.def.h 2 | index 9efa774..357dc6f 100644 3 | --- a/config.def.h 4 | +++ b/config.def.h 5 | @@ -3,6 +3,11 @@ 6 | /* appearance */ 7 | static const unsigned int borderpx = 1; /* border pixel of windows */ 8 | static const unsigned int snap = 32; /* snap pixel */ 9 | +static const unsigned int gappih = 20; /* horiz inner gap between windows */ 10 | +static const unsigned int gappiv = 10; /* vert inner gap between windows */ 11 | +static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ 12 | +static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */ 13 | +static int smartgaps = 0; /* 1 means no outer gap when there is only one window */ 14 | static const int showbar = 1; /* 0 means no bar */ 15 | static const int topbar = 1; /* 0 means bottom bar */ 16 | static const char *fonts[] = { "monospace:size=10" }; 17 | @@ -37,11 +42,26 @@ static const int nmaster = 1; /* number of clients in master area */ 18 | static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ 19 | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 20 | 21 | +#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ 22 | +#include "vanitygaps.c" 23 | + 24 | static const Layout layouts[] = { 25 | /* symbol arrange function */ 26 | { "[]=", tile }, /* first entry is default */ 27 | - { "><>", NULL }, /* no layout function means floating behavior */ 28 | { "[M]", monocle }, 29 | + { "[@]", spiral }, 30 | + { "[\\]", dwindle }, 31 | + { "H[]", deck }, 32 | + { "TTT", bstack }, 33 | + { "===", bstackhoriz }, 34 | + { "HHH", grid }, 35 | + { "###", nrowgrid }, 36 | + { "---", horizgrid }, 37 | + { ":::", gaplessgrid }, 38 | + { "|M|", centeredmaster }, 39 | + { ">M>", centeredfloatingmaster }, 40 | + { "><>", NULL }, /* no layout function means floating behavior */ 41 | + { NULL, NULL }, 42 | }; 43 | 44 | /* key definitions */ 45 | @@ -71,7 +91,26 @@ static const Key keys[] = { 46 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, 47 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, 48 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, 49 | + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, 50 | + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, 51 | + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, 52 | { MODKEY, XK_Return, zoom, {0} }, 53 | + { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } }, 54 | + { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } }, 55 | + { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, 56 | + { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, 57 | + { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, 58 | + { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, 59 | + { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, 60 | + { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, 61 | + { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, 62 | + { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, 63 | + { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, 64 | + { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, 65 | + { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, 66 | + { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, 67 | + { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, 68 | + { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, 69 | { MODKEY, XK_Tab, view, {0} }, 70 | { MODKEY|ShiftMask, XK_c, killclient, {0} }, 71 | { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, 72 | diff --git a/dwm.c b/dwm.c 73 | index f1d86b2..5bbd733 100644 74 | --- a/dwm.c 75 | +++ b/dwm.c 76 | @@ -87,6 +87,7 @@ typedef struct Client Client; 77 | struct Client { 78 | char name[256]; 79 | float mina, maxa; 80 | + float cfact; 81 | int x, y, w, h; 82 | int oldx, oldy, oldw, oldh; 83 | int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; 84 | @@ -119,6 +120,10 @@ struct Monitor { 85 | int by; /* bar geometry */ 86 | int mx, my, mw, mh; /* screen size */ 87 | int wx, wy, ww, wh; /* window area */ 88 | + int gappih; /* horizontal gap between windows */ 89 | + int gappiv; /* vertical gap between windows */ 90 | + int gappoh; /* horizontal outer gaps */ 91 | + int gappov; /* vertical outer gaps */ 92 | unsigned int seltags; 93 | unsigned int sellt; 94 | unsigned int tagset[2]; 95 | @@ -201,6 +206,7 @@ static void setclientstate(Client *c, long state); 96 | static void setfocus(Client *c); 97 | static void setfullscreen(Client *c, int fullscreen); 98 | static void setlayout(const Arg *arg); 99 | +static void setcfact(const Arg *arg); 100 | static void setmfact(const Arg *arg); 101 | static void setup(void); 102 | static void seturgent(Client *c, int urg); 103 | @@ -208,7 +214,6 @@ static void showhide(Client *c); 104 | static void spawn(const Arg *arg); 105 | static void tag(const Arg *arg); 106 | static void tagmon(const Arg *arg); 107 | -static void tile(Monitor *m); 108 | static void togglebar(const Arg *arg); 109 | static void togglefloating(const Arg *arg); 110 | static void toggletag(const Arg *arg); 111 | @@ -641,6 +646,10 @@ createmon(void) 112 | m->nmaster = nmaster; 113 | m->showbar = showbar; 114 | m->topbar = topbar; 115 | + m->gappih = gappih; 116 | + m->gappiv = gappiv; 117 | + m->gappoh = gappoh; 118 | + m->gappov = gappov; 119 | m->lt[0] = &layouts[0]; 120 | m->lt[1] = &layouts[1 % LENGTH(layouts)]; 121 | strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 122 | @@ -1043,6 +1052,7 @@ manage(Window w, XWindowAttributes *wa) 123 | c->w = c->oldw = wa->width; 124 | c->h = c->oldh = wa->height; 125 | c->oldbw = wa->border_width; 126 | + c->cfact = 1.0; 127 | 128 | updatetitle(c); 129 | if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { 130 | @@ -1521,6 +1531,24 @@ setlayout(const Arg *arg) 131 | drawbar(selmon); 132 | } 133 | 134 | +void 135 | +setcfact(const Arg *arg) { 136 | + float f; 137 | + Client *c; 138 | + 139 | + c = selmon->sel; 140 | + 141 | + if(!arg || !c || !selmon->lt[selmon->sellt]->arrange) 142 | + return; 143 | + f = arg->f + c->cfact; 144 | + if(arg->f == 0.0) 145 | + f = 1.0; 146 | + else if(f < 0.25 || f > 4.0) 147 | + return; 148 | + c->cfact = f; 149 | + arrange(selmon); 150 | +} 151 | + 152 | /* arg > 1.0 will set mfact absolutely */ 153 | void 154 | setmfact(const Arg *arg) 155 | @@ -1684,34 +1712,6 @@ tagmon(const Arg *arg) 156 | sendmon(selmon->sel, dirtomon(arg->i)); 157 | } 158 | 159 | -void 160 | -tile(Monitor *m) 161 | -{ 162 | - unsigned int i, n, h, mw, my, ty; 163 | - Client *c; 164 | - 165 | - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 166 | - if (n == 0) 167 | - return; 168 | - 169 | - if (n > m->nmaster) 170 | - mw = m->nmaster ? m->ww * m->mfact : 0; 171 | - else 172 | - mw = m->ww; 173 | - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 174 | - if (i < m->nmaster) { 175 | - h = (m->wh - my) / (MIN(n, m->nmaster) - i); 176 | - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); 177 | - if (my + HEIGHT(c) < m->wh) 178 | - my += HEIGHT(c); 179 | - } else { 180 | - h = (m->wh - ty) / (n - i); 181 | - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); 182 | - if (ty + HEIGHT(c) < m->wh) 183 | - ty += HEIGHT(c); 184 | - } 185 | -} 186 | - 187 | void 188 | togglebar(const Arg *arg) 189 | { 190 | diff --git a/vanitygaps.c b/vanitygaps.c 191 | new file mode 100644 192 | index 0000000..1a816b6 193 | --- /dev/null 194 | +++ b/vanitygaps.c 195 | @@ -0,0 +1,822 @@ 196 | +/* Key binding functions */ 197 | +static void defaultgaps(const Arg *arg); 198 | +static void incrgaps(const Arg *arg); 199 | +static void incrigaps(const Arg *arg); 200 | +static void incrogaps(const Arg *arg); 201 | +static void incrohgaps(const Arg *arg); 202 | +static void incrovgaps(const Arg *arg); 203 | +static void incrihgaps(const Arg *arg); 204 | +static void incrivgaps(const Arg *arg); 205 | +static void togglegaps(const Arg *arg); 206 | +/* Layouts (delete the ones you do not need) */ 207 | +static void bstack(Monitor *m); 208 | +static void bstackhoriz(Monitor *m); 209 | +static void centeredmaster(Monitor *m); 210 | +static void centeredfloatingmaster(Monitor *m); 211 | +static void deck(Monitor *m); 212 | +static void dwindle(Monitor *m); 213 | +static void fibonacci(Monitor *m, int s); 214 | +static void grid(Monitor *m); 215 | +static void nrowgrid(Monitor *m); 216 | +static void spiral(Monitor *m); 217 | +static void tile(Monitor *m); 218 | +/* Internals */ 219 | +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); 220 | +static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); 221 | +static void setgaps(int oh, int ov, int ih, int iv); 222 | + 223 | +/* Settings */ 224 | +#if !PERTAG_PATCH 225 | +static int enablegaps = 1; 226 | +#endif // PERTAG_PATCH 227 | + 228 | +void 229 | +setgaps(int oh, int ov, int ih, int iv) 230 | +{ 231 | + if (oh < 0) oh = 0; 232 | + if (ov < 0) ov = 0; 233 | + if (ih < 0) ih = 0; 234 | + if (iv < 0) iv = 0; 235 | + 236 | + selmon->gappoh = oh; 237 | + selmon->gappov = ov; 238 | + selmon->gappih = ih; 239 | + selmon->gappiv = iv; 240 | + arrange(selmon); 241 | +} 242 | + 243 | +void 244 | +togglegaps(const Arg *arg) 245 | +{ 246 | + #if PERTAG_PATCH 247 | + selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; 248 | + #else 249 | + enablegaps = !enablegaps; 250 | + #endif // PERTAG_PATCH 251 | + arrange(NULL); 252 | +} 253 | + 254 | +void 255 | +defaultgaps(const Arg *arg) 256 | +{ 257 | + setgaps(gappoh, gappov, gappih, gappiv); 258 | +} 259 | + 260 | +void 261 | +incrgaps(const Arg *arg) 262 | +{ 263 | + setgaps( 264 | + selmon->gappoh + arg->i, 265 | + selmon->gappov + arg->i, 266 | + selmon->gappih + arg->i, 267 | + selmon->gappiv + arg->i 268 | + ); 269 | +} 270 | + 271 | +void 272 | +incrigaps(const Arg *arg) 273 | +{ 274 | + setgaps( 275 | + selmon->gappoh, 276 | + selmon->gappov, 277 | + selmon->gappih + arg->i, 278 | + selmon->gappiv + arg->i 279 | + ); 280 | +} 281 | + 282 | +void 283 | +incrogaps(const Arg *arg) 284 | +{ 285 | + setgaps( 286 | + selmon->gappoh + arg->i, 287 | + selmon->gappov + arg->i, 288 | + selmon->gappih, 289 | + selmon->gappiv 290 | + ); 291 | +} 292 | + 293 | +void 294 | +incrohgaps(const Arg *arg) 295 | +{ 296 | + setgaps( 297 | + selmon->gappoh + arg->i, 298 | + selmon->gappov, 299 | + selmon->gappih, 300 | + selmon->gappiv 301 | + ); 302 | +} 303 | + 304 | +void 305 | +incrovgaps(const Arg *arg) 306 | +{ 307 | + setgaps( 308 | + selmon->gappoh, 309 | + selmon->gappov + arg->i, 310 | + selmon->gappih, 311 | + selmon->gappiv 312 | + ); 313 | +} 314 | + 315 | +void 316 | +incrihgaps(const Arg *arg) 317 | +{ 318 | + setgaps( 319 | + selmon->gappoh, 320 | + selmon->gappov, 321 | + selmon->gappih + arg->i, 322 | + selmon->gappiv 323 | + ); 324 | +} 325 | + 326 | +void 327 | +incrivgaps(const Arg *arg) 328 | +{ 329 | + setgaps( 330 | + selmon->gappoh, 331 | + selmon->gappov, 332 | + selmon->gappih, 333 | + selmon->gappiv + arg->i 334 | + ); 335 | +} 336 | + 337 | +void 338 | +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) 339 | +{ 340 | + unsigned int n, oe, ie; 341 | + #if PERTAG_PATCH 342 | + oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; 343 | + #else 344 | + oe = ie = enablegaps; 345 | + #endif // PERTAG_PATCH 346 | + Client *c; 347 | + 348 | + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 349 | + if (smartgaps && n == 1) { 350 | + oe = 0; // outer gaps disabled when only one client 351 | + } 352 | + 353 | + *oh = m->gappoh*oe; // outer horizontal gap 354 | + *ov = m->gappov*oe; // outer vertical gap 355 | + *ih = m->gappih*ie; // inner horizontal gap 356 | + *iv = m->gappiv*ie; // inner vertical gap 357 | + *nc = n; // number of clients 358 | +} 359 | + 360 | +void 361 | +getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) 362 | +{ 363 | + unsigned int n; 364 | + float mfacts = 0, sfacts = 0; 365 | + int mtotal = 0, stotal = 0; 366 | + Client *c; 367 | + 368 | + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 369 | + if (n < m->nmaster) 370 | + mfacts += c->cfact; 371 | + else 372 | + sfacts += c->cfact; 373 | + 374 | + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 375 | + if (n < m->nmaster) 376 | + mtotal += msize * (c->cfact / mfacts); 377 | + else 378 | + stotal += ssize * (c->cfact / sfacts); 379 | + 380 | + *mf = mfacts; // total factor of master area 381 | + *sf = sfacts; // total factor of stack area 382 | + *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split 383 | + *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split 384 | +} 385 | + 386 | +/*** 387 | + * Layouts 388 | + */ 389 | + 390 | +/* 391 | + * Bottomstack layout + gaps 392 | + * https://dwm.suckless.org/patches/bottomstack/ 393 | + */ 394 | +static void 395 | +bstack(Monitor *m) 396 | +{ 397 | + unsigned int i, n; 398 | + int oh, ov, ih, iv; 399 | + int mx = 0, my = 0, mh = 0, mw = 0; 400 | + int sx = 0, sy = 0, sh = 0, sw = 0; 401 | + float mfacts, sfacts; 402 | + int mrest, srest; 403 | + Client *c; 404 | + 405 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 406 | + if (n == 0) 407 | + return; 408 | + 409 | + sx = mx = m->wx + ov; 410 | + sy = my = m->wy + oh; 411 | + sh = mh = m->wh - 2*oh; 412 | + mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 413 | + sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); 414 | + 415 | + if (m->nmaster && n > m->nmaster) { 416 | + sh = (mh - ih) * (1 - m->mfact); 417 | + mh = mh - ih - sh; 418 | + sx = mx; 419 | + sy = my + mh + ih; 420 | + } 421 | + 422 | + getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 423 | + 424 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 425 | + if (i < m->nmaster) { 426 | + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 427 | + mx += WIDTH(c) + iv; 428 | + } else { 429 | + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 430 | + sx += WIDTH(c) + iv; 431 | + } 432 | + } 433 | +} 434 | + 435 | +static void 436 | +bstackhoriz(Monitor *m) 437 | +{ 438 | + unsigned int i, n; 439 | + int oh, ov, ih, iv; 440 | + int mx = 0, my = 0, mh = 0, mw = 0; 441 | + int sx = 0, sy = 0, sh = 0, sw = 0; 442 | + float mfacts, sfacts; 443 | + int mrest, srest; 444 | + Client *c; 445 | + 446 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 447 | + if (n == 0) 448 | + return; 449 | + 450 | + sx = mx = m->wx + ov; 451 | + sy = my = m->wy + oh; 452 | + mh = m->wh - 2*oh; 453 | + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 454 | + mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 455 | + sw = m->ww - 2*ov; 456 | + 457 | + if (m->nmaster && n > m->nmaster) { 458 | + sh = (mh - ih) * (1 - m->mfact); 459 | + mh = mh - ih - sh; 460 | + sy = my + mh + ih; 461 | + sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); 462 | + } 463 | + 464 | + getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); 465 | + 466 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 467 | + if (i < m->nmaster) { 468 | + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 469 | + mx += WIDTH(c) + iv; 470 | + } else { 471 | + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 472 | + sy += HEIGHT(c) + ih; 473 | + } 474 | + } 475 | +} 476 | + 477 | +/* 478 | + * Centred master layout + gaps 479 | + * https://dwm.suckless.org/patches/centeredmaster/ 480 | + */ 481 | +void 482 | +centeredmaster(Monitor *m) 483 | +{ 484 | + unsigned int i, n; 485 | + int oh, ov, ih, iv; 486 | + int mx = 0, my = 0, mh = 0, mw = 0; 487 | + int lx = 0, ly = 0, lw = 0, lh = 0; 488 | + int rx = 0, ry = 0, rw = 0, rh = 0; 489 | + float mfacts = 0, lfacts = 0, rfacts = 0; 490 | + int mtotal = 0, ltotal = 0, rtotal = 0; 491 | + int mrest = 0, lrest = 0, rrest = 0; 492 | + Client *c; 493 | + 494 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 495 | + if (n == 0) 496 | + return; 497 | + 498 | + /* initialize areas */ 499 | + mx = m->wx + ov; 500 | + my = m->wy + oh; 501 | + mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); 502 | + mw = m->ww - 2*ov; 503 | + lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); 504 | + rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); 505 | + 506 | + if (m->nmaster && n > m->nmaster) { 507 | + /* go mfact box in the center if more than nmaster clients */ 508 | + if (n - m->nmaster > 1) { 509 | + /* ||<-S->|<---M--->|<-S->|| */ 510 | + mw = (m->ww - 2*ov - 2*iv) * m->mfact; 511 | + lw = (m->ww - mw - 2*ov - 2*iv) / 2; 512 | + rw = (m->ww - mw - 2*ov - 2*iv) - lw; 513 | + mx += lw + iv; 514 | + } else { 515 | + /* ||<---M--->|<-S->|| */ 516 | + mw = (mw - iv) * m->mfact; 517 | + lw = 0; 518 | + rw = m->ww - mw - iv - 2*ov; 519 | + } 520 | + lx = m->wx + ov; 521 | + ly = m->wy + oh; 522 | + rx = mx + mw + iv; 523 | + ry = m->wy + oh; 524 | + } 525 | + 526 | + /* calculate facts */ 527 | + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { 528 | + if (!m->nmaster || n < m->nmaster) 529 | + mfacts += c->cfact; 530 | + else if ((n - m->nmaster) % 2) 531 | + lfacts += c->cfact; // total factor of left hand stack area 532 | + else 533 | + rfacts += c->cfact; // total factor of right hand stack area 534 | + } 535 | + 536 | + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 537 | + if (!m->nmaster || n < m->nmaster) 538 | + mtotal += mh * (c->cfact / mfacts); 539 | + else if ((n - m->nmaster) % 2) 540 | + ltotal += lh * (c->cfact / lfacts); 541 | + else 542 | + rtotal += rh * (c->cfact / rfacts); 543 | + 544 | + mrest = mh - mtotal; 545 | + lrest = lh - ltotal; 546 | + rrest = rh - rtotal; 547 | + 548 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 549 | + if (!m->nmaster || i < m->nmaster) { 550 | + /* nmaster clients are stacked vertically, in the center of the screen */ 551 | + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 552 | + my += HEIGHT(c) + ih; 553 | + } else { 554 | + /* stack clients are stacked vertically */ 555 | + if ((i - m->nmaster) % 2 ) { 556 | + resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); 557 | + ly += HEIGHT(c) + ih; 558 | + } else { 559 | + resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); 560 | + ry += HEIGHT(c) + ih; 561 | + } 562 | + } 563 | + } 564 | +} 565 | + 566 | +void 567 | +centeredfloatingmaster(Monitor *m) 568 | +{ 569 | + unsigned int i, n; 570 | + float mfacts, sfacts; 571 | + float mivf = 1.0; // master inner vertical gap factor 572 | + int oh, ov, ih, iv, mrest, srest; 573 | + int mx = 0, my = 0, mh = 0, mw = 0; 574 | + int sx = 0, sy = 0, sh = 0, sw = 0; 575 | + Client *c; 576 | + 577 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 578 | + if (n == 0) 579 | + return; 580 | + 581 | + sx = mx = m->wx + ov; 582 | + sy = my = m->wy + oh; 583 | + sh = mh = m->wh - 2*oh; 584 | + mw = m->ww - 2*ov - iv*(n - 1); 585 | + sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); 586 | + 587 | + if (m->nmaster && n > m->nmaster) { 588 | + mivf = 0.8; 589 | + /* go mfact box in the center if more than nmaster clients */ 590 | + if (m->ww > m->wh) { 591 | + mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); 592 | + mh = m->wh * 0.9; 593 | + } else { 594 | + mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); 595 | + mh = m->wh * m->mfact; 596 | + } 597 | + mx = m->wx + (m->ww - mw) / 2; 598 | + my = m->wy + (m->wh - mh - 2*oh) / 2; 599 | + 600 | + sx = m->wx + ov; 601 | + sy = m->wy + oh; 602 | + sh = m->wh - 2*oh; 603 | + } 604 | + 605 | + getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 606 | + 607 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 608 | + if (i < m->nmaster) { 609 | + /* nmaster clients are stacked horizontally, in the center of the screen */ 610 | + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 611 | + mx += WIDTH(c) + iv*mivf; 612 | + } else { 613 | + /* stack clients are stacked horizontally */ 614 | + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 615 | + sx += WIDTH(c) + iv; 616 | + } 617 | +} 618 | + 619 | +/* 620 | + * Deck layout + gaps 621 | + * https://dwm.suckless.org/patches/deck/ 622 | + */ 623 | +void 624 | +deck(Monitor *m) 625 | +{ 626 | + unsigned int i, n; 627 | + int oh, ov, ih, iv; 628 | + int mx = 0, my = 0, mh = 0, mw = 0; 629 | + int sx = 0, sy = 0, sh = 0, sw = 0; 630 | + float mfacts, sfacts; 631 | + int mrest, srest; 632 | + Client *c; 633 | + 634 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 635 | + if (n == 0) 636 | + return; 637 | + 638 | + sx = mx = m->wx + ov; 639 | + sy = my = m->wy + oh; 640 | + sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 641 | + sw = mw = m->ww - 2*ov; 642 | + 643 | + if (m->nmaster && n > m->nmaster) { 644 | + sw = (mw - iv) * (1 - m->mfact); 645 | + mw = mw - iv - sw; 646 | + sx = mx + mw + iv; 647 | + sh = m->wh - 2*oh; 648 | + } 649 | + 650 | + getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 651 | + 652 | + if (n - m->nmaster > 0) /* override layout symbol */ 653 | + snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); 654 | + 655 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 656 | + if (i < m->nmaster) { 657 | + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 658 | + my += HEIGHT(c) + ih; 659 | + } else { 660 | + resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); 661 | + } 662 | +} 663 | + 664 | +/* 665 | + * Fibonacci layout + gaps 666 | + * https://dwm.suckless.org/patches/fibonacci/ 667 | + */ 668 | +void 669 | +fibonacci(Monitor *m, int s) 670 | +{ 671 | + unsigned int i, n; 672 | + int nx, ny, nw, nh; 673 | + int oh, ov, ih, iv; 674 | + int nv, hrest = 0, wrest = 0, r = 1; 675 | + Client *c; 676 | + 677 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 678 | + if (n == 0) 679 | + return; 680 | + 681 | + nx = m->wx + ov; 682 | + ny = m->wy + oh; 683 | + nw = m->ww - 2*ov; 684 | + nh = m->wh - 2*oh; 685 | + 686 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { 687 | + if (r) { 688 | + if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) 689 | + || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { 690 | + r = 0; 691 | + } 692 | + if (r && i < n - 1) { 693 | + if (i % 2) { 694 | + nv = (nh - ih) / 2; 695 | + hrest = nh - 2*nv - ih; 696 | + nh = nv; 697 | + } else { 698 | + nv = (nw - iv) / 2; 699 | + wrest = nw - 2*nv - iv; 700 | + nw = nv; 701 | + } 702 | + 703 | + if ((i % 4) == 2 && !s) 704 | + nx += nw + iv; 705 | + else if ((i % 4) == 3 && !s) 706 | + ny += nh + ih; 707 | + } 708 | + 709 | + if ((i % 4) == 0) { 710 | + if (s) { 711 | + ny += nh + ih; 712 | + nh += hrest; 713 | + } 714 | + else { 715 | + nh -= hrest; 716 | + ny -= nh + ih; 717 | + } 718 | + } 719 | + else if ((i % 4) == 1) { 720 | + nx += nw + iv; 721 | + nw += wrest; 722 | + } 723 | + else if ((i % 4) == 2) { 724 | + ny += nh + ih; 725 | + nh += hrest; 726 | + if (i < n - 1) 727 | + nw += wrest; 728 | + } 729 | + else if ((i % 4) == 3) { 730 | + if (s) { 731 | + nx += nw + iv; 732 | + nw -= wrest; 733 | + } else { 734 | + nw -= wrest; 735 | + nx -= nw + iv; 736 | + nh += hrest; 737 | + } 738 | + } 739 | + if (i == 0) { 740 | + if (n != 1) { 741 | + nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); 742 | + wrest = 0; 743 | + } 744 | + ny = m->wy + oh; 745 | + } 746 | + else if (i == 1) 747 | + nw = m->ww - nw - iv - 2*ov; 748 | + i++; 749 | + } 750 | + 751 | + resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); 752 | + } 753 | +} 754 | + 755 | +void 756 | +dwindle(Monitor *m) 757 | +{ 758 | + fibonacci(m, 1); 759 | +} 760 | + 761 | +void 762 | +spiral(Monitor *m) 763 | +{ 764 | + fibonacci(m, 0); 765 | +} 766 | + 767 | +/* 768 | + * Gappless grid layout + gaps (ironically) 769 | + * https://dwm.suckless.org/patches/gaplessgrid/ 770 | + */ 771 | +void 772 | +gaplessgrid(Monitor *m) 773 | +{ 774 | + unsigned int i, n; 775 | + int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters 776 | + int oh, ov, ih, iv; 777 | + Client *c; 778 | + 779 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 780 | + if (n == 0) 781 | + return; 782 | + 783 | + /* grid dimensions */ 784 | + for (cols = 0; cols <= n/2; cols++) 785 | + if (cols*cols >= n) 786 | + break; 787 | + if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ 788 | + cols = 2; 789 | + rows = n/cols; 790 | + cn = rn = 0; // reset column no, row no, client count 791 | + 792 | + ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 793 | + cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; 794 | + rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 795 | + crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 796 | + x = m->wx + ov; 797 | + y = m->wy + oh; 798 | + 799 | + for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { 800 | + if (i/rows + 1 > cols - n%cols) { 801 | + rows = n/cols + 1; 802 | + ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 803 | + rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 804 | + } 805 | + resize(c, 806 | + x, 807 | + y + rn*(ch + ih) + MIN(rn, rrest), 808 | + cw + (cn < crest ? 1 : 0) - 2*c->bw, 809 | + ch + (rn < rrest ? 1 : 0) - 2*c->bw, 810 | + 0); 811 | + rn++; 812 | + if (rn >= rows) { 813 | + rn = 0; 814 | + x += cw + ih + (cn < crest ? 1 : 0); 815 | + cn++; 816 | + } 817 | + } 818 | +} 819 | + 820 | +/* 821 | + * Gridmode layout + gaps 822 | + * https://dwm.suckless.org/patches/gridmode/ 823 | + */ 824 | +void 825 | +grid(Monitor *m) 826 | +{ 827 | + unsigned int i, n; 828 | + int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; 829 | + int oh, ov, ih, iv; 830 | + Client *c; 831 | + 832 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 833 | + 834 | + /* grid dimensions */ 835 | + for (rows = 0; rows <= n/2; rows++) 836 | + if (rows*rows >= n) 837 | + break; 838 | + cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; 839 | + 840 | + /* window geoms (cell height/width) */ 841 | + ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); 842 | + cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); 843 | + chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 844 | + cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 845 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 846 | + cc = i / rows; 847 | + cr = i % rows; 848 | + cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); 849 | + cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); 850 | + resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); 851 | + } 852 | +} 853 | + 854 | +/* 855 | + * Horizontal grid layout + gaps 856 | + * https://dwm.suckless.org/patches/horizgrid/ 857 | + */ 858 | +void 859 | +horizgrid(Monitor *m) { 860 | + Client *c; 861 | + unsigned int n, i; 862 | + int oh, ov, ih, iv; 863 | + int mx = 0, my = 0, mh = 0, mw = 0; 864 | + int sx = 0, sy = 0, sh = 0, sw = 0; 865 | + int ntop, nbottom = 1; 866 | + float mfacts = 0, sfacts = 0; 867 | + int mrest, srest, mtotal = 0, stotal = 0; 868 | + 869 | + /* Count windows */ 870 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 871 | + if (n == 0) 872 | + return; 873 | + 874 | + if (n <= 2) 875 | + ntop = n; 876 | + else { 877 | + ntop = n / 2; 878 | + nbottom = n - ntop; 879 | + } 880 | + sx = mx = m->wx + ov; 881 | + sy = my = m->wy + oh; 882 | + sh = mh = m->wh - 2*oh; 883 | + sw = mw = m->ww - 2*ov; 884 | + 885 | + if (n > ntop) { 886 | + sh = (mh - ih) / 2; 887 | + mh = mh - ih - sh; 888 | + sy = my + mh + ih; 889 | + mw = m->ww - 2*ov - iv * (ntop - 1); 890 | + sw = m->ww - 2*ov - iv * (nbottom - 1); 891 | + } 892 | + 893 | + /* calculate facts */ 894 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 895 | + if (i < ntop) 896 | + mfacts += c->cfact; 897 | + else 898 | + sfacts += c->cfact; 899 | + 900 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 901 | + if (i < ntop) 902 | + mtotal += mh * (c->cfact / mfacts); 903 | + else 904 | + stotal += sw * (c->cfact / sfacts); 905 | + 906 | + mrest = mh - mtotal; 907 | + srest = sw - stotal; 908 | + 909 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 910 | + if (i < ntop) { 911 | + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 912 | + mx += WIDTH(c) + iv; 913 | + } else { 914 | + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 915 | + sx += WIDTH(c) + iv; 916 | + } 917 | +} 918 | + 919 | +/* 920 | + * nrowgrid layout + gaps 921 | + * https://dwm.suckless.org/patches/nrowgrid/ 922 | + */ 923 | +void 924 | +nrowgrid(Monitor *m) 925 | +{ 926 | + unsigned int n; 927 | + int ri = 0, ci = 0; /* counters */ 928 | + int oh, ov, ih, iv; /* vanitygap settings */ 929 | + unsigned int cx, cy, cw, ch; /* client geometry */ 930 | + unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ 931 | + unsigned int cols, rows = m->nmaster + 1; 932 | + Client *c; 933 | + 934 | + /* count clients */ 935 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 936 | + 937 | + /* nothing to do here */ 938 | + if (n == 0) 939 | + return; 940 | + 941 | + /* force 2 clients to always split vertically */ 942 | + if (FORCE_VSPLIT && n == 2) 943 | + rows = 1; 944 | + 945 | + /* never allow empty rows */ 946 | + if (n < rows) 947 | + rows = n; 948 | + 949 | + /* define first row */ 950 | + cols = n / rows; 951 | + uc = cols; 952 | + cy = m->wy + oh; 953 | + ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; 954 | + uh = ch; 955 | + 956 | + for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) { 957 | + if (ci == cols) { 958 | + uw = 0; 959 | + ci = 0; 960 | + ri++; 961 | + 962 | + /* next row */ 963 | + cols = (n - uc) / (rows - ri); 964 | + uc += cols; 965 | + cy = m->wy + oh + uh + ih; 966 | + uh += ch + ih; 967 | + } 968 | + 969 | + cx = m->wx + ov + uw; 970 | + cw = (m->ww - 2*ov - uw) / (cols - ci); 971 | + uw += cw + iv; 972 | + 973 | + resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); 974 | + } 975 | +} 976 | + 977 | +/* 978 | + * Default tile layout + gaps 979 | + */ 980 | +static void 981 | +tile(Monitor *m) 982 | +{ 983 | + unsigned int i, n; 984 | + int oh, ov, ih, iv; 985 | + int mx = 0, my = 0, mh = 0, mw = 0; 986 | + int sx = 0, sy = 0, sh = 0, sw = 0; 987 | + float mfacts, sfacts; 988 | + int mrest, srest; 989 | + Client *c; 990 | + 991 | + getgaps(m, &oh, &ov, &ih, &iv, &n); 992 | + if (n == 0) 993 | + return; 994 | + 995 | + sx = mx = m->wx + ov; 996 | + sy = my = m->wy + oh; 997 | + mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 998 | + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 999 | + sw = mw = m->ww - 2*ov; 1000 | + 1001 | + if (m->nmaster && n > m->nmaster) { 1002 | + sw = (mw - iv) * (1 - m->mfact); 1003 | + mw = mw - iv - sw; 1004 | + sx = mx + mw + iv; 1005 | + } 1006 | + 1007 | + getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 1008 | + 1009 | + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 1010 | + if (i < m->nmaster) { 1011 | + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 1012 | + my += HEIGHT(c) + ih; 1013 | + } else { 1014 | + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 1015 | + sy += HEIGHT(c) + ih; 1016 | + } 1017 | +} 1018 | \ No newline at end of file 1019 | -------------------------------------------------------------------------------- /patches/dwm-movestack-20211115-a786211.diff: -------------------------------------------------------------------------------- 1 | From 9a4037dc0ef56f91c009317e78e9e3790dafbb58 Mon Sep 17 00:00:00 2001 2 | From: BrunoCooper17 3 | Date: Mon, 15 Nov 2021 14:04:53 -0600 4 | Subject: [PATCH] MoveStack patch 5 | 6 | This plugin allows you to move clients around in the stack and swap them 7 | with the master. It emulates the behavior off mod+shift+j and mod+shift+k 8 | in Xmonad. movestack(+1) will swap the client with the current focus with 9 | the next client. movestack(-1) will swap the client with the current focus 10 | with the previous client. 11 | --- 12 | config.def.h | 3 +++ 13 | movestack.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 14 | 2 files changed, 51 insertions(+) 15 | create mode 100644 movestack.c 16 | 17 | diff --git a/config.def.h b/config.def.h 18 | index a2ac963..33efa5b 100644 19 | --- a/config.def.h 20 | +++ b/config.def.h 21 | @@ -60,6 +60,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() 22 | static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; 23 | static const char *termcmd[] = { "st", NULL }; 24 | 25 | +#include "movestack.c" 26 | static Key keys[] = { 27 | /* modifier key function argument */ 28 | { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 29 | @@ -71,6 +72,8 @@ static Key keys[] = { 30 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, 31 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, 32 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, 33 | + { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, 34 | + { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, 35 | { MODKEY, XK_Return, zoom, {0} }, 36 | { MODKEY, XK_Tab, view, {0} }, 37 | { MODKEY|ShiftMask, XK_c, killclient, {0} }, 38 | diff --git a/movestack.c b/movestack.c 39 | new file mode 100644 40 | index 0000000..520f4ae 41 | --- /dev/null 42 | +++ b/movestack.c 43 | @@ -0,0 +1,48 @@ 44 | +void 45 | +movestack(const Arg *arg) { 46 | + Client *c = NULL, *p = NULL, *pc = NULL, *i; 47 | + 48 | + if(arg->i > 0) { 49 | + /* find the client after selmon->sel */ 50 | + for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 51 | + if(!c) 52 | + for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 53 | + 54 | + } 55 | + else { 56 | + /* find the client before selmon->sel */ 57 | + for(i = selmon->clients; i != selmon->sel; i = i->next) 58 | + if(ISVISIBLE(i) && !i->isfloating) 59 | + c = i; 60 | + if(!c) 61 | + for(; i; i = i->next) 62 | + if(ISVISIBLE(i) && !i->isfloating) 63 | + c = i; 64 | + } 65 | + /* find the client before selmon->sel and c */ 66 | + for(i = selmon->clients; i && (!p || !pc); i = i->next) { 67 | + if(i->next == selmon->sel) 68 | + p = i; 69 | + if(i->next == c) 70 | + pc = i; 71 | + } 72 | + 73 | + /* swap c and selmon->sel selmon->clients in the selmon->clients list */ 74 | + if(c && c != selmon->sel) { 75 | + Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; 76 | + selmon->sel->next = c->next==selmon->sel?c:c->next; 77 | + c->next = temp; 78 | + 79 | + if(p && p != c) 80 | + p->next = c; 81 | + if(pc && pc != selmon->sel) 82 | + pc->next = selmon->sel; 83 | + 84 | + if(selmon->sel == selmon->clients) 85 | + selmon->clients = c; 86 | + else if(c == selmon->clients) 87 | + selmon->clients = selmon->sel; 88 | + 89 | + arrange(selmon); 90 | + } 91 | +} 92 | \ No newline at end of file 93 | -- 94 | 2.33.1 95 | 96 | -------------------------------------------------------------------------------- /patches/dwm-pertag_with_sel-20231003-9f88553.diff: -------------------------------------------------------------------------------- 1 | From b47a32da69a1bb6f60b9c81619f3e504278cc780 Mon Sep 17 00:00:00 2001 2 | From: Leonardo-Boss <70913810+Leonardo-Boss@users.noreply.github.com> 3 | Date: Tue, 3 Oct 2023 12:33:58 -0300 4 | Subject: [PATCH] pertag with last selection 5 | 6 | --- 7 | dwm.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 8 | 1 file changed, 90 insertions(+), 7 deletions(-) 9 | 10 | diff --git a/dwm.c b/dwm.c 11 | index f1d86b2..0e4d444 100644 12 | --- a/dwm.c 13 | +++ b/dwm.c 14 | @@ -111,6 +111,7 @@ typedef struct { 15 | void (*arrange)(Monitor *); 16 | } Layout; 17 | 18 | +typedef struct Pertag Pertag; 19 | struct Monitor { 20 | char ltsymbol[16]; 21 | float mfact; 22 | @@ -130,6 +131,7 @@ struct Monitor { 23 | Monitor *next; 24 | Window barwin; 25 | const Layout *lt[2]; 26 | + Pertag *pertag; 27 | }; 28 | 29 | typedef struct { 30 | @@ -271,6 +273,16 @@ static Window root, wmcheckwin; 31 | /* configuration, allows nested code to access above variables */ 32 | #include "config.h" 33 | 34 | +struct Pertag { 35 | + unsigned int curtag, prevtag; /* current and previous tag */ 36 | + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ 37 | + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ 38 | + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ 39 | + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ 40 | + int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ 41 | + Client *sel[LENGTH(tags) + 1]; /* selected client */ 42 | +}; 43 | + 44 | /* compile-time check if all tags fit into an unsigned int bit array. */ 45 | struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 46 | 47 | @@ -634,6 +646,7 @@ Monitor * 48 | createmon(void) 49 | { 50 | Monitor *m; 51 | + unsigned int i; 52 | 53 | m = ecalloc(1, sizeof(Monitor)); 54 | m->tagset[0] = m->tagset[1] = 1; 55 | @@ -644,6 +657,20 @@ createmon(void) 56 | m->lt[0] = &layouts[0]; 57 | m->lt[1] = &layouts[1 % LENGTH(layouts)]; 58 | strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 59 | + m->pertag = ecalloc(1, sizeof(Pertag)); 60 | + m->pertag->curtag = m->pertag->prevtag = 1; 61 | + 62 | + for (i = 0; i <= LENGTH(tags); i++) { 63 | + m->pertag->nmasters[i] = m->nmaster; 64 | + m->pertag->mfacts[i] = m->mfact; 65 | + 66 | + m->pertag->ltidxs[i][0] = m->lt[0]; 67 | + m->pertag->ltidxs[i][1] = m->lt[1]; 68 | + m->pertag->sellts[i] = m->sellt; 69 | + 70 | + m->pertag->showbars[i] = m->showbar; 71 | + } 72 | + 73 | return m; 74 | } 75 | 76 | @@ -808,6 +835,7 @@ focus(Client *c) 77 | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); 78 | } 79 | selmon->sel = c; 80 | + selmon->pertag->sel[selmon->pertag->curtag] = c; 81 | drawbars(); 82 | } 83 | 84 | @@ -980,7 +1008,7 @@ grabkeys(void) 85 | void 86 | incnmaster(const Arg *arg) 87 | { 88 | - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 89 | + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); 90 | arrange(selmon); 91 | } 92 | 93 | @@ -1511,9 +1539,9 @@ void 94 | setlayout(const Arg *arg) 95 | { 96 | if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 97 | - selmon->sellt ^= 1; 98 | + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; 99 | if (arg && arg->v) 100 | - selmon->lt[selmon->sellt] = (Layout *)arg->v; 101 | + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; 102 | strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 103 | if (selmon->sel) 104 | arrange(selmon); 105 | @@ -1532,7 +1560,7 @@ setmfact(const Arg *arg) 106 | f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 107 | if (f < 0.05 || f > 0.95) 108 | return; 109 | - selmon->mfact = f; 110 | + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; 111 | arrange(selmon); 112 | } 113 | 114 | @@ -1715,7 +1743,7 @@ tile(Monitor *m) 115 | void 116 | togglebar(const Arg *arg) 117 | { 118 | - selmon->showbar = !selmon->showbar; 119 | + selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; 120 | updatebarpos(selmon); 121 | XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 122 | arrange(selmon); 123 | @@ -1754,9 +1782,33 @@ void 124 | toggleview(const Arg *arg) 125 | { 126 | unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 127 | + int i; 128 | 129 | if (newtagset) { 130 | selmon->tagset[selmon->seltags] = newtagset; 131 | + 132 | + if (newtagset == ~0) { 133 | + selmon->pertag->prevtag = selmon->pertag->curtag; 134 | + selmon->pertag->curtag = 0; 135 | + } 136 | + 137 | + /* test if the user did not select the same tag */ 138 | + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { 139 | + selmon->pertag->prevtag = selmon->pertag->curtag; 140 | + for (i = 0; !(newtagset & 1 << i); i++) ; 141 | + selmon->pertag->curtag = i + 1; 142 | + } 143 | + 144 | + /* apply settings for this view */ 145 | + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 146 | + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 147 | + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 148 | + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 149 | + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 150 | + 151 | + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) 152 | + togglebar(NULL); 153 | + 154 | focus(NULL); 155 | arrange(selmon); 156 | } 157 | @@ -1778,9 +1830,14 @@ unfocus(Client *c, int setfocus) 158 | void 159 | unmanage(Client *c, int destroyed) 160 | { 161 | + int i; 162 | Monitor *m = c->mon; 163 | XWindowChanges wc; 164 | 165 | + for (i = 0; i < LENGTH(tags) + 1; i++) 166 | + if (c->mon->pertag->sel[i] == c) 167 | + c->mon->pertag->sel[i] = NULL; 168 | + 169 | detach(c); 170 | detachstack(c); 171 | if (!destroyed) { 172 | @@ -2053,12 +2110,38 @@ updatewmhints(Client *c) 173 | void 174 | view(const Arg *arg) 175 | { 176 | + int i; 177 | + unsigned int tmptag; 178 | + 179 | if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 180 | return; 181 | selmon->seltags ^= 1; /* toggle sel tagset */ 182 | - if (arg->ui & TAGMASK) 183 | + if (arg->ui & TAGMASK) { 184 | selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 185 | - focus(NULL); 186 | + selmon->pertag->prevtag = selmon->pertag->curtag; 187 | + 188 | + if (arg->ui == ~0) 189 | + selmon->pertag->curtag = 0; 190 | + else { 191 | + for (i = 0; !(arg->ui & 1 << i); i++) ; 192 | + selmon->pertag->curtag = i + 1; 193 | + } 194 | + } else { 195 | + tmptag = selmon->pertag->prevtag; 196 | + selmon->pertag->prevtag = selmon->pertag->curtag; 197 | + selmon->pertag->curtag = tmptag; 198 | + } 199 | + 200 | + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 201 | + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 202 | + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 203 | + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 204 | + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 205 | + 206 | + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) 207 | + togglebar(NULL); 208 | + 209 | + focus(selmon->pertag->sel[selmon->pertag->curtag]); 210 | arrange(selmon); 211 | } 212 | 213 | -- 214 | 2.41.0 215 | 216 | -------------------------------------------------------------------------------- /patches/dwm-resizehere-20230824-e81f17d.diff: -------------------------------------------------------------------------------- 1 | From d2824944615917697c18555a397bf84f2249a722 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Gutyina=20Gerg=C5=91?= 3 | Date: Thu, 24 Aug 2023 15:06:56 +0200 4 | Subject: [PATCH] Resize clients without wrapping the pointer 5 | 6 | --- 7 | dwm.c | 14 +++++++------- 8 | 1 file changed, 7 insertions(+), 7 deletions(-) 9 | 10 | diff --git a/dwm.c b/dwm.c 11 | index f1d86b2..8c661a2 100644 12 | --- a/dwm.c 13 | +++ b/dwm.c 14 | @@ -1300,7 +1300,7 @@ resizeclient(Client *c, int x, int y, int w, int h) 15 | void 16 | resizemouse(const Arg *arg) 17 | { 18 | - int ocx, ocy, nw, nh; 19 | + int x, y, ocw, och, nw, nh; 20 | Client *c; 21 | Monitor *m; 22 | XEvent ev; 23 | @@ -1311,12 +1311,13 @@ resizemouse(const Arg *arg) 24 | if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ 25 | return; 26 | restack(selmon); 27 | - ocx = c->x; 28 | - ocy = c->y; 29 | + ocw = c->w; 30 | + och = c->h; 31 | if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, 32 | None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) 33 | return; 34 | - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 35 | + if(!getrootptr(&x, &y)) 36 | + return; 37 | do { 38 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); 39 | switch(ev.type) { 40 | @@ -1330,8 +1331,8 @@ resizemouse(const Arg *arg) 41 | continue; 42 | lasttime = ev.xmotion.time; 43 | 44 | - nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); 45 | - nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); 46 | + nw = MAX(ocw + (ev.xmotion.x - x), 1); 47 | + nh = MAX(och + (ev.xmotion.y - y), 1); 48 | if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww 49 | && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) 50 | { 51 | @@ -1344,7 +1345,6 @@ resizemouse(const Arg *arg) 52 | break; 53 | } 54 | } while (ev.type != ButtonRelease); 55 | - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 56 | XUngrabPointer(dpy, CurrentTime); 57 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 58 | if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 59 | -- 60 | 2.41.0 61 | 62 | -------------------------------------------------------------------------------- /patches/dwm-setborderpx-6.2.diff: -------------------------------------------------------------------------------- 1 | diff -up a/config.def.h b/config.def.h 2 | --- a/config.def.h 2020-05-12 02:17:20.070933833 +0200 3 | +++ b/config.def.h 2020-05-13 03:27:51.018695798 +0200 4 | @@ -84,6 +84,9 @@ static Key keys[] = { 5 | { MODKEY, XK_period, focusmon, {.i = +1 } }, 6 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, 7 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, 8 | + { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } }, 9 | + { MODKEY|ShiftMask, XK_plus, setborderpx, {.i = +1 } }, 10 | + { MODKEY|ShiftMask, XK_numbersign, setborderpx, {.i = 0 } }, 11 | TAGKEYS( XK_1, 0) 12 | TAGKEYS( XK_2, 1) 13 | TAGKEYS( XK_3, 2) 14 | diff -up a/dwm.c b/dwm.c 15 | --- a/dwm.c 2020-05-12 02:17:20.070933833 +0200 16 | +++ b/dwm.c 2020-05-14 00:17:35.047919771 +0200 17 | @@ -119,6 +119,7 @@ struct Monitor { 18 | int by; /* bar geometry */ 19 | int mx, my, mw, mh; /* screen size */ 20 | int wx, wy, ww, wh; /* window area */ 21 | + unsigned int borderpx; 22 | unsigned int seltags; 23 | unsigned int sellt; 24 | unsigned int tagset[2]; 25 | @@ -196,6 +197,7 @@ static void run(void); 26 | static void scan(void); 27 | static int sendevent(Client *c, Atom proto); 28 | static void sendmon(Client *c, Monitor *m); 29 | +static void setborderpx(const Arg *arg); 30 | static void setclientstate(Client *c, long state); 31 | static void setfocus(Client *c); 32 | static void setfullscreen(Client *c, int fullscreen); 33 | @@ -638,6 +640,7 @@ createmon(void) 34 | m->nmaster = nmaster; 35 | m->showbar = showbar; 36 | m->topbar = topbar; 37 | + m->borderpx = borderpx; 38 | m->lt[0] = &layouts[0]; 39 | m->lt[1] = &layouts[1 % LENGTH(layouts)]; 40 | strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 41 | @@ -1047,7 +1050,7 @@ manage(Window w, XWindowAttributes *wa) 42 | /* only fix client y-offset, if the client center might cover the bar */ 43 | c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) 44 | && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); 45 | - c->bw = borderpx; 46 | + c->bw = c->mon->borderpx; 47 | 48 | wc.border_width = c->bw; 49 | XConfigureWindow(dpy, w, CWBorderWidth, &wc); 50 | @@ -1424,6 +1427,40 @@ sendmon(Client *c, Monitor *m) 51 | } 52 | 53 | void 54 | +setborderpx(const Arg *arg) 55 | +{ 56 | + Client *c; 57 | + int prev_borderpx = selmon->borderpx; 58 | + 59 | + if (arg->i == 0) 60 | + selmon->borderpx = borderpx; 61 | + else if (selmon->borderpx + arg->i < 0) 62 | + selmon->borderpx = 0; 63 | + else 64 | + selmon->borderpx += arg->i; 65 | + 66 | + for (c = selmon->clients; c; c = c->next) 67 | + { 68 | + if (c->bw + arg->i < 0) 69 | + c->bw = selmon->borderpx = 0; 70 | + else 71 | + c->bw = selmon->borderpx; 72 | + if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) 73 | + { 74 | + if (arg->i != 0 && prev_borderpx + arg->i >= 0) 75 | + resize(c, c->x, c->y, c->w-(arg->i*2), c->h-(arg->i*2), 0); 76 | + else if (arg->i != 0) 77 | + resizeclient(c, c->x, c->y, c->w, c->h); 78 | + else if (prev_borderpx > borderpx) 79 | + resize(c, c->x, c->y, c->w + 2*(prev_borderpx - borderpx), c->h + 2*(prev_borderpx - borderpx), 0); 80 | + else if (prev_borderpx < borderpx) 81 | + resize(c, c->x, c->y, c->w-2*(borderpx - prev_borderpx), c->h-2*(borderpx - prev_borderpx), 0); 82 | + } 83 | + } 84 | + arrange(selmon); 85 | +} 86 | + 87 | +void 88 | setclientstate(Client *c, long state) 89 | { 90 | long data[] = { state, None }; 91 | -------------------------------------------------------------------------------- /patches/dwm-status2d-6.3.diff: -------------------------------------------------------------------------------- 1 | diff --git a/dwm.c b/dwm.c 2 | index a96f33c..24b1eeb 100644 3 | --- a/dwm.c 4 | +++ b/dwm.c 5 | @@ -163,6 +163,7 @@ static void detachstack(Client *c); 6 | static Monitor *dirtomon(int dir); 7 | static void drawbar(Monitor *m); 8 | static void drawbars(void); 9 | +static int drawstatusbar(Monitor *m, int bh, char* text); 10 | static void enternotify(XEvent *e); 11 | static void expose(XEvent *e); 12 | static void focus(Client *c); 13 | @@ -237,7 +238,7 @@ static void zoom(const Arg *arg); 14 | 15 | /* variables */ 16 | static const char broken[] = "broken"; 17 | -static char stext[256]; 18 | +static char stext[1024]; 19 | static int screen; 20 | static int sw, sh; /* X display screen geometry width, height */ 21 | static int bh, blw = 0; /* bar geometry */ 22 | @@ -485,7 +486,7 @@ cleanup(void) 23 | cleanupmon(mons); 24 | for (i = 0; i < CurLast; i++) 25 | drw_cur_free(drw, cursor[i]); 26 | - for (i = 0; i < LENGTH(colors); i++) 27 | + for (i = 0; i < LENGTH(colors) + 1; i++) 28 | free(scheme[i]); 29 | XDestroyWindow(dpy, wmcheckwin); 30 | drw_free(drw); 31 | @@ -693,6 +694,114 @@ dirtomon(int dir) 32 | return m; 33 | } 34 | 35 | +int 36 | +drawstatusbar(Monitor *m, int bh, char* stext) { 37 | + int ret, i, w, x, len; 38 | + short isCode = 0; 39 | + char *text; 40 | + char *p; 41 | + 42 | + len = strlen(stext) + 1 ; 43 | + if (!(text = (char*) malloc(sizeof(char)*len))) 44 | + die("malloc"); 45 | + p = text; 46 | + memcpy(text, stext, len); 47 | + 48 | + /* compute width of the status text */ 49 | + w = 0; 50 | + i = -1; 51 | + while (text[++i]) { 52 | + if (text[i] == '^') { 53 | + if (!isCode) { 54 | + isCode = 1; 55 | + text[i] = '\0'; 56 | + w += TEXTW(text) - lrpad; 57 | + text[i] = '^'; 58 | + if (text[++i] == 'f') 59 | + w += atoi(text + ++i); 60 | + } else { 61 | + isCode = 0; 62 | + text = text + i + 1; 63 | + i = -1; 64 | + } 65 | + } 66 | + } 67 | + if (!isCode) 68 | + w += TEXTW(text) - lrpad; 69 | + else 70 | + isCode = 0; 71 | + text = p; 72 | + 73 | + w += 2; /* 1px padding on both sides */ 74 | + ret = x = m->ww - w; 75 | + 76 | + drw_setscheme(drw, scheme[LENGTH(colors)]); 77 | + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; 78 | + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; 79 | + drw_rect(drw, x, 0, w, bh, 1, 1); 80 | + x++; 81 | + 82 | + /* process status text */ 83 | + i = -1; 84 | + while (text[++i]) { 85 | + if (text[i] == '^' && !isCode) { 86 | + isCode = 1; 87 | + 88 | + text[i] = '\0'; 89 | + w = TEXTW(text) - lrpad; 90 | + drw_text(drw, x, 0, w, bh, 0, text, 0); 91 | + 92 | + x += w; 93 | + 94 | + /* process code */ 95 | + while (text[++i] != '^') { 96 | + if (text[i] == 'c') { 97 | + char buf[8]; 98 | + memcpy(buf, (char*)text+i+1, 7); 99 | + buf[7] = '\0'; 100 | + drw_clr_create(drw, &drw->scheme[ColFg], buf); 101 | + i += 7; 102 | + } else if (text[i] == 'b') { 103 | + char buf[8]; 104 | + memcpy(buf, (char*)text+i+1, 7); 105 | + buf[7] = '\0'; 106 | + drw_clr_create(drw, &drw->scheme[ColBg], buf); 107 | + i += 7; 108 | + } else if (text[i] == 'd') { 109 | + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; 110 | + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; 111 | + } else if (text[i] == 'r') { 112 | + int rx = atoi(text + ++i); 113 | + while (text[++i] != ','); 114 | + int ry = atoi(text + ++i); 115 | + while (text[++i] != ','); 116 | + int rw = atoi(text + ++i); 117 | + while (text[++i] != ','); 118 | + int rh = atoi(text + ++i); 119 | + 120 | + drw_rect(drw, rx + x, ry, rw, rh, 1, 0); 121 | + } else if (text[i] == 'f') { 122 | + x += atoi(text + ++i); 123 | + } 124 | + } 125 | + 126 | + text = text + i + 1; 127 | + i=-1; 128 | + isCode = 0; 129 | + } 130 | + } 131 | + 132 | + if (!isCode) { 133 | + w = TEXTW(text) - lrpad; 134 | + drw_text(drw, x, 0, w, bh, 0, text, 0); 135 | + } 136 | + 137 | + drw_setscheme(drw, scheme[SchemeNorm]); 138 | + free(p); 139 | + 140 | + return ret; 141 | +} 142 | + 143 | void 144 | drawbar(Monitor *m) 145 | { 146 | @@ -707,9 +816,7 @@ drawbar(Monitor *m) 147 | 148 | /* draw status first so it can be overdrawn by tags later */ 149 | if (m == selmon) { /* status is only drawn on selected monitor */ 150 | - drw_setscheme(drw, scheme[SchemeNorm]); 151 | - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 152 | - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); 153 | + tw = m->ww - drawstatusbar(m, bh, stext); 154 | } 155 | 156 | for (c = m->clients; c; c = c->next) { 157 | @@ -1571,7 +1678,8 @@ setup(void) 158 | cursor[CurResize] = drw_cur_create(drw, XC_sizing); 159 | cursor[CurMove] = drw_cur_create(drw, XC_fleur); 160 | /* init appearance */ 161 | - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); 162 | + scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); 163 | + scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); 164 | for (i = 0; i < LENGTH(colors); i++) 165 | scheme[i] = drw_scm_create(drw, colors[i], 3); 166 | /* init bars */ 167 | -------------------------------------------------------------------------------- /patches/dwm-statusallmons-6.2.diff: -------------------------------------------------------------------------------- 1 | diff -up a/dwm.c b/dwm.c 2 | --- a/dwm.c 2020-07-09 16:49:10.023585649 +0200 3 | +++ b/dwm.c 2020-07-09 16:49:43.497542191 +0200 4 | @@ -702,7 +702,7 @@ drawbar(Monitor *m) 5 | Client *c; 6 | 7 | /* draw status first so it can be overdrawn by tags later */ 8 | - if (m == selmon) { /* status is only drawn on selected monitor */ 9 | + if (m == selmon || 1) { /* status is only drawn on selected monitor */ 10 | drw_setscheme(drw, scheme[SchemeNorm]); 11 | sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 12 | drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); 13 | @@ -1987,9 +1987,11 @@ updatesizehints(Client *c) 14 | void 15 | updatestatus(void) 16 | { 17 | + Monitor* m; 18 | if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 19 | strcpy(stext, "dwm-"VERSION); 20 | - drawbar(selmon); 21 | + for(m = mons; m; m = m->next) 22 | + drawbar(m); 23 | } 24 | 25 | void 26 | -------------------------------------------------------------------------------- /patches/dwm-tiledmove-20231210-b731.diff: -------------------------------------------------------------------------------- 1 | From 427c5fef13676179621949f0a8a4036e49d4b74e Mon Sep 17 00:00:00 2001 2 | From: Niki <> 3 | Date: Sun, 10 Dec 2023 00:29:59 +0000 4 | Subject: [PATCH] The function `movemouse` now doesn't force clients to be 5 | floating. 6 | 7 | Tiling clients when moved will swap with any existing clients that 8 | overlap with the cursor, and snap to other monitors. 9 | --- 10 | dwm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 11 | 1 file changed, 53 insertions(+), 3 deletions(-) 12 | 13 | diff --git a/dwm.c b/dwm.c 14 | index d12be2d..b1023e0 100644 15 | --- a/dwm.c 16 | +++ b/dwm.c 17 | @@ -1189,11 +1189,60 @@ movemouse(const Arg *arg) 18 | ny = selmon->wy; 19 | else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) 20 | ny = selmon->wy + selmon->wh - HEIGHT(c); 21 | - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange 22 | - && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) 23 | - togglefloating(NULL); 24 | if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) 25 | resize(c, nx, ny, c->w, c->h, 1); 26 | + else if (selmon->lt[selmon->sellt]->arrange || !c->isfloating) { 27 | + if ((m = recttomon(ev.xmotion.x_root, ev.xmotion.y_root, 1, 1)) != selmon) { 28 | + sendmon(c, m); 29 | + selmon = m; 30 | + focus(NULL); 31 | + } 32 | + 33 | + Client *cc = c->mon->clients; 34 | + while (1) { 35 | + if (cc == 0) break; 36 | + if( 37 | + cc != c && !cc->isfloating && ISVISIBLE(cc) && 38 | + ev.xmotion.x_root > cc->x && 39 | + ev.xmotion.x_root < cc->x + cc->w && 40 | + ev.xmotion.y_root > cc->y && 41 | + ev.xmotion.y_root < cc->y + cc->h ) { 42 | + break; 43 | + } 44 | + 45 | + cc = cc->next; 46 | + } 47 | + 48 | + if (cc) { 49 | + Client *cl1, *cl2, ocl1; 50 | + 51 | + if (!selmon->lt[selmon->sellt]->arrange) return; 52 | + 53 | + cl1 = c; 54 | + cl2 = cc; 55 | + ocl1 = *cl1; 56 | + strcpy(cl1->name, cl2->name); 57 | + cl1->win = cl2->win; 58 | + cl1->x = cl2->x; 59 | + cl1->y = cl2->y; 60 | + cl1->w = cl2->w; 61 | + cl1->h = cl2->h; 62 | + 63 | + cl2->win = ocl1.win; 64 | + strcpy(cl2->name, ocl1.name); 65 | + cl2->x = ocl1.x; 66 | + cl2->y = ocl1.y; 67 | + cl2->w = ocl1.w; 68 | + cl2->h = ocl1.h; 69 | + 70 | + selmon->sel = cl2; 71 | + 72 | + c = cc; 73 | + focus(c); 74 | + 75 | + arrange(cl1->mon); 76 | + } 77 | + } 78 | break; 79 | } 80 | } while (ev.type != ButtonRelease); 81 | -- 82 | 2.43.0 83 | 84 | -------------------------------------------------------------------------------- /patches/dwm-unfloatvisible-6.2.diff: -------------------------------------------------------------------------------- 1 | From a972569532c9d46f79776b0f687ebbbd67a6b69f Mon Sep 17 00:00:00 2001 2 | From: Alexander Courtis 3 | Date: Mon, 22 Apr 2019 22:23:12 +1000 4 | Subject: [PATCH] unfloat any visible windows which have isfloating set 5 | 6 | optionally takes a layout to also apply 7 | 8 | e.g. 9 | { MODKEY|ShiftMask, XK_space, unfloatvisible, {0} }, 10 | { MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[1]} }, 11 | --- 12 | unfloat.c | 14 ++++++++++++++ 13 | 1 file changed, 14 insertions(+) 14 | create mode 100644 unfloat.c 15 | 16 | diff --git a/unfloat.c b/unfloat.c 17 | new file mode 100644 18 | index 0000000..ef84111 19 | --- /dev/null 20 | +++ b/unfloat.c 21 | @@ -0,0 +1,14 @@ 22 | +void 23 | +unfloatvisible(const Arg *arg) 24 | +{ 25 | + Client *c; 26 | + 27 | + for (c = selmon->clients; c; c = c->next) 28 | + if (ISVISIBLE(c) && c->isfloating) 29 | + c->isfloating = c->isfixed; 30 | + 31 | + if (arg && arg->v) 32 | + setlayout(arg); 33 | + else 34 | + arrange(selmon); 35 | +} 36 | -- 37 | 2.21.0 38 | 39 | -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/screenshots/3.png -------------------------------------------------------------------------------- /themes/mhtheme.h: -------------------------------------------------------------------------------- 1 | // mh's them 2 | // clang-format off 3 | 4 | static const char col_gray1[] = "#0a0a0a"; 5 | static const char col_gray2[] = "#262626"; 6 | static const char col_gray3[] = "#cdd6f4"; 7 | static const char col_gray4[] = "#0a0a0a"; 8 | static const char col_accnt[] = "#99f6e4"; 9 | -------------------------------------------------------------------------------- /transient.c: -------------------------------------------------------------------------------- 1 | /* cc transient.c -o transient -lX11 */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(void) { 9 | Display *d; 10 | Window r, f, t = None; 11 | XSizeHints h; 12 | XEvent e; 13 | 14 | d = XOpenDisplay(NULL); 15 | if (!d) 16 | exit(1); 17 | r = DefaultRootWindow(d); 18 | 19 | f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); 20 | h.min_width = h.max_width = h.min_height = h.max_height = 400; 21 | h.flags = PMinSize | PMaxSize; 22 | XSetWMNormalHints(d, f, &h); 23 | XStoreName(d, f, "floating"); 24 | XMapWindow(d, f); 25 | 26 | XSelectInput(d, f, ExposureMask); 27 | while (1) { 28 | XNextEvent(d, &e); 29 | 30 | if (t == None) { 31 | sleep(5); 32 | t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); 33 | XSetTransientForHint(d, t, f); 34 | XStoreName(d, t, "transient"); 35 | XMapWindow(d, t); 36 | XSelectInput(d, t, ExposureMask); 37 | } 38 | } 39 | 40 | XCloseDisplay(d); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /unfloat.c: -------------------------------------------------------------------------------- 1 | void 2 | unfloatvisible(const Arg *arg) 3 | { 4 | Client *c; 5 | 6 | for (c = selmon->clients; c; c = c->next) 7 | if (ISVISIBLE(c) && c->isfloating) 8 | c->isfloating = c->isfixed; 9 | 10 | if (arg && arg->v) 11 | setlayout(arg); 12 | else 13 | arrange(selmon); 14 | } 15 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | void 10 | die(const char *fmt, ...) 11 | { 12 | va_list ap; 13 | 14 | va_start(ap, fmt); 15 | vfprintf(stderr, fmt, ap); 16 | va_end(ap); 17 | 18 | if (fmt[0] && fmt[strlen(fmt)-1] == ':') { 19 | fputc(' ', stderr); 20 | perror(NULL); 21 | } else { 22 | fputc('\n', stderr); 23 | } 24 | 25 | exit(1); 26 | } 27 | 28 | void * 29 | ecalloc(size_t nmemb, size_t size) 30 | { 31 | void *p; 32 | 33 | if (!(p = calloc(nmemb, size))) 34 | die("calloc:"); 35 | return p; 36 | } 37 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #define MAX(A, B) ((A) > (B) ? (A) : (B)) 4 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 5 | #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) 6 | 7 | void die(const char *fmt, ...); 8 | void *ecalloc(size_t nmemb, size_t size); 9 | -------------------------------------------------------------------------------- /util.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxhu08/dwm-rev1/e31b48b14d5e506120fd28cbc507e8ec4def4e8d/util.o -------------------------------------------------------------------------------- /vanitygaps.c: -------------------------------------------------------------------------------- 1 | /* Key binding functions */ 2 | static void defaultgaps(const Arg *arg); 3 | static void incrgaps(const Arg *arg); 4 | static void incrigaps(const Arg *arg); 5 | static void incrogaps(const Arg *arg); 6 | static void incrohgaps(const Arg *arg); 7 | static void incrovgaps(const Arg *arg); 8 | static void incrihgaps(const Arg *arg); 9 | static void incrivgaps(const Arg *arg); 10 | static void togglegaps(const Arg *arg); 11 | /* Layouts (delete the ones you do not need) */ 12 | static void bstack(Monitor *m); 13 | static void bstackhoriz(Monitor *m); 14 | static void centeredmaster(Monitor *m); 15 | static void centeredfloatingmaster(Monitor *m); 16 | static void deck(Monitor *m); 17 | static void dwindle(Monitor *m); 18 | static void fibonacci(Monitor *m, int s); 19 | static void grid(Monitor *m); 20 | static void nrowgrid(Monitor *m); 21 | static void spiral(Monitor *m); 22 | static void tile(Monitor *m); 23 | /* Internals */ 24 | static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); 25 | static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); 26 | static void setgaps(int oh, int ov, int ih, int iv); 27 | 28 | /* Settings */ 29 | #if !PERTAG_PATCH 30 | static int enablegaps = 1; 31 | #endif // PERTAG_PATCH 32 | 33 | void 34 | setgaps(int oh, int ov, int ih, int iv) 35 | { 36 | if (oh < 0) oh = 0; 37 | if (ov < 0) ov = 0; 38 | if (ih < 0) ih = 0; 39 | if (iv < 0) iv = 0; 40 | 41 | selmon->gappoh = oh; 42 | selmon->gappov = ov; 43 | selmon->gappih = ih; 44 | selmon->gappiv = iv; 45 | arrange(selmon); 46 | } 47 | 48 | void 49 | togglegaps(const Arg *arg) 50 | { 51 | #if PERTAG_PATCH 52 | selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; 53 | #else 54 | enablegaps = !enablegaps; 55 | #endif // PERTAG_PATCH 56 | arrange(NULL); 57 | } 58 | 59 | void 60 | defaultgaps(const Arg *arg) 61 | { 62 | setgaps(gappoh, gappov, gappih, gappiv); 63 | } 64 | 65 | void 66 | incrgaps(const Arg *arg) 67 | { 68 | setgaps( 69 | selmon->gappoh + arg->i, 70 | selmon->gappov + arg->i, 71 | selmon->gappih + arg->i, 72 | selmon->gappiv + arg->i 73 | ); 74 | } 75 | 76 | void 77 | incrigaps(const Arg *arg) 78 | { 79 | setgaps( 80 | selmon->gappoh, 81 | selmon->gappov, 82 | selmon->gappih + arg->i, 83 | selmon->gappiv + arg->i 84 | ); 85 | } 86 | 87 | void 88 | incrogaps(const Arg *arg) 89 | { 90 | setgaps( 91 | selmon->gappoh + arg->i, 92 | selmon->gappov + arg->i, 93 | selmon->gappih, 94 | selmon->gappiv 95 | ); 96 | } 97 | 98 | void 99 | incrohgaps(const Arg *arg) 100 | { 101 | setgaps( 102 | selmon->gappoh + arg->i, 103 | selmon->gappov, 104 | selmon->gappih, 105 | selmon->gappiv 106 | ); 107 | } 108 | 109 | void 110 | incrovgaps(const Arg *arg) 111 | { 112 | setgaps( 113 | selmon->gappoh, 114 | selmon->gappov + arg->i, 115 | selmon->gappih, 116 | selmon->gappiv 117 | ); 118 | } 119 | 120 | void 121 | incrihgaps(const Arg *arg) 122 | { 123 | setgaps( 124 | selmon->gappoh, 125 | selmon->gappov, 126 | selmon->gappih + arg->i, 127 | selmon->gappiv 128 | ); 129 | } 130 | 131 | void 132 | incrivgaps(const Arg *arg) 133 | { 134 | setgaps( 135 | selmon->gappoh, 136 | selmon->gappov, 137 | selmon->gappih, 138 | selmon->gappiv + arg->i 139 | ); 140 | } 141 | 142 | void 143 | getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) 144 | { 145 | unsigned int n, oe, ie; 146 | #if PERTAG_PATCH 147 | oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; 148 | #else 149 | oe = ie = enablegaps; 150 | #endif // PERTAG_PATCH 151 | Client *c; 152 | 153 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 154 | if (smartgaps && n == 1) { 155 | oe = 0; // outer gaps disabled when only one client 156 | } 157 | 158 | *oh = m->gappoh*oe; // outer horizontal gap 159 | *ov = m->gappov*oe; // outer vertical gap 160 | *ih = m->gappih*ie; // inner horizontal gap 161 | *iv = m->gappiv*ie; // inner vertical gap 162 | *nc = n; // number of clients 163 | } 164 | 165 | void 166 | getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) 167 | { 168 | unsigned int n; 169 | float mfacts = 0, sfacts = 0; 170 | int mtotal = 0, stotal = 0; 171 | Client *c; 172 | 173 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 174 | if (n < m->nmaster) 175 | mfacts += c->cfact; 176 | else 177 | sfacts += c->cfact; 178 | 179 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 180 | if (n < m->nmaster) 181 | mtotal += msize * (c->cfact / mfacts); 182 | else 183 | stotal += ssize * (c->cfact / sfacts); 184 | 185 | *mf = mfacts; // total factor of master area 186 | *sf = sfacts; // total factor of stack area 187 | *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split 188 | *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split 189 | } 190 | 191 | /*** 192 | * Layouts 193 | */ 194 | 195 | /* 196 | * Bottomstack layout + gaps 197 | * https://dwm.suckless.org/patches/bottomstack/ 198 | */ 199 | static void 200 | bstack(Monitor *m) 201 | { 202 | unsigned int i, n; 203 | int oh, ov, ih, iv; 204 | int mx = 0, my = 0, mh = 0, mw = 0; 205 | int sx = 0, sy = 0, sh = 0, sw = 0; 206 | float mfacts, sfacts; 207 | int mrest, srest; 208 | Client *c; 209 | 210 | getgaps(m, &oh, &ov, &ih, &iv, &n); 211 | if (n == 0) 212 | return; 213 | 214 | sx = mx = m->wx + ov; 215 | sy = my = m->wy + oh; 216 | sh = mh = m->wh - 2*oh; 217 | mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 218 | sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); 219 | 220 | if (m->nmaster && n > m->nmaster) { 221 | sh = (mh - ih) * (1 - m->mfact); 222 | mh = mh - ih - sh; 223 | sx = mx; 224 | sy = my + mh + ih; 225 | } 226 | 227 | getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 228 | 229 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 230 | if (i < m->nmaster) { 231 | resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 232 | mx += WIDTH(c) + iv; 233 | } else { 234 | resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 235 | sx += WIDTH(c) + iv; 236 | } 237 | } 238 | } 239 | 240 | static void 241 | bstackhoriz(Monitor *m) 242 | { 243 | unsigned int i, n; 244 | int oh, ov, ih, iv; 245 | int mx = 0, my = 0, mh = 0, mw = 0; 246 | int sx = 0, sy = 0, sh = 0, sw = 0; 247 | float mfacts, sfacts; 248 | int mrest, srest; 249 | Client *c; 250 | 251 | getgaps(m, &oh, &ov, &ih, &iv, &n); 252 | if (n == 0) 253 | return; 254 | 255 | sx = mx = m->wx + ov; 256 | sy = my = m->wy + oh; 257 | mh = m->wh - 2*oh; 258 | sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 259 | mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 260 | sw = m->ww - 2*ov; 261 | 262 | if (m->nmaster && n > m->nmaster) { 263 | sh = (mh - ih) * (1 - m->mfact); 264 | mh = mh - ih - sh; 265 | sy = my + mh + ih; 266 | sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); 267 | } 268 | 269 | getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); 270 | 271 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 272 | if (i < m->nmaster) { 273 | resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 274 | mx += WIDTH(c) + iv; 275 | } else { 276 | resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 277 | sy += HEIGHT(c) + ih; 278 | } 279 | } 280 | } 281 | 282 | /* 283 | * Centred master layout + gaps 284 | * https://dwm.suckless.org/patches/centeredmaster/ 285 | */ 286 | void 287 | centeredmaster(Monitor *m) 288 | { 289 | unsigned int i, n; 290 | int oh, ov, ih, iv; 291 | int mx = 0, my = 0, mh = 0, mw = 0; 292 | int lx = 0, ly = 0, lw = 0, lh = 0; 293 | int rx = 0, ry = 0, rw = 0, rh = 0; 294 | float mfacts = 0, lfacts = 0, rfacts = 0; 295 | int mtotal = 0, ltotal = 0, rtotal = 0; 296 | int mrest = 0, lrest = 0, rrest = 0; 297 | Client *c; 298 | 299 | getgaps(m, &oh, &ov, &ih, &iv, &n); 300 | if (n == 0) 301 | return; 302 | 303 | /* initialize areas */ 304 | mx = m->wx + ov; 305 | my = m->wy + oh; 306 | mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); 307 | mw = m->ww - 2*ov; 308 | lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); 309 | rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); 310 | 311 | if (m->nmaster && n > m->nmaster) { 312 | /* go mfact box in the center if more than nmaster clients */ 313 | if (n - m->nmaster > 1) { 314 | /* ||<-S->|<---M--->|<-S->|| */ 315 | mw = (m->ww - 2*ov - 2*iv) * m->mfact; 316 | lw = (m->ww - mw - 2*ov - 2*iv) / 2; 317 | rw = (m->ww - mw - 2*ov - 2*iv) - lw; 318 | mx += lw + iv; 319 | } else { 320 | /* ||<---M--->|<-S->|| */ 321 | mw = (mw - iv) * m->mfact; 322 | lw = 0; 323 | rw = m->ww - mw - iv - 2*ov; 324 | } 325 | lx = m->wx + ov; 326 | ly = m->wy + oh; 327 | rx = mx + mw + iv; 328 | ry = m->wy + oh; 329 | } 330 | 331 | /* calculate facts */ 332 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { 333 | if (!m->nmaster || n < m->nmaster) 334 | mfacts += c->cfact; 335 | else if ((n - m->nmaster) % 2) 336 | lfacts += c->cfact; // total factor of left hand stack area 337 | else 338 | rfacts += c->cfact; // total factor of right hand stack area 339 | } 340 | 341 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 342 | if (!m->nmaster || n < m->nmaster) 343 | mtotal += mh * (c->cfact / mfacts); 344 | else if ((n - m->nmaster) % 2) 345 | ltotal += lh * (c->cfact / lfacts); 346 | else 347 | rtotal += rh * (c->cfact / rfacts); 348 | 349 | mrest = mh - mtotal; 350 | lrest = lh - ltotal; 351 | rrest = rh - rtotal; 352 | 353 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 354 | if (!m->nmaster || i < m->nmaster) { 355 | /* nmaster clients are stacked vertically, in the center of the screen */ 356 | resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 357 | my += HEIGHT(c) + ih; 358 | } else { 359 | /* stack clients are stacked vertically */ 360 | if ((i - m->nmaster) % 2 ) { 361 | resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); 362 | ly += HEIGHT(c) + ih; 363 | } else { 364 | resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); 365 | ry += HEIGHT(c) + ih; 366 | } 367 | } 368 | } 369 | } 370 | 371 | void 372 | centeredfloatingmaster(Monitor *m) 373 | { 374 | unsigned int i, n; 375 | float mfacts, sfacts; 376 | float mivf = 1.0; // master inner vertical gap factor 377 | int oh, ov, ih, iv, mrest, srest; 378 | int mx = 0, my = 0, mh = 0, mw = 0; 379 | int sx = 0, sy = 0, sh = 0, sw = 0; 380 | Client *c; 381 | 382 | getgaps(m, &oh, &ov, &ih, &iv, &n); 383 | if (n == 0) 384 | return; 385 | 386 | sx = mx = m->wx + ov; 387 | sy = my = m->wy + oh; 388 | sh = mh = m->wh - 2*oh; 389 | mw = m->ww - 2*ov - iv*(n - 1); 390 | sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); 391 | 392 | if (m->nmaster && n > m->nmaster) { 393 | mivf = 0.8; 394 | /* go mfact box in the center if more than nmaster clients */ 395 | if (m->ww > m->wh) { 396 | mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); 397 | mh = m->wh * 0.9; 398 | } else { 399 | mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); 400 | mh = m->wh * m->mfact; 401 | } 402 | mx = m->wx + (m->ww - mw) / 2; 403 | my = m->wy + (m->wh - mh - 2*oh) / 2; 404 | 405 | sx = m->wx + ov; 406 | sy = m->wy + oh; 407 | sh = m->wh - 2*oh; 408 | } 409 | 410 | getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 411 | 412 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 413 | if (i < m->nmaster) { 414 | /* nmaster clients are stacked horizontally, in the center of the screen */ 415 | resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 416 | mx += WIDTH(c) + iv*mivf; 417 | } else { 418 | /* stack clients are stacked horizontally */ 419 | resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 420 | sx += WIDTH(c) + iv; 421 | } 422 | } 423 | 424 | /* 425 | * Deck layout + gaps 426 | * https://dwm.suckless.org/patches/deck/ 427 | */ 428 | void 429 | deck(Monitor *m) 430 | { 431 | unsigned int i, n; 432 | int oh, ov, ih, iv; 433 | int mx = 0, my = 0, mh = 0, mw = 0; 434 | int sx = 0, sy = 0, sh = 0, sw = 0; 435 | float mfacts, sfacts; 436 | int mrest, srest; 437 | Client *c; 438 | 439 | getgaps(m, &oh, &ov, &ih, &iv, &n); 440 | if (n == 0) 441 | return; 442 | 443 | sx = mx = m->wx + ov; 444 | sy = my = m->wy + oh; 445 | sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 446 | sw = mw = m->ww - 2*ov; 447 | 448 | if (m->nmaster && n > m->nmaster) { 449 | sw = (mw - iv) * (1 - m->mfact); 450 | mw = mw - iv - sw; 451 | sx = mx + mw + iv; 452 | sh = m->wh - 2*oh; 453 | } 454 | 455 | getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 456 | 457 | if (n - m->nmaster > 0) /* override layout symbol */ 458 | snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); 459 | 460 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 461 | if (i < m->nmaster) { 462 | resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 463 | my += HEIGHT(c) + ih; 464 | } else { 465 | resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); 466 | } 467 | } 468 | 469 | /* 470 | * Fibonacci layout + gaps 471 | * https://dwm.suckless.org/patches/fibonacci/ 472 | */ 473 | void 474 | fibonacci(Monitor *m, int s) 475 | { 476 | unsigned int i, n; 477 | int nx, ny, nw, nh; 478 | int oh, ov, ih, iv; 479 | int nv, hrest = 0, wrest = 0, r = 1; 480 | Client *c; 481 | 482 | getgaps(m, &oh, &ov, &ih, &iv, &n); 483 | if (n == 0) 484 | return; 485 | 486 | nx = m->wx + ov; 487 | ny = m->wy + oh; 488 | nw = m->ww - 2*ov; 489 | nh = m->wh - 2*oh; 490 | 491 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { 492 | if (r) { 493 | if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) 494 | || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { 495 | r = 0; 496 | } 497 | if (r && i < n - 1) { 498 | if (i % 2) { 499 | nv = (nh - ih) / 2; 500 | hrest = nh - 2*nv - ih; 501 | nh = nv; 502 | } else { 503 | nv = (nw - iv) / 2; 504 | wrest = nw - 2*nv - iv; 505 | nw = nv; 506 | } 507 | 508 | if ((i % 4) == 2 && !s) 509 | nx += nw + iv; 510 | else if ((i % 4) == 3 && !s) 511 | ny += nh + ih; 512 | } 513 | 514 | if ((i % 4) == 0) { 515 | if (s) { 516 | ny += nh + ih; 517 | nh += hrest; 518 | } 519 | else { 520 | nh -= hrest; 521 | ny -= nh + ih; 522 | } 523 | } 524 | else if ((i % 4) == 1) { 525 | nx += nw + iv; 526 | nw += wrest; 527 | } 528 | else if ((i % 4) == 2) { 529 | ny += nh + ih; 530 | nh += hrest; 531 | if (i < n - 1) 532 | nw += wrest; 533 | } 534 | else if ((i % 4) == 3) { 535 | if (s) { 536 | nx += nw + iv; 537 | nw -= wrest; 538 | } else { 539 | nw -= wrest; 540 | nx -= nw + iv; 541 | nh += hrest; 542 | } 543 | } 544 | if (i == 0) { 545 | if (n != 1) { 546 | nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); 547 | wrest = 0; 548 | } 549 | ny = m->wy + oh; 550 | } 551 | else if (i == 1) 552 | nw = m->ww - nw - iv - 2*ov; 553 | i++; 554 | } 555 | 556 | resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); 557 | } 558 | } 559 | 560 | void 561 | dwindle(Monitor *m) 562 | { 563 | fibonacci(m, 1); 564 | } 565 | 566 | void 567 | spiral(Monitor *m) 568 | { 569 | fibonacci(m, 0); 570 | } 571 | 572 | /* 573 | * Gappless grid layout + gaps (ironically) 574 | * https://dwm.suckless.org/patches/gaplessgrid/ 575 | */ 576 | void 577 | gaplessgrid(Monitor *m) 578 | { 579 | unsigned int i, n; 580 | int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters 581 | int oh, ov, ih, iv; 582 | Client *c; 583 | 584 | getgaps(m, &oh, &ov, &ih, &iv, &n); 585 | if (n == 0) 586 | return; 587 | 588 | /* grid dimensions */ 589 | for (cols = 0; cols <= n/2; cols++) 590 | if (cols*cols >= n) 591 | break; 592 | if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ 593 | cols = 2; 594 | rows = n/cols; 595 | cn = rn = 0; // reset column no, row no, client count 596 | 597 | ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 598 | cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; 599 | rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 600 | crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 601 | x = m->wx + ov; 602 | y = m->wy + oh; 603 | 604 | for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { 605 | if (i/rows + 1 > cols - n%cols) { 606 | rows = n/cols + 1; 607 | ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 608 | rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 609 | } 610 | resize(c, 611 | x, 612 | y + rn*(ch + ih) + MIN(rn, rrest), 613 | cw + (cn < crest ? 1 : 0) - 2*c->bw, 614 | ch + (rn < rrest ? 1 : 0) - 2*c->bw, 615 | 0); 616 | rn++; 617 | if (rn >= rows) { 618 | rn = 0; 619 | x += cw + ih + (cn < crest ? 1 : 0); 620 | cn++; 621 | } 622 | } 623 | } 624 | 625 | /* 626 | * Gridmode layout + gaps 627 | * https://dwm.suckless.org/patches/gridmode/ 628 | */ 629 | void 630 | grid(Monitor *m) 631 | { 632 | unsigned int i, n; 633 | int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; 634 | int oh, ov, ih, iv; 635 | Client *c; 636 | 637 | getgaps(m, &oh, &ov, &ih, &iv, &n); 638 | 639 | /* grid dimensions */ 640 | for (rows = 0; rows <= n/2; rows++) 641 | if (rows*rows >= n) 642 | break; 643 | cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; 644 | 645 | /* window geoms (cell height/width) */ 646 | ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); 647 | cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); 648 | chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 649 | cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 650 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 651 | cc = i / rows; 652 | cr = i % rows; 653 | cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); 654 | cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); 655 | resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); 656 | } 657 | } 658 | 659 | /* 660 | * Horizontal grid layout + gaps 661 | * https://dwm.suckless.org/patches/horizgrid/ 662 | */ 663 | void 664 | horizgrid(Monitor *m) { 665 | Client *c; 666 | unsigned int n, i; 667 | int oh, ov, ih, iv; 668 | int mx = 0, my = 0, mh = 0, mw = 0; 669 | int sx = 0, sy = 0, sh = 0, sw = 0; 670 | int ntop, nbottom = 1; 671 | float mfacts = 0, sfacts = 0; 672 | int mrest, srest, mtotal = 0, stotal = 0; 673 | 674 | /* Count windows */ 675 | getgaps(m, &oh, &ov, &ih, &iv, &n); 676 | if (n == 0) 677 | return; 678 | 679 | if (n <= 2) 680 | ntop = n; 681 | else { 682 | ntop = n / 2; 683 | nbottom = n - ntop; 684 | } 685 | sx = mx = m->wx + ov; 686 | sy = my = m->wy + oh; 687 | sh = mh = m->wh - 2*oh; 688 | sw = mw = m->ww - 2*ov; 689 | 690 | if (n > ntop) { 691 | sh = (mh - ih) / 2; 692 | mh = mh - ih - sh; 693 | sy = my + mh + ih; 694 | mw = m->ww - 2*ov - iv * (ntop - 1); 695 | sw = m->ww - 2*ov - iv * (nbottom - 1); 696 | } 697 | 698 | /* calculate facts */ 699 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 700 | if (i < ntop) 701 | mfacts += c->cfact; 702 | else 703 | sfacts += c->cfact; 704 | 705 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 706 | if (i < ntop) 707 | mtotal += mh * (c->cfact / mfacts); 708 | else 709 | stotal += sw * (c->cfact / sfacts); 710 | 711 | mrest = mh - mtotal; 712 | srest = sw - stotal; 713 | 714 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 715 | if (i < ntop) { 716 | resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 717 | mx += WIDTH(c) + iv; 718 | } else { 719 | resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 720 | sx += WIDTH(c) + iv; 721 | } 722 | } 723 | 724 | /* 725 | * nrowgrid layout + gaps 726 | * https://dwm.suckless.org/patches/nrowgrid/ 727 | */ 728 | void 729 | nrowgrid(Monitor *m) 730 | { 731 | unsigned int n; 732 | int ri = 0, ci = 0; /* counters */ 733 | int oh, ov, ih, iv; /* vanitygap settings */ 734 | unsigned int cx, cy, cw, ch; /* client geometry */ 735 | unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ 736 | unsigned int cols, rows = m->nmaster + 1; 737 | Client *c; 738 | 739 | /* count clients */ 740 | getgaps(m, &oh, &ov, &ih, &iv, &n); 741 | 742 | /* nothing to do here */ 743 | if (n == 0) 744 | return; 745 | 746 | /* force 2 clients to always split vertically */ 747 | if (FORCE_VSPLIT && n == 2) 748 | rows = 1; 749 | 750 | /* never allow empty rows */ 751 | if (n < rows) 752 | rows = n; 753 | 754 | /* define first row */ 755 | cols = n / rows; 756 | uc = cols; 757 | cy = m->wy + oh; 758 | ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; 759 | uh = ch; 760 | 761 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) { 762 | if (ci == cols) { 763 | uw = 0; 764 | ci = 0; 765 | ri++; 766 | 767 | /* next row */ 768 | cols = (n - uc) / (rows - ri); 769 | uc += cols; 770 | cy = m->wy + oh + uh + ih; 771 | uh += ch + ih; 772 | } 773 | 774 | cx = m->wx + ov + uw; 775 | cw = (m->ww - 2*ov - uw) / (cols - ci); 776 | uw += cw + iv; 777 | 778 | resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); 779 | } 780 | } 781 | 782 | /* 783 | * Default tile layout + gaps 784 | */ 785 | static void 786 | tile(Monitor *m) 787 | { 788 | unsigned int i, n; 789 | int oh, ov, ih, iv; 790 | int mx = 0, my = 0, mh = 0, mw = 0; 791 | int sx = 0, sy = 0, sh = 0, sw = 0; 792 | float mfacts, sfacts; 793 | int mrest, srest; 794 | Client *c; 795 | 796 | getgaps(m, &oh, &ov, &ih, &iv, &n); 797 | if (n == 0) 798 | return; 799 | 800 | sx = mx = m->wx + ov; 801 | sy = my = m->wy + oh; 802 | mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 803 | sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 804 | sw = mw = m->ww - 2*ov; 805 | 806 | if (m->nmaster && n > m->nmaster) { 807 | sw = (mw - iv) * (1 - m->mfact); 808 | mw = mw - iv - sw; 809 | sx = mx + mw + iv; 810 | } 811 | 812 | getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 813 | 814 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 815 | if (i < m->nmaster) { 816 | resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 817 | my += HEIGHT(c) + ih; 818 | } else { 819 | resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 820 | sy += HEIGHT(c) + ih; 821 | } 822 | } --------------------------------------------------------------------------------