├── .gitignore ├── LICENSE ├── README.md ├── dwm ├── .gitignore ├── LICENSE ├── Makefile ├── config.h ├── config.mk ├── drw.c ├── drw.h ├── dwm.1 ├── dwm.c ├── patches │ ├── dwm-actualfullscreen-20211013-cb3f58a.diff │ ├── dwm-alwayscenter-20200625-f04cac6.diff │ ├── dwm-attachbottom-6.3.diff │ ├── dwm-centretitle-20200907-61bb8b2.diff │ ├── dwm-dragmfact-6.2.diff │ ├── dwm-fullgaps-6.4.diff │ ├── dwm-preserveonrestart-6.3.diff │ ├── dwm-restartsig-20180523-6.2.diff │ ├── dwm-savefloats-20181212-b69c870.diff │ ├── dwm-systray-20230922-9f88553.diff │ └── dwm-tiledmove-20231210-b731.diff ├── transient.c ├── util.c └── util.h ├── extra ├── dwm.desktop ├── fastfetch.jsonc ├── nvim │ ├── init.lua │ └── lua │ │ ├── keymap │ │ └── init.lua │ │ └── plug │ │ ├── config.lua │ │ ├── load.lua │ │ └── lsp.lua ├── picom.conf ├── rofi-catppuccin.rasi ├── rofi.rasi ├── tmux.conf ├── trapd00r-catppuccin.zsh-theme ├── xinitrc └── zshrc ├── install.sh ├── install_preview.gif ├── install_preview.tape ├── preview.png ├── st ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── arg.h ├── config.h ├── config.mk ├── hb.c ├── hb.h ├── patches │ ├── st-anysize-20220718-baa9357.diff │ ├── st-ligatures-20240427-0.9.2.diff │ └── st-scrollback-0.9.2.diff ├── st.1 ├── st.c ├── st.h ├── st.info ├── win.h └── x.c └── update.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .vim 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Adam Perkowski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

My DWM Rice

3 | 4 | ![Preview](preview.png) 5 | 6 |

DWM

7 | 8 |
9 | 10 | - Better fullscreen 11 | - Floating window centering 12 | - New windows attach to the bottom of the stack 13 | - Window title centered 14 | - Right mouse button window resizing 15 | - Gaps 16 | - **Smooth updating & restarting** with window preservation 17 | - Floating window position saving 18 | - Systray 19 | - Moving **tiled** windows with mouse buttons 20 | 21 |

Extra

22 | 23 | - Automatic installation and update scripts 24 | - Kitty configuration 25 | - Fastfetch rice 26 | - Full Neovim configuration with LSP, remaps, theme and plugins 27 | - Custom coc.nvim patch 28 | - Picom configuration 29 | - Rofi rice 30 | - Custom ZSH configuration and theme 31 | 32 |
33 | 34 |

Installation

35 | 36 | The installation script is designed for a minimal Arch Linux install, but may work on some Arch-based distros. 37 | 38 |
39 | 40 | > [!IMPORTANT] 41 | > This rice relies on having a permanent existing `dwm/` directory. **Don't remove the directory after setup.** 42 | 43 | #### To install, execute the following commands: 44 | > [!CAUTION] 45 | > This might overwrite your existing dotfiles. Make sure to back everything up. 46 | 47 | ```bash 48 | git clone --depth 1 https://github.com/adamperkowski/dwm.git -b dwm 49 | cd dwm 50 | ./install.sh 51 | ``` 52 | 53 | #### To update, execute the following commands: 54 | 55 | ```bash 56 | cd $DWM_DIR && ./update.sh 57 | ``` 58 | 59 | You might need to re-run `./install.sh` after an update. 60 | 61 |
62 | 63 |

Installation Preview

64 | 65 | ![Installation Preview](install_preview.gif) 66 | 67 |

Keybind List

68 | 69 | |Keybind|Description| 70 | |---|---| 71 | |`SUPER + RETURN`|Spawns `st` (terminal)| 72 | |`SUPER + SHIFT + RETURN`|Spawns `rofi` (application launcher)| 73 | |`PRNTSCR`|Spawns `flameshot gui` (screenshot utility)| 74 | |`SUPER + J` or `L`|Moves focus to previous window| 75 | |`SUPER + H` or `K`|Moves focus to next window| 76 | |`SUPER + SHIFT + J` or `L`|Resizes selected window up or right| 77 | |`SUPER + SHIFT + H` or `L`|Resizes selected window down or left| 78 | |`SUPER + LMB`|Drags selected window| 79 | |`SUPER + RMB`|Resizes selected window| 80 | |`SUPER + I`|Increases master stack| 81 | |`SUPER + D`|Decreases master stack| 82 | |`SUPER + TAB`|Enters focus mode| 83 | |`SUPER + SHIFT + TAB`|Exits focus mode| 84 | |`SUPER + SHIFT + C`|Kills selected window| 85 | |`SUPER + SPACE`|Toggles floating mode| 86 | |`SUPER + F`|Toggles fullscreen mode| 87 | |`SUPER + ,`|Moves focus to previous monitor| 88 | |`SUPER + .`|Moves focus to next monitor| 89 | |`SUPER + SHIFT + ,`|Moves selected window to previous monitor| 90 | |`SUPER + SHIFT + .`|Moves selected window to next monitor| 91 | |`SUPER + 1`-`9`|Moves focus to a tag `1`-`9`| 92 | |`SUPER + 0`|Shows all windows| 93 | |`SUPER + SHIFT + Q`|Restarts dwm| 94 | |`SUPER + SHIFT + W`|Kills dwm| 95 | 96 |
97 | -------------------------------------------------------------------------------- /dwm/.gitignore: -------------------------------------------------------------------------------- 1 | dwm 2 | dwm.c.* 3 | *.o 4 | *-* 5 | *.tar.gz 6 | *.orig 7 | *.rej 8 | -------------------------------------------------------------------------------- /dwm/LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2024-present Adam Perkowski 4 | 5 | © 2006-2019 Anselm R Garbe 6 | © 2006-2009 Jukka Salmi 7 | © 2006-2007 Sander van Dijk 8 | © 2007-2011 Peter Hartlich 9 | © 2007-2009 Szabolcs Nagy 10 | © 2007-2009 Christof Musik 11 | © 2007-2009 Premysl Hruby 12 | © 2007-2008 Enno Gottox Boland 13 | © 2008 Martin Hurton 14 | © 2008 Neale Pickett 15 | © 2009 Mate Nagy 16 | © 2010-2016 Hiltjo Posthuma 17 | © 2010-2012 Connor Lane Smith 18 | © 2011 Christoph Lohmann <20h@r-36.net> 19 | © 2015-2016 Quentin Rameau 20 | © 2015-2016 Eric Pruitt 21 | © 2016-2017 Markus Teich 22 | © 2020-2022 Chris Down 23 | 24 | Permission is hereby granted, free of charge, to any person obtaining a 25 | copy of this software and associated documentation files (the "Software"), 26 | to deal in the Software without restriction, including without limitation 27 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 28 | and/or sell copies of the Software, and to permit persons to whom the 29 | Software is furnished to do so, subject to the following conditions: 30 | 31 | The above copyright notice and this permission notice shall be included in 32 | all copies or substantial portions of the Software. 33 | 34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 37 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 40 | DEALINGS IN THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /dwm/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.mk 15 | 16 | dwm: ${OBJ} 17 | ${CC} -o $@ ${OBJ} ${LDFLAGS} 18 | 19 | clean: 20 | rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz 21 | 22 | install: all 23 | install -Dm755 dwm -t ${DESTDIR}${PREFIX}/bin 24 | sed "s/VERSION/${VERSION}/g" < dwm.1 > dwm.1.install 25 | install -Dm644 dwm.1.install -t ${DESTDIR}${MANPREFIX}/man1 26 | rm -f dwm.1.install 27 | 28 | .PHONY: all clean install 29 | -------------------------------------------------------------------------------- /dwm/config.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | /* appearance */ 4 | static const unsigned int borderpx = 2; /* border pixel of windows */ 5 | static const unsigned int gappx = 10; /* gaps between windows */ 6 | static const unsigned int snap = 32; /* snap pixel */ 7 | static const unsigned int systraypinning = 1; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ 8 | static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ 9 | static const unsigned int systrayspacing = 2; /* systray spacing */ 10 | static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ 11 | static const int showsystray = 1; /* 0 means no systray */ 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[] = { "FiraCode Nerd Font:size=10:antialias=true" }; 15 | static const char dmenufont[] = "monospace:size=10"; 16 | static const char col_bg[] = "#1e1e2e"; 17 | static const char col_fg[] = "#f38ba8"; 18 | static const char col_dsel[] = "#313244"; 19 | static const char *colors[][3] = { 20 | /* fg bg border */ 21 | [SchemeNorm] = { col_fg, col_bg, col_dsel }, 22 | [SchemeSel] = { col_fg, col_bg, col_fg }, 23 | }; 24 | 25 | /* tagging */ 26 | static const char *tags[] = { "󰬺", "󰬻", "󰬼", "󰬽", "󰬾", "󰬿", "󰭀", "󰭁", "󰭂" }; 27 | 28 | static const Rule rules[] = { 29 | /* xprop(1): 30 | * WM_CLASS(STRING) = instance, class 31 | * WM_NAME(STRING) = title 32 | */ 33 | /* class instance title tags mask isfloating monitor */ 34 | { "floorp", NULL, NULL, 2, 0, 0 }, 35 | { "chromium", NULL, NULL, 2, 0, 0 }, 36 | { "firefox", NULL, NULL, 2, 0, 0 }, 37 | }; 38 | 39 | /* layout(s) */ 40 | static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ 41 | static const int nmaster = 1; /* number of clients in master area */ 42 | static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ 43 | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 44 | 45 | static const Layout layouts[] = { 46 | /* symbol arrange function */ 47 | { "", tile }, /* first entry is default */ 48 | { "", NULL }, /* no layout function means floating behavior */ 49 | { "", monocle }, 50 | }; 51 | 52 | /* key definitions */ 53 | #define MODKEY Mod4Mask 54 | #define TAGKEYS(KEY,TAG) \ 55 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 56 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 57 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 58 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 59 | 60 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 61 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 62 | 63 | /* commands */ 64 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 65 | static const char *dmenucmd[] = { "dmenu_run", NULL }; 66 | static const char *termcmd[] = { "st", NULL }; 67 | static const char *launchcmd[] = { "rofi", "-show", "drun", NULL }; 68 | static const char *flamcmd[] = { "flameshot", "gui", NULL }; 69 | 70 | static const Key keys[] = { 71 | /* modifier key function argument */ 72 | { MODKEY|ShiftMask, XK_Return, spawn, {.v = launchcmd } }, 73 | { MODKEY, XK_Return, spawn, {.v = termcmd } }, 74 | { 0, XK_Print, spawn, {.v = flamcmd } }, 75 | { MODKEY, XK_j, focusstack, {.i = +1 } }, 76 | { MODKEY, XK_l, focusstack, {.i = +1 } }, 77 | { MODKEY, XK_k, focusstack, {.i = -1 } }, 78 | { MODKEY, XK_h, focusstack, {.i = -1 } }, 79 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, 80 | { MODKEY, XK_d, incnmaster, {.i = -1 } }, 81 | { MODKEY|ShiftMask, XK_k, setmfact, {.f = +0.05} }, 82 | { MODKEY|ShiftMask, XK_l, setmfact, {.f = +0.05} }, 83 | { MODKEY|ShiftMask, XK_j, setmfact, {.f = -0.05} }, 84 | { MODKEY|ShiftMask, XK_h, setmfact, {.f = -0.05} }, 85 | { MODKEY|ShiftMask, XK_Tab, setlayout, {.v = &layouts[0]} }, 86 | { MODKEY, XK_Tab, setlayout, {.v = &layouts[2]} }, 87 | { MODKEY|ShiftMask, XK_c, killclient, {0} }, 88 | { MODKEY, XK_space, togglefloating, {0} }, 89 | { MODKEY, XK_f, togglefullscr, {0} }, 90 | { MODKEY, XK_0, view, {.ui = ~0 } }, 91 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, 92 | { MODKEY, XK_period, focusmon, {.i = +1 } }, 93 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, 94 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, 95 | TAGKEYS( XK_1, 0) 96 | TAGKEYS( XK_2, 1) 97 | TAGKEYS( XK_3, 2) 98 | TAGKEYS( XK_4, 3) 99 | TAGKEYS( XK_5, 4) 100 | TAGKEYS( XK_6, 5) 101 | TAGKEYS( XK_7, 6) 102 | TAGKEYS( XK_8, 7) 103 | TAGKEYS( XK_9, 8) 104 | { MODKEY|ShiftMask, XK_w, quit, {0} }, 105 | { MODKEY|ShiftMask, XK_q, quit, {1} }, 106 | }; 107 | 108 | /* button definitions */ 109 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 110 | static const Button buttons[] = { 111 | /* click event mask button function argument */ 112 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 113 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 114 | { ClkWinTitle, 0, Button2, zoom, {0} }, 115 | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 116 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 117 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 118 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 119 | { ClkTagBar, 0, Button1, view, {0} }, 120 | { ClkTagBar, 0, Button3, toggleview, {0} }, 121 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 122 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /dwm/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, 0xF8}; 16 | static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; 17 | static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; 18 | 19 | static long 20 | utf8decodebyte(const char c, size_t *i) 21 | { 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 29 | utf8validate(long *u, size_t i) 30 | { 31 | if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) 32 | *u = UTF_INVALID; 33 | for (i = 1; *u > utfmax[i]; ++i) 34 | ; 35 | return i; 36 | } 37 | 38 | static size_t 39 | utf8decode(const char *c, long *u, size_t clen) 40 | { 41 | size_t i, j, len, type; 42 | long udecoded; 43 | 44 | *u = UTF_INVALID; 45 | if (!clen) 46 | return 0; 47 | udecoded = utf8decodebyte(c[0], &len); 48 | if (!BETWEEN(len, 1, UTF_SIZ)) 49 | return 1; 50 | for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { 51 | udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); 52 | if (type) 53 | return j; 54 | } 55 | if (j < len) 56 | return 0; 57 | *u = udecoded; 58 | utf8validate(u, len); 59 | 60 | return len; 61 | } 62 | 63 | Drw * 64 | drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) 65 | { 66 | Drw *drw = ecalloc(1, sizeof(Drw)); 67 | 68 | drw->dpy = dpy; 69 | drw->screen = screen; 70 | drw->root = root; 71 | drw->w = w; 72 | drw->h = h; 73 | drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); 74 | drw->gc = XCreateGC(dpy, root, 0, NULL); 75 | XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); 76 | 77 | return drw; 78 | } 79 | 80 | void 81 | drw_resize(Drw *drw, unsigned int w, unsigned int h) 82 | { 83 | if (!drw) 84 | return; 85 | 86 | drw->w = w; 87 | drw->h = h; 88 | if (drw->drawable) 89 | XFreePixmap(drw->dpy, drw->drawable); 90 | drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); 91 | } 92 | 93 | void 94 | drw_free(Drw *drw) 95 | { 96 | XFreePixmap(drw->dpy, drw->drawable); 97 | XFreeGC(drw->dpy, drw->gc); 98 | drw_fontset_free(drw->fonts); 99 | free(drw); 100 | } 101 | 102 | /* This function is an implementation detail. Library users should use 103 | * drw_fontset_create instead. 104 | */ 105 | static Fnt * 106 | xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) 107 | { 108 | Fnt *font; 109 | XftFont *xfont = NULL; 110 | FcPattern *pattern = NULL; 111 | 112 | if (fontname) { 113 | /* Using the pattern found at font->xfont->pattern does not yield the 114 | * same substitution results as using the pattern returned by 115 | * FcNameParse; using the latter results in the desired fallback 116 | * behaviour whereas the former just results in missing-character 117 | * rectangles being drawn, at least with some fonts. */ 118 | if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { 119 | fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); 120 | return NULL; 121 | } 122 | if (!(pattern = FcNameParse((FcChar8 *) fontname))) { 123 | fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); 124 | XftFontClose(drw->dpy, xfont); 125 | return NULL; 126 | } 127 | } else if (fontpattern) { 128 | if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { 129 | fprintf(stderr, "error, cannot load font from pattern.\n"); 130 | return NULL; 131 | } 132 | } else { 133 | die("no font specified."); 134 | } 135 | 136 | font = ecalloc(1, sizeof(Fnt)); 137 | font->xfont = xfont; 138 | font->pattern = pattern; 139 | font->h = xfont->ascent + xfont->descent; 140 | font->dpy = drw->dpy; 141 | 142 | return font; 143 | } 144 | 145 | static void 146 | xfont_free(Fnt *font) 147 | { 148 | if (!font) 149 | return; 150 | if (font->pattern) 151 | FcPatternDestroy(font->pattern); 152 | XftFontClose(font->dpy, font->xfont); 153 | free(font); 154 | } 155 | 156 | Fnt* 157 | drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) 158 | { 159 | Fnt *cur, *ret = NULL; 160 | size_t i; 161 | 162 | if (!drw || !fonts) 163 | return NULL; 164 | 165 | for (i = 1; i <= fontcount; i++) { 166 | if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { 167 | cur->next = ret; 168 | ret = cur; 169 | } 170 | } 171 | return (drw->fonts = ret); 172 | } 173 | 174 | void 175 | drw_fontset_free(Fnt *font) 176 | { 177 | if (font) { 178 | drw_fontset_free(font->next); 179 | xfont_free(font); 180 | } 181 | } 182 | 183 | void 184 | drw_clr_create(Drw *drw, Clr *dest, const char *clrname) 185 | { 186 | if (!drw || !dest || !clrname) 187 | return; 188 | 189 | if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), 190 | DefaultColormap(drw->dpy, drw->screen), 191 | clrname, dest)) 192 | die("error, cannot allocate color '%s'", clrname); 193 | } 194 | 195 | /* Wrapper to create color schemes. The caller has to call free(3) on the 196 | * returned color scheme when done using it. */ 197 | Clr * 198 | drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) 199 | { 200 | size_t i; 201 | Clr *ret; 202 | 203 | /* need at least two colors for a scheme */ 204 | if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) 205 | return NULL; 206 | 207 | for (i = 0; i < clrcount; i++) 208 | drw_clr_create(drw, &ret[i], clrnames[i]); 209 | return ret; 210 | } 211 | 212 | void 213 | drw_setfontset(Drw *drw, Fnt *set) 214 | { 215 | if (drw) 216 | drw->fonts = set; 217 | } 218 | 219 | void 220 | drw_setscheme(Drw *drw, Clr *scm) 221 | { 222 | if (drw) 223 | drw->scheme = scm; 224 | } 225 | 226 | void 227 | drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) 228 | { 229 | if (!drw || !drw->scheme) 230 | return; 231 | XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); 232 | if (filled) 233 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 234 | else 235 | XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); 236 | } 237 | 238 | int 239 | drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) 240 | { 241 | int i, ty, ellipsis_x = 0; 242 | unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; 243 | XftDraw *d = NULL; 244 | Fnt *usedfont, *curfont, *nextfont; 245 | int utf8strlen, utf8charlen, render = x || y || w || h; 246 | long utf8codepoint = 0; 247 | const char *utf8str; 248 | FcCharSet *fccharset; 249 | FcPattern *fcpattern; 250 | FcPattern *match; 251 | XftResult result; 252 | int charexists = 0, overflow = 0; 253 | /* keep track of a couple codepoints for which we have no match. */ 254 | enum { nomatches_len = 64 }; 255 | static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; 256 | static unsigned int ellipsis_width = 0; 257 | 258 | if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) 259 | return 0; 260 | 261 | if (!render) { 262 | w = invert ? invert : ~invert; 263 | } else { 264 | XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); 265 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 266 | d = XftDrawCreate(drw->dpy, drw->drawable, 267 | DefaultVisual(drw->dpy, drw->screen), 268 | DefaultColormap(drw->dpy, drw->screen)); 269 | x += lpad; 270 | w -= lpad; 271 | } 272 | 273 | usedfont = drw->fonts; 274 | if (!ellipsis_width && render) 275 | ellipsis_width = drw_fontset_getwidth(drw, "..."); 276 | while (1) { 277 | ew = ellipsis_len = utf8strlen = 0; 278 | utf8str = text; 279 | nextfont = NULL; 280 | while (*text) { 281 | utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); 282 | for (curfont = drw->fonts; curfont; curfont = curfont->next) { 283 | charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); 284 | if (charexists) { 285 | drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); 286 | if (ew + ellipsis_width <= w) { 287 | /* keep track where the ellipsis still fits */ 288 | ellipsis_x = x + ew; 289 | ellipsis_w = w - ew; 290 | ellipsis_len = utf8strlen; 291 | } 292 | 293 | if (ew + tmpw > w) { 294 | overflow = 1; 295 | /* called from drw_fontset_getwidth_clamp(): 296 | * it wants the width AFTER the overflow 297 | */ 298 | if (!render) 299 | x += tmpw; 300 | else 301 | utf8strlen = ellipsis_len; 302 | } else if (curfont == usedfont) { 303 | utf8strlen += utf8charlen; 304 | text += utf8charlen; 305 | ew += tmpw; 306 | } else { 307 | nextfont = curfont; 308 | } 309 | break; 310 | } 311 | } 312 | 313 | if (overflow || !charexists || nextfont) 314 | break; 315 | else 316 | charexists = 0; 317 | } 318 | 319 | if (utf8strlen) { 320 | if (render) { 321 | ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; 322 | XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], 323 | usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); 324 | } 325 | x += ew; 326 | w -= ew; 327 | } 328 | if (render && overflow) 329 | drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); 330 | 331 | if (!*text || overflow) { 332 | break; 333 | } else if (nextfont) { 334 | charexists = 0; 335 | usedfont = nextfont; 336 | } else { 337 | /* Regardless of whether or not a fallback font is found, the 338 | * character must be drawn. */ 339 | charexists = 1; 340 | 341 | for (i = 0; i < nomatches_len; ++i) { 342 | /* avoid calling XftFontMatch if we know we won't find a match */ 343 | if (utf8codepoint == nomatches.codepoint[i]) 344 | goto no_match; 345 | } 346 | 347 | fccharset = FcCharSetCreate(); 348 | FcCharSetAddChar(fccharset, utf8codepoint); 349 | 350 | if (!drw->fonts->pattern) { 351 | /* Refer to the comment in xfont_create for more information. */ 352 | die("the first font in the cache must be loaded from a font string."); 353 | } 354 | 355 | fcpattern = FcPatternDuplicate(drw->fonts->pattern); 356 | FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); 357 | FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); 358 | 359 | FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); 360 | FcDefaultSubstitute(fcpattern); 361 | match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); 362 | 363 | FcCharSetDestroy(fccharset); 364 | FcPatternDestroy(fcpattern); 365 | 366 | if (match) { 367 | usedfont = xfont_create(drw, NULL, match); 368 | if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { 369 | for (curfont = drw->fonts; curfont->next; curfont = curfont->next) 370 | ; /* NOP */ 371 | curfont->next = usedfont; 372 | } else { 373 | xfont_free(usedfont); 374 | nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; 375 | no_match: 376 | usedfont = drw->fonts; 377 | } 378 | } 379 | } 380 | } 381 | if (d) 382 | XftDrawDestroy(d); 383 | 384 | return x + (render ? w : 0); 385 | } 386 | 387 | void 388 | drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) 389 | { 390 | if (!drw) 391 | return; 392 | 393 | XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); 394 | XSync(drw->dpy, False); 395 | } 396 | 397 | unsigned int 398 | drw_fontset_getwidth(Drw *drw, const char *text) 399 | { 400 | if (!drw || !drw->fonts || !text) 401 | return 0; 402 | return drw_text(drw, 0, 0, 0, 0, 0, text, 0); 403 | } 404 | 405 | unsigned int 406 | drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) 407 | { 408 | unsigned int tmp = 0; 409 | if (drw && drw->fonts && text && n) 410 | tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); 411 | return MIN(n, tmp); 412 | } 413 | 414 | void 415 | drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) 416 | { 417 | XGlyphInfo ext; 418 | 419 | if (!font || !text) 420 | return; 421 | 422 | XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); 423 | if (w) 424 | *w = ext.xOff; 425 | if (h) 426 | *h = font->h; 427 | } 428 | 429 | Cur * 430 | drw_cur_create(Drw *drw, int shape) 431 | { 432 | Cur *cur; 433 | 434 | if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) 435 | return NULL; 436 | 437 | cur->cursor = XCreateFontCursor(drw->dpy, shape); 438 | 439 | return cur; 440 | } 441 | 442 | void 443 | drw_cur_free(Drw *drw, Cur *cursor) 444 | { 445 | if (!cursor) 446 | return; 447 | 448 | XFreeCursor(drw->dpy, cursor->cursor); 449 | free(cursor); 450 | } 451 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /dwm/patches/dwm-attachbottom-6.3.diff: -------------------------------------------------------------------------------- 1 | diff -up dwm-6.3/dwm.c dwm-6.3-attachbottom/dwm.c 2 | --- dwm-6.3/dwm.c 2022-01-07 12:42:18.000000000 +0100 3 | +++ dwm-6.3-attachbottom/dwm.c 2022-08-17 22:14:41.813809073 +0200 4 | @@ -147,6 +147,7 @@ static int applysizehints(Client *c, int 5 | static void arrange(Monitor *m); 6 | static void arrangemon(Monitor *m); 7 | static void attach(Client *c); 8 | +static void attachbottom(Client *c); 9 | static void attachstack(Client *c); 10 | static void buttonpress(XEvent *e); 11 | static void checkotherwm(void); 12 | @@ -408,6 +409,15 @@ attach(Client *c) 13 | } 14 | 15 | void 16 | +attachbottom(Client *c) 17 | +{ 18 | + Client **tc; 19 | + c->next = NULL; 20 | + for (tc = &c->mon->clients; *tc; tc = &(*tc)->next); 21 | + *tc = c; 22 | +} 23 | + 24 | +void 25 | attachstack(Client *c) 26 | { 27 | c->snext = c->mon->stack; 28 | @@ -1066,7 +1076,7 @@ manage(Window w, XWindowAttributes *wa) 29 | c->isfloating = c->oldstate = trans != None || c->isfixed; 30 | if (c->isfloating) 31 | XRaiseWindow(dpy, c->win); 32 | - attach(c); 33 | + attachbottom(c); 34 | attachstack(c); 35 | XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, 36 | (unsigned char *) &(c->win), 1); 37 | @@ -1421,7 +1431,7 @@ sendmon(Client *c, Monitor *m) 38 | detachstack(c); 39 | c->mon = m; 40 | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 41 | - attach(c); 42 | + attachbottom(c); 43 | attachstack(c); 44 | focus(NULL); 45 | arrange(NULL); 46 | @@ -1903,7 +1913,7 @@ updategeom(void) 47 | m->clients = c->next; 48 | detachstack(c); 49 | c->mon = mons; 50 | - attach(c); 51 | + attachbottom(c); 52 | attachstack(c); 53 | } 54 | if (m == selmon) 55 | -------------------------------------------------------------------------------- /dwm/patches/dwm-centretitle-20200907-61bb8b2.diff: -------------------------------------------------------------------------------- 1 | From fe22e3d1434be1819fe0c0200d4a20967b02f3f6 Mon Sep 17 00:00:00 2001 2 | From: Felix Chen 3 | Date: Mon, 7 Sep 2020 11:45:01 +0800 4 | Subject: [PATCH] Place title in the middle of barwin 5 | 6 | --- 7 | dwm.c | 7 +++++-- 8 | 1 file changed, 5 insertions(+), 2 deletions(-) 9 | 10 | diff --git a/dwm.c b/dwm.c 11 | index 664c527..23e94f5 100644 12 | --- a/dwm.c 13 | +++ b/dwm.c 14 | @@ -697,6 +697,7 @@ void 15 | drawbar(Monitor *m) 16 | { 17 | int x, w, tw = 0; 18 | + int tlpad; 19 | int boxs = drw->fonts->h / 9; 20 | int boxw = drw->fonts->h / 6 + 2; 21 | unsigned int i, occ = 0, urg = 0; 22 | @@ -732,9 +733,11 @@ drawbar(Monitor *m) 23 | if ((w = m->ww - tw - x) > bh) { 24 | if (m->sel) { 25 | drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 26 | - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); 27 | + tlpad = MAX((m->ww - ((int)TEXTW(m->sel->name) - lrpad)) / 2 - x, lrpad / 2); 28 | + drw_text(drw, x, 0, w, bh, tlpad, m->sel->name, 0); 29 | if (m->sel->isfloating) 30 | - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); 31 | + drw_rect(drw, x + boxs + tlpad - lrpad / 2, boxs, 32 | + boxw, boxw, m->sel->isfixed, 0); 33 | } else { 34 | drw_setscheme(drw, scheme[SchemeNorm]); 35 | drw_rect(drw, x, 0, w, bh, 1, 1); 36 | -- 37 | 2.28.0 38 | -------------------------------------------------------------------------------- /dwm/patches/dwm-dragmfact-6.2.diff: -------------------------------------------------------------------------------- 1 | From 17df87822b379ce47d0aba3c36c5ef0adf4a7c3e Mon Sep 17 00:00:00 2001 2 | From: Miles Alan 3 | Date: Sun, 8 Dec 2019 18:15:13 -0600 4 | Subject: [PATCH] Mod + Right click / drag in tiling mode to resize mfact. 5 | Works with multiple monitors. 6 | 7 | --- 8 | dwm.c | 32 +++++++++++++++++++++++--------- 9 | 1 file changed, 23 insertions(+), 9 deletions(-) 10 | 11 | diff --git a/dwm.c b/dwm.c 12 | index c15f679..e273803 100644 13 | --- a/dwm.c 14 | +++ b/dwm.c 15 | @@ -1911,7 +1911,16 @@ resizemouse(const Arg *arg) 16 | if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, 17 | None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) 18 | return; 19 | - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 20 | + 21 | + if (c->isfloating || NULL == c->mon->lt[c->mon->sellt]->arrange) { 22 | + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 23 | + } else { 24 | + XWarpPointer(dpy, None, root, 0, 0, 0, 0, 25 | + selmon->mx + (selmon->ww * selmon->mfact), 26 | + selmon->my + (selmon->wh / 2) 27 | + ); 28 | + } 29 | + 30 | do { 31 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); 32 | switch(ev.type) { 33 | @@ -1927,19 +1936,24 @@ resizemouse(const Arg *arg) 34 | 35 | nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); 36 | nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); 37 | - if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww 38 | - && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) 39 | - { 40 | - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange 41 | - && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) 42 | - togglefloating(NULL); 43 | - } 44 | + 45 | if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) 46 | resize(c, c->x, c->y, nw, nh, 1); 47 | break; 48 | } 49 | } while (ev.type != ButtonRelease); 50 | - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 51 | + 52 | + if (c->isfloating || NULL == c->mon->lt[c->mon->sellt]->arrange) { 53 | + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 54 | + } else { 55 | + selmon->mfact = (double) (ev.xmotion.x_root - selmon->mx) / (double) selmon->ww; 56 | + arrange(selmon); 57 | + XWarpPointer(dpy, None, root, 0, 0, 0, 0, 58 | + selmon->mx + (selmon->ww * selmon->mfact), 59 | + selmon->my + (selmon->wh / 2) 60 | + ); 61 | + } 62 | + 63 | XUngrabPointer(dpy, CurrentTime); 64 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 65 | if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 66 | -- 67 | 2.23.0 68 | 69 | -------------------------------------------------------------------------------- /dwm/patches/dwm-fullgaps-6.4.diff: -------------------------------------------------------------------------------- 1 | diff -up a/config.def.h b/config.def.h 2 | --- a/config.def.h 3 | +++ b/config.def.h 4 | @@ -2,6 +2,7 @@ 5 | 6 | /* appearance */ 7 | static const unsigned int borderpx = 1; /* border pixel of windows */ 8 | +static const unsigned int gappx = 5; /* gaps between windows */ 9 | static const unsigned int snap = 32; /* snap pixel */ 10 | static const int showbar = 1; /* 0 means no bar */ 11 | static const int topbar = 1; /* 0 means bottom bar */ 12 | @@ -85,6 +86,9 @@ static const Key keys[] = { 13 | { MODKEY, XK_period, focusmon, {.i = +1 } }, 14 | { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, 15 | { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, 16 | + { MODKEY, XK_minus, setgaps, {.i = -1 } }, 17 | + { MODKEY, XK_equal, setgaps, {.i = +1 } }, 18 | + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, 19 | TAGKEYS( XK_1, 0) 20 | TAGKEYS( XK_2, 1) 21 | TAGKEYS( XK_3, 2) 22 | diff -up a/dwm.c b/dwm.c 23 | --- a/dwm.c 2023-04-30 24 | +++ b/dwm.c 2023-04-30 25 | @@ -119,6 +119,7 @@ struct Monitor { 26 | int by; /* bar geometry */ 27 | int mx, my, mw, mh; /* screen size */ 28 | int wx, wy, ww, wh; /* window area */ 29 | + int gappx; /* gaps between windows */ 30 | unsigned int seltags; 31 | unsigned int sellt; 32 | unsigned int tagset[2]; 33 | @@ -200,6 +201,7 @@ static void sendmon(Client *c, Monitor * 34 | static void setclientstate(Client *c, long state); 35 | static void setfocus(Client *c); 36 | static void setfullscreen(Client *c, int fullscreen); 37 | +static void setgaps(const Arg *arg); 38 | static void setlayout(const Arg *arg); 39 | static void setmfact(const Arg *arg); 40 | static void setup(void); 41 | @@ -641,6 +643,7 @@ createmon(void) 42 | m->nmaster = nmaster; 43 | m->showbar = showbar; 44 | m->topbar = topbar; 45 | + m->gappx = gappx; 46 | m->lt[0] = &layouts[0]; 47 | m->lt[1] = &layouts[1 % LENGTH(layouts)]; 48 | strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 49 | @@ -1508,6 +1511,16 @@ setfullscreen(Client *c, int fullscreen) 50 | } 51 | 52 | void 53 | +setgaps(const Arg *arg) 54 | +{ 55 | + if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) 56 | + selmon->gappx = 0; 57 | + else 58 | + selmon->gappx += arg->i; 59 | + arrange(selmon); 60 | +} 61 | + 62 | +void 63 | setlayout(const Arg *arg) 64 | { 65 | if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 66 | @@ -1697,18 +1710,18 @@ tile(Monitor *m) 67 | if (n > m->nmaster) 68 | mw = m->nmaster ? m->ww * m->mfact : 0; 69 | else 70 | - mw = m->ww; 71 | - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 72 | - if (i < m->nmaster) { 73 | - h = (m->wh - my) / (MIN(n, m->nmaster) - i); 74 | - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); 75 | - if (my + HEIGHT(c) < m->wh) 76 | - my += HEIGHT(c); 77 | + mw = m->ww - m->gappx; 78 | + for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 79 | + if (i < m->nmaster) { 80 | + h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; 81 | + resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); 82 | + if (my + HEIGHT(c) + m->gappx < m->wh) 83 | + my += HEIGHT(c) + m->gappx; 84 | } else { 85 | - h = (m->wh - ty) / (n - i); 86 | - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); 87 | - if (ty + HEIGHT(c) < m->wh) 88 | - ty += HEIGHT(c); 89 | + h = (m->wh - ty) / (n - i) - m->gappx; 90 | + resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); 91 | + if (ty + HEIGHT(c) + m->gappx < m->wh) 92 | + ty += HEIGHT(c) + m->gappx; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /dwm/patches/dwm-preserveonrestart-6.3.diff: -------------------------------------------------------------------------------- 1 | From 713fa8650f5a20006451ebcccf57a4512e83bae8 Mon Sep 17 00:00:00 2001 2 | From: Arda Atci 3 | Date: Wed, 18 May 2022 17:23:16 +0300 4 | Subject: [PATCH] preserve clients on old tags when renewing dwm 5 | 6 | By default, when dwm is recompiled-restarted all clients will 7 | lose it's current tag and collapse to first tag. This patch preserves 8 | clients on old tags, however note that layout order is not preserved. 9 | 10 | --- 11 | dwm.c | 38 +++++++++++++++++++++++++++++++++++++- 12 | 1 file changed, 37 insertions(+), 1 deletion(-) 13 | 14 | diff --git a/dwm.c b/dwm.c 15 | index a96f33c..a12e0bd 100644 16 | --- a/dwm.c 17 | +++ b/dwm.c 18 | @@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 19 | enum { SchemeNorm, SchemeSel }; /* color schemes */ 20 | enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 21 | NetWMFullscreen, NetActiveWindow, NetWMWindowType, 22 | - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 23 | + NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */ 24 | enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 25 | enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 26 | ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 27 | @@ -198,6 +198,7 @@ static void scan(void); 28 | static int sendevent(Client *c, Atom proto); 29 | static void sendmon(Client *c, Monitor *m); 30 | static void setclientstate(Client *c, long state); 31 | +static void setclienttagprop(Client *c); 32 | static void setfocus(Client *c); 33 | static void setfullscreen(Client *c, int fullscreen); 34 | static void setlayout(const Arg *arg); 35 | @@ -1060,6 +1061,26 @@ manage(Window w, XWindowAttributes *wa) 36 | updatewindowtype(c); 37 | updatesizehints(c); 38 | updatewmhints(c); 39 | + { 40 | + int format; 41 | + unsigned long *data, n, extra; 42 | + Monitor *m; 43 | + Atom atom; 44 | + if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL, 45 | + &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) { 46 | + c->tags = *data; 47 | + for (m = mons; m; m = m->next) { 48 | + if (m->num == *(data+1)) { 49 | + c->mon = m; 50 | + break; 51 | + } 52 | + } 53 | + } 54 | + if (n > 0) 55 | + XFree(data); 56 | + } 57 | + setclienttagprop(c); 58 | + 59 | XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); 60 | grabbuttons(c, 0); 61 | if (!c->isfloating) 62 | @@ -1423,6 +1444,7 @@ sendmon(Client *c, Monitor *m) 63 | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 64 | attach(c); 65 | attachstack(c); 66 | + setclienttagprop(c); 67 | focus(NULL); 68 | arrange(NULL); 69 | } 70 | @@ -1566,6 +1588,7 @@ setup(void) 71 | netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 72 | netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 73 | netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); 74 | + netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False); 75 | /* init cursors */ 76 | cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); 77 | cursor[CurResize] = drw_cur_create(drw, XC_sizing); 78 | @@ -1589,6 +1612,7 @@ setup(void) 79 | XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, 80 | PropModeReplace, (unsigned char *) netatom, NetLast); 81 | XDeleteProperty(dpy, root, netatom[NetClientList]); 82 | + XDeleteProperty(dpy, root, netatom[NetClientInfo]); 83 | /* select events */ 84 | wa.cursor = cursor[CurNormal]->cursor; 85 | wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask 86 | @@ -1656,11 +1680,22 @@ spawn(const Arg *arg) 87 | } 88 | } 89 | 90 | +void 91 | +setclienttagprop(Client *c) 92 | +{ 93 | + long data[] = { (long) c->tags, (long) c->mon->num }; 94 | + XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32, 95 | + PropModeReplace, (unsigned char *) data, 2); 96 | +} 97 | + 98 | void 99 | tag(const Arg *arg) 100 | { 101 | + Client *c; 102 | if (selmon->sel && arg->ui & TAGMASK) { 103 | + c = selmon->sel; 104 | selmon->sel->tags = arg->ui & TAGMASK; 105 | + setclienttagprop(c); 106 | focus(NULL); 107 | arrange(selmon); 108 | } 109 | @@ -1735,6 +1770,7 @@ toggletag(const Arg *arg) 110 | newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 111 | if (newtags) { 112 | selmon->sel->tags = newtags; 113 | + setclienttagprop(selmon->sel); 114 | focus(NULL); 115 | arrange(selmon); 116 | } 117 | -- 118 | 2.36.1 119 | -------------------------------------------------------------------------------- /dwm/patches/dwm-restartsig-20180523-6.2.diff: -------------------------------------------------------------------------------- 1 | From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001 2 | From: Christopher Drelich 3 | Date: Wed, 23 May 2018 22:50:38 -0400 4 | Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM 5 | handlers. 6 | 7 | Modified quit() to restart if it receives arg .i = 1 8 | MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that. 9 | 10 | Signal handlers were handled for SIGHUP and SIGTERM. 11 | If dwm receives these signals it calls quit() with 12 | arg .i = to 1 or 0, respectively. 13 | 14 | To restart dwm: 15 | MOD+CTRL+SHIFT+Q 16 | or 17 | kill -HUP dwmpid 18 | 19 | To quit dwm cleanly: 20 | MOD+SHIFT+Q 21 | or 22 | kill -TERM dwmpid 23 | --- 24 | config.def.h | 1 + 25 | dwm.1 | 10 ++++++++++ 26 | dwm.c | 22 ++++++++++++++++++++++ 27 | 3 files changed, 33 insertions(+) 28 | 29 | diff --git a/config.def.h b/config.def.h 30 | index a9ac303..e559429 100644 31 | --- a/config.def.h 32 | +++ b/config.def.h 33 | @@ -94,6 +94,7 @@ static Key keys[] = { 34 | TAGKEYS( XK_8, 7) 35 | TAGKEYS( XK_9, 8) 36 | { MODKEY|ShiftMask, XK_q, quit, {0} }, 37 | + { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, 38 | }; 39 | 40 | /* button definitions */ 41 | diff --git a/dwm.1 b/dwm.1 42 | index 13b3729..36a331c 100644 43 | --- a/dwm.1 44 | +++ b/dwm.1 45 | @@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view. 46 | .TP 47 | .B Mod1\-Shift\-q 48 | Quit dwm. 49 | +.TP 50 | +.B Mod1\-Control\-Shift\-q 51 | +Restart dwm. 52 | .SS Mouse commands 53 | .TP 54 | .B Mod1\-Button1 55 | @@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float 56 | .SH CUSTOMIZATION 57 | dwm is customized by creating a custom config.h and (re)compiling the source 58 | code. This keeps it fast, secure and simple. 59 | +.SH SIGNALS 60 | +.TP 61 | +.B SIGHUP - 1 62 | +Restart the dwm process. 63 | +.TP 64 | +.B SIGTERM - 15 65 | +Cleanly terminate the dwm process. 66 | .SH SEE ALSO 67 | .BR dmenu (1), 68 | .BR st (1) 69 | diff --git a/dwm.c b/dwm.c 70 | index bb95e26..286eecd 100644 71 | --- a/dwm.c 72 | +++ b/dwm.c 73 | @@ -205,6 +205,8 @@ static void setup(void); 74 | static void seturgent(Client *c, int urg); 75 | static void showhide(Client *c); 76 | static void sigchld(int unused); 77 | +static void sighup(int unused); 78 | +static void sigterm(int unused); 79 | static void spawn(const Arg *arg); 80 | static void tag(const Arg *arg); 81 | static void tagmon(const Arg *arg); 82 | @@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { 83 | [UnmapNotify] = unmapnotify 84 | }; 85 | static Atom wmatom[WMLast], netatom[NetLast]; 86 | +static int restart = 0; 87 | static int running = 1; 88 | static Cur *cursor[CurLast]; 89 | static Clr **scheme; 90 | @@ -1248,6 +1251,7 @@ propertynotify(XEvent *e) 91 | void 92 | quit(const Arg *arg) 93 | { 94 | + if(arg->i) restart = 1; 95 | running = 0; 96 | } 97 | 98 | @@ -1536,6 +1540,9 @@ setup(void) 99 | /* clean up any zombies immediately */ 100 | sigchld(0); 101 | 102 | + signal(SIGHUP, sighup); 103 | + signal(SIGTERM, sigterm); 104 | + 105 | /* init screen */ 106 | screen = DefaultScreen(dpy); 107 | sw = DisplayWidth(dpy, screen); 108 | @@ -1637,6 +1644,20 @@ sigchld(int unused) 109 | } 110 | 111 | void 112 | +sighup(int unused) 113 | +{ 114 | + Arg a = {.i = 1}; 115 | + quit(&a); 116 | +} 117 | + 118 | +void 119 | +sigterm(int unused) 120 | +{ 121 | + Arg a = {.i = 0}; 122 | + quit(&a); 123 | +} 124 | + 125 | +void 126 | spawn(const Arg *arg) 127 | { 128 | if (arg->v == dmenucmd) 129 | @@ -2139,6 +2160,7 @@ main(int argc, char *argv[]) 130 | setup(); 131 | scan(); 132 | run(); 133 | + if(restart) execvp(argv[0], argv); 134 | cleanup(); 135 | XCloseDisplay(dpy); 136 | return EXIT_SUCCESS; 137 | -- 138 | 2.7.4 139 | 140 | -------------------------------------------------------------------------------- /dwm/patches/dwm-savefloats-20181212-b69c870.diff: -------------------------------------------------------------------------------- 1 | diff --git i/dwm.c w/dwm.c 2 | index 4465af1..96b0b26 100644 3 | --- i/dwm.c 4 | +++ w/dwm.c 5 | @@ -88,6 +88,7 @@ struct Client { 6 | char name[256]; 7 | float mina, maxa; 8 | int x, y, w, h; 9 | + int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */ 10 | int oldx, oldy, oldw, oldh; 11 | int basew, baseh, incw, inch, maxw, maxh, minw, minh; 12 | int bw, oldbw; 13 | @@ -1056,6 +1057,10 @@ manage(Window w, XWindowAttributes *wa) 14 | updatewindowtype(c); 15 | updatesizehints(c); 16 | updatewmhints(c); 17 | + c->sfx = c->x; 18 | + c->sfy = c->y; 19 | + c->sfw = c->w; 20 | + c->sfh = c->h; 21 | XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); 22 | grabbuttons(c, 0); 23 | if (!c->isfloating) 24 | @@ -1714,8 +1719,16 @@ togglefloating(const Arg *arg) 25 | return; 26 | selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; 27 | if (selmon->sel->isfloating) 28 | - resize(selmon->sel, selmon->sel->x, selmon->sel->y, 29 | - selmon->sel->w, selmon->sel->h, 0); 30 | + /* restore last known float dimensions */ 31 | + resize(selmon->sel, selmon->sel->sfx, selmon->sel->sfy, 32 | + selmon->sel->sfw, selmon->sel->sfh, False); 33 | + else { 34 | + /* save last known float dimensions */ 35 | + selmon->sel->sfx = selmon->sel->x; 36 | + selmon->sel->sfy = selmon->sel->y; 37 | + selmon->sel->sfw = selmon->sel->w; 38 | + selmon->sel->sfh = selmon->sel->h; 39 | + } 40 | arrange(selmon); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /dwm/patches/dwm-systray-20230922-9f88553.diff: -------------------------------------------------------------------------------- 1 | diff --git a/config.def.h b/config.def.h 2 | index 9efa774..fed4fb9 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 systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ 10 | +static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ 11 | +static const unsigned int systrayspacing = 2; /* systray spacing */ 12 | +static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ 13 | +static const int showsystray = 1; /* 0 means no systray */ 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 | diff --git a/dwm.c b/dwm.c 18 | index f1d86b2..f9e7e4a 100644 19 | --- a/dwm.c 20 | +++ b/dwm.c 21 | @@ -57,12 +57,27 @@ 22 | #define TAGMASK ((1 << LENGTH(tags)) - 1) 23 | #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) 24 | 25 | +#define SYSTEM_TRAY_REQUEST_DOCK 0 26 | +/* XEMBED messages */ 27 | +#define XEMBED_EMBEDDED_NOTIFY 0 28 | +#define XEMBED_WINDOW_ACTIVATE 1 29 | +#define XEMBED_FOCUS_IN 4 30 | +#define XEMBED_MODALITY_ON 10 31 | +#define XEMBED_MAPPED (1 << 0) 32 | +#define XEMBED_WINDOW_ACTIVATE 1 33 | +#define XEMBED_WINDOW_DEACTIVATE 2 34 | +#define VERSION_MAJOR 0 35 | +#define VERSION_MINOR 0 36 | +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR 37 | + 38 | /* enums */ 39 | enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 40 | enum { SchemeNorm, SchemeSel }; /* color schemes */ 41 | enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 42 | + NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, 43 | NetWMFullscreen, NetActiveWindow, NetWMWindowType, 44 | NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 45 | +enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ 46 | enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 47 | enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 48 | ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 49 | @@ -141,6 +156,12 @@ typedef struct { 50 | int monitor; 51 | } Rule; 52 | 53 | +typedef struct Systray Systray; 54 | +struct Systray { 55 | + Window win; 56 | + Client *icons; 57 | +}; 58 | + 59 | /* function declarations */ 60 | static void applyrules(Client *c); 61 | static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); 62 | @@ -172,6 +193,7 @@ static void focusstack(const Arg *arg); 63 | static Atom getatomprop(Client *c, Atom prop); 64 | static int getrootptr(int *x, int *y); 65 | static long getstate(Window w); 66 | +static unsigned int getsystraywidth(); 67 | static int gettextprop(Window w, Atom atom, char *text, unsigned int size); 68 | static void grabbuttons(Client *c, int focused); 69 | static void grabkeys(void); 70 | @@ -189,13 +211,16 @@ static void pop(Client *c); 71 | static void propertynotify(XEvent *e); 72 | static void quit(const Arg *arg); 73 | static Monitor *recttomon(int x, int y, int w, int h); 74 | +static void removesystrayicon(Client *i); 75 | static void resize(Client *c, int x, int y, int w, int h, int interact); 76 | +static void resizebarwin(Monitor *m); 77 | static void resizeclient(Client *c, int x, int y, int w, int h); 78 | static void resizemouse(const Arg *arg); 79 | +static void resizerequest(XEvent *e); 80 | static void restack(Monitor *m); 81 | static void run(void); 82 | static void scan(void); 83 | -static int sendevent(Client *c, Atom proto); 84 | +static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); 85 | static void sendmon(Client *c, Monitor *m); 86 | static void setclientstate(Client *c, long state); 87 | static void setfocus(Client *c); 88 | @@ -206,6 +231,7 @@ static void setup(void); 89 | static void seturgent(Client *c, int urg); 90 | static void showhide(Client *c); 91 | static void spawn(const Arg *arg); 92 | +static Monitor *systraytomon(Monitor *m); 93 | static void tag(const Arg *arg); 94 | static void tagmon(const Arg *arg); 95 | static void tile(Monitor *m); 96 | @@ -223,18 +249,23 @@ static int updategeom(void); 97 | static void updatenumlockmask(void); 98 | static void updatesizehints(Client *c); 99 | static void updatestatus(void); 100 | +static void updatesystray(void); 101 | +static void updatesystrayicongeom(Client *i, int w, int h); 102 | +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); 103 | static void updatetitle(Client *c); 104 | static void updatewindowtype(Client *c); 105 | static void updatewmhints(Client *c); 106 | static void view(const Arg *arg); 107 | static Client *wintoclient(Window w); 108 | static Monitor *wintomon(Window w); 109 | +static Client *wintosystrayicon(Window w); 110 | static int xerror(Display *dpy, XErrorEvent *ee); 111 | static int xerrordummy(Display *dpy, XErrorEvent *ee); 112 | static int xerrorstart(Display *dpy, XErrorEvent *ee); 113 | static void zoom(const Arg *arg); 114 | 115 | /* variables */ 116 | +static Systray *systray = NULL; 117 | static const char broken[] = "broken"; 118 | static char stext[256]; 119 | static int screen; 120 | @@ -257,9 +288,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { 121 | [MapRequest] = maprequest, 122 | [MotionNotify] = motionnotify, 123 | [PropertyNotify] = propertynotify, 124 | + [ResizeRequest] = resizerequest, 125 | [UnmapNotify] = unmapnotify 126 | }; 127 | -static Atom wmatom[WMLast], netatom[NetLast]; 128 | +static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; 129 | static int running = 1; 130 | static Cur *cursor[CurLast]; 131 | static Clr **scheme; 132 | @@ -441,7 +473,7 @@ buttonpress(XEvent *e) 133 | arg.ui = 1 << i; 134 | } else if (ev->x < x + TEXTW(selmon->ltsymbol)) 135 | click = ClkLtSymbol; 136 | - else if (ev->x > selmon->ww - (int)TEXTW(stext)) 137 | + else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) 138 | click = ClkStatusText; 139 | else 140 | click = ClkWinTitle; 141 | @@ -484,6 +516,13 @@ cleanup(void) 142 | XUngrabKey(dpy, AnyKey, AnyModifier, root); 143 | while (mons) 144 | cleanupmon(mons); 145 | + 146 | + if (showsystray) { 147 | + XUnmapWindow(dpy, systray->win); 148 | + XDestroyWindow(dpy, systray->win); 149 | + free(systray); 150 | + } 151 | + 152 | for (i = 0; i < CurLast; i++) 153 | drw_cur_free(drw, cursor[i]); 154 | for (i = 0; i < LENGTH(colors); i++) 155 | @@ -515,9 +554,58 @@ cleanupmon(Monitor *mon) 156 | void 157 | clientmessage(XEvent *e) 158 | { 159 | + XWindowAttributes wa; 160 | + XSetWindowAttributes swa; 161 | XClientMessageEvent *cme = &e->xclient; 162 | Client *c = wintoclient(cme->window); 163 | 164 | + if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { 165 | + /* add systray icons */ 166 | + if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { 167 | + if (!(c = (Client *)calloc(1, sizeof(Client)))) 168 | + die("fatal: could not malloc() %u bytes\n", sizeof(Client)); 169 | + if (!(c->win = cme->data.l[2])) { 170 | + free(c); 171 | + return; 172 | + } 173 | + c->mon = selmon; 174 | + c->next = systray->icons; 175 | + systray->icons = c; 176 | + if (!XGetWindowAttributes(dpy, c->win, &wa)) { 177 | + /* use sane defaults */ 178 | + wa.width = bh; 179 | + wa.height = bh; 180 | + wa.border_width = 0; 181 | + } 182 | + c->x = c->oldx = c->y = c->oldy = 0; 183 | + c->w = c->oldw = wa.width; 184 | + c->h = c->oldh = wa.height; 185 | + c->oldbw = wa.border_width; 186 | + c->bw = 0; 187 | + c->isfloating = True; 188 | + /* reuse tags field as mapped status */ 189 | + c->tags = 1; 190 | + updatesizehints(c); 191 | + updatesystrayicongeom(c, wa.width, wa.height); 192 | + XAddToSaveSet(dpy, c->win); 193 | + XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); 194 | + XReparentWindow(dpy, c->win, systray->win, 0, 0); 195 | + /* use parents background color */ 196 | + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 197 | + XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); 198 | + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 199 | + /* FIXME not sure if I have to send these events, too */ 200 | + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 201 | + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 202 | + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 203 | + XSync(dpy, False); 204 | + resizebarwin(selmon); 205 | + updatesystray(); 206 | + setclientstate(c, NormalState); 207 | + } 208 | + return; 209 | + } 210 | + 211 | if (!c) 212 | return; 213 | if (cme->message_type == netatom[NetWMState]) { 214 | @@ -570,7 +658,7 @@ configurenotify(XEvent *e) 215 | for (c = m->clients; c; c = c->next) 216 | if (c->isfullscreen) 217 | resizeclient(c, m->mx, m->my, m->mw, m->mh); 218 | - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); 219 | + resizebarwin(m); 220 | } 221 | focus(NULL); 222 | arrange(NULL); 223 | @@ -655,6 +743,11 @@ destroynotify(XEvent *e) 224 | 225 | if ((c = wintoclient(ev->window))) 226 | unmanage(c, 1); 227 | + else if ((c = wintosystrayicon(ev->window))) { 228 | + removesystrayicon(c); 229 | + resizebarwin(selmon); 230 | + updatesystray(); 231 | + } 232 | } 233 | 234 | void 235 | @@ -698,7 +791,7 @@ dirtomon(int dir) 236 | void 237 | drawbar(Monitor *m) 238 | { 239 | - int x, w, tw = 0; 240 | + int x, w, tw = 0, stw = 0; 241 | int boxs = drw->fonts->h / 9; 242 | int boxw = drw->fonts->h / 6 + 2; 243 | unsigned int i, occ = 0, urg = 0; 244 | @@ -707,13 +800,17 @@ drawbar(Monitor *m) 245 | if (!m->showbar) 246 | return; 247 | 248 | + if(showsystray && m == systraytomon(m) && !systrayonleft) 249 | + stw = getsystraywidth(); 250 | + 251 | /* draw status first so it can be overdrawn by tags later */ 252 | if (m == selmon) { /* status is only drawn on selected monitor */ 253 | drw_setscheme(drw, scheme[SchemeNorm]); 254 | - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 255 | - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); 256 | + tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */ 257 | + drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); 258 | } 259 | 260 | + resizebarwin(m); 261 | for (c = m->clients; c; c = c->next) { 262 | occ |= c->tags; 263 | if (c->isurgent) 264 | @@ -734,7 +831,7 @@ drawbar(Monitor *m) 265 | drw_setscheme(drw, scheme[SchemeNorm]); 266 | x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); 267 | 268 | - if ((w = m->ww - tw - x) > bh) { 269 | + if ((w = m->ww - tw - stw - x) > bh) { 270 | if (m->sel) { 271 | drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 272 | drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); 273 | @@ -745,7 +842,7 @@ drawbar(Monitor *m) 274 | drw_rect(drw, x, 0, w, bh, 1, 1); 275 | } 276 | } 277 | - drw_map(drw, m->barwin, 0, 0, m->ww, bh); 278 | + drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); 279 | } 280 | 281 | void 282 | @@ -782,8 +879,11 @@ expose(XEvent *e) 283 | Monitor *m; 284 | XExposeEvent *ev = &e->xexpose; 285 | 286 | - if (ev->count == 0 && (m = wintomon(ev->window))) 287 | + if (ev->count == 0 && (m = wintomon(ev->window))) { 288 | drawbar(m); 289 | + if (m == selmon) 290 | + updatesystray(); 291 | + } 292 | } 293 | 294 | void 295 | @@ -869,14 +969,32 @@ getatomprop(Client *c, Atom prop) 296 | unsigned char *p = NULL; 297 | Atom da, atom = None; 298 | 299 | - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, 300 | + /* FIXME getatomprop should return the number of items and a pointer to 301 | + * the stored data instead of this workaround */ 302 | + Atom req = XA_ATOM; 303 | + if (prop == xatom[XembedInfo]) 304 | + req = xatom[XembedInfo]; 305 | + 306 | + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, 307 | &da, &di, &dl, &dl, &p) == Success && p) { 308 | atom = *(Atom *)p; 309 | + if (da == xatom[XembedInfo] && dl == 2) 310 | + atom = ((Atom *)p)[1]; 311 | XFree(p); 312 | } 313 | return atom; 314 | } 315 | 316 | +unsigned int 317 | +getsystraywidth() 318 | +{ 319 | + unsigned int w = 0; 320 | + Client *i; 321 | + if(showsystray) 322 | + for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; 323 | + return w ? w + systrayspacing : 1; 324 | +} 325 | + 326 | int 327 | getrootptr(int *x, int *y) 328 | { 329 | @@ -1017,7 +1135,8 @@ killclient(const Arg *arg) 330 | { 331 | if (!selmon->sel) 332 | return; 333 | - if (!sendevent(selmon->sel, wmatom[WMDelete])) { 334 | + 335 | + if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { 336 | XGrabServer(dpy); 337 | XSetErrorHandler(xerrordummy); 338 | XSetCloseDownMode(dpy, DestroyAll); 339 | @@ -1104,6 +1223,13 @@ maprequest(XEvent *e) 340 | static XWindowAttributes wa; 341 | XMapRequestEvent *ev = &e->xmaprequest; 342 | 343 | + Client *i; 344 | + if ((i = wintosystrayicon(ev->window))) { 345 | + sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); 346 | + resizebarwin(selmon); 347 | + updatesystray(); 348 | + } 349 | + 350 | if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) 351 | return; 352 | if (!wintoclient(ev->window)) 353 | @@ -1225,6 +1351,17 @@ propertynotify(XEvent *e) 354 | Window trans; 355 | XPropertyEvent *ev = &e->xproperty; 356 | 357 | + if ((c = wintosystrayicon(ev->window))) { 358 | + if (ev->atom == XA_WM_NORMAL_HINTS) { 359 | + updatesizehints(c); 360 | + updatesystrayicongeom(c, c->w, c->h); 361 | + } 362 | + else 363 | + updatesystrayiconstate(c, ev); 364 | + resizebarwin(selmon); 365 | + updatesystray(); 366 | + } 367 | + 368 | if ((ev->window == root) && (ev->atom == XA_WM_NAME)) 369 | updatestatus(); 370 | else if (ev->state == PropertyDelete) 371 | @@ -1275,6 +1412,19 @@ recttomon(int x, int y, int w, int h) 372 | return r; 373 | } 374 | 375 | +void 376 | +removesystrayicon(Client *i) 377 | +{ 378 | + Client **ii; 379 | + 380 | + if (!showsystray || !i) 381 | + return; 382 | + for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); 383 | + if (ii) 384 | + *ii = i->next; 385 | + free(i); 386 | +} 387 | + 388 | void 389 | resize(Client *c, int x, int y, int w, int h, int interact) 390 | { 391 | @@ -1282,6 +1432,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) 392 | resizeclient(c, x, y, w, h); 393 | } 394 | 395 | +void 396 | +resizebarwin(Monitor *m) { 397 | + unsigned int w = m->ww; 398 | + if (showsystray && m == systraytomon(m) && !systrayonleft) 399 | + w -= getsystraywidth(); 400 | + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); 401 | +} 402 | + 403 | void 404 | resizeclient(Client *c, int x, int y, int w, int h) 405 | { 406 | @@ -1297,6 +1455,19 @@ resizeclient(Client *c, int x, int y, int w, int h) 407 | XSync(dpy, False); 408 | } 409 | 410 | +void 411 | +resizerequest(XEvent *e) 412 | +{ 413 | + XResizeRequestEvent *ev = &e->xresizerequest; 414 | + Client *i; 415 | + 416 | + if ((i = wintosystrayicon(ev->window))) { 417 | + updatesystrayicongeom(i, ev->width, ev->height); 418 | + resizebarwin(selmon); 419 | + updatesystray(); 420 | + } 421 | +} 422 | + 423 | void 424 | resizemouse(const Arg *arg) 425 | { 426 | @@ -1443,26 +1614,37 @@ setclientstate(Client *c, long state) 427 | } 428 | 429 | int 430 | -sendevent(Client *c, Atom proto) 431 | +sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) 432 | { 433 | int n; 434 | - Atom *protocols; 435 | + Atom *protocols, mt; 436 | int exists = 0; 437 | XEvent ev; 438 | 439 | - if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { 440 | - while (!exists && n--) 441 | - exists = protocols[n] == proto; 442 | - XFree(protocols); 443 | + if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { 444 | + mt = wmatom[WMProtocols]; 445 | + if (XGetWMProtocols(dpy, w, &protocols, &n)) { 446 | + while (!exists && n--) 447 | + exists = protocols[n] == proto; 448 | + XFree(protocols); 449 | + } 450 | + } 451 | + else { 452 | + exists = True; 453 | + mt = proto; 454 | } 455 | + 456 | if (exists) { 457 | ev.type = ClientMessage; 458 | - ev.xclient.window = c->win; 459 | - ev.xclient.message_type = wmatom[WMProtocols]; 460 | + ev.xclient.window = w; 461 | + ev.xclient.message_type = mt; 462 | ev.xclient.format = 32; 463 | - ev.xclient.data.l[0] = proto; 464 | - ev.xclient.data.l[1] = CurrentTime; 465 | - XSendEvent(dpy, c->win, False, NoEventMask, &ev); 466 | + ev.xclient.data.l[0] = d0; 467 | + ev.xclient.data.l[1] = d1; 468 | + ev.xclient.data.l[2] = d2; 469 | + ev.xclient.data.l[3] = d3; 470 | + ev.xclient.data.l[4] = d4; 471 | + XSendEvent(dpy, w, False, mask, &ev); 472 | } 473 | return exists; 474 | } 475 | @@ -1476,7 +1658,7 @@ setfocus(Client *c) 476 | XA_WINDOW, 32, PropModeReplace, 477 | (unsigned char *) &(c->win), 1); 478 | } 479 | - sendevent(c, wmatom[WMTakeFocus]); 480 | + sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); 481 | } 482 | 483 | void 484 | @@ -1572,6 +1754,10 @@ setup(void) 485 | wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); 486 | netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); 487 | netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); 488 | + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); 489 | + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); 490 | + netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); 491 | + netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); 492 | netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); 493 | netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); 494 | netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); 495 | @@ -1579,6 +1765,9 @@ setup(void) 496 | netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 497 | netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 498 | netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); 499 | + xatom[Manager] = XInternAtom(dpy, "MANAGER", False); 500 | + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); 501 | + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); 502 | /* init cursors */ 503 | cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); 504 | cursor[CurResize] = drw_cur_create(drw, XC_sizing); 505 | @@ -1587,6 +1776,8 @@ setup(void) 506 | scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); 507 | for (i = 0; i < LENGTH(colors); i++) 508 | scheme[i] = drw_scm_create(drw, colors[i], 3); 509 | + /* init system tray */ 510 | + updatesystray(); 511 | /* init bars */ 512 | updatebars(); 513 | updatestatus(); 514 | @@ -1717,7 +1908,18 @@ togglebar(const Arg *arg) 515 | { 516 | selmon->showbar = !selmon->showbar; 517 | updatebarpos(selmon); 518 | - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 519 | + resizebarwin(selmon); 520 | + if (showsystray) { 521 | + XWindowChanges wc; 522 | + if (!selmon->showbar) 523 | + wc.y = -bh; 524 | + else if (selmon->showbar) { 525 | + wc.y = 0; 526 | + if (!selmon->topbar) 527 | + wc.y = selmon->mh - bh; 528 | + } 529 | + XConfigureWindow(dpy, systray->win, CWY, &wc); 530 | + } 531 | arrange(selmon); 532 | } 533 | 534 | @@ -1813,11 +2015,18 @@ unmapnotify(XEvent *e) 535 | else 536 | unmanage(c, 0); 537 | } 538 | + else if ((c = wintosystrayicon(ev->window))) { 539 | + /* KLUDGE! sometimes icons occasionally unmap their windows, but do 540 | + * _not_ destroy them. We map those windows back */ 541 | + XMapRaised(dpy, c->win); 542 | + updatesystray(); 543 | + } 544 | } 545 | 546 | void 547 | updatebars(void) 548 | { 549 | + unsigned int w; 550 | Monitor *m; 551 | XSetWindowAttributes wa = { 552 | .override_redirect = True, 553 | @@ -1828,10 +2037,15 @@ updatebars(void) 554 | for (m = mons; m; m = m->next) { 555 | if (m->barwin) 556 | continue; 557 | - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), 558 | + w = m->ww; 559 | + if (showsystray && m == systraytomon(m)) 560 | + w -= getsystraywidth(); 561 | + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), 562 | CopyFromParent, DefaultVisual(dpy, screen), 563 | CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 564 | XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 565 | + if (showsystray && m == systraytomon(m)) 566 | + XMapRaised(dpy, systray->win); 567 | XMapRaised(dpy, m->barwin); 568 | XSetClassHint(dpy, m->barwin, &ch); 569 | } 570 | @@ -2008,6 +2222,125 @@ updatestatus(void) 571 | if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 572 | strcpy(stext, "dwm-"VERSION); 573 | drawbar(selmon); 574 | + updatesystray(); 575 | +} 576 | + 577 | + 578 | +void 579 | +updatesystrayicongeom(Client *i, int w, int h) 580 | +{ 581 | + if (i) { 582 | + i->h = bh; 583 | + if (w == h) 584 | + i->w = bh; 585 | + else if (h == bh) 586 | + i->w = w; 587 | + else 588 | + i->w = (int) ((float)bh * ((float)w / (float)h)); 589 | + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); 590 | + /* force icons into the systray dimensions if they don't want to */ 591 | + if (i->h > bh) { 592 | + if (i->w == i->h) 593 | + i->w = bh; 594 | + else 595 | + i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); 596 | + i->h = bh; 597 | + } 598 | + } 599 | +} 600 | + 601 | +void 602 | +updatesystrayiconstate(Client *i, XPropertyEvent *ev) 603 | +{ 604 | + long flags; 605 | + int code = 0; 606 | + 607 | + if (!showsystray || !i || ev->atom != xatom[XembedInfo] || 608 | + !(flags = getatomprop(i, xatom[XembedInfo]))) 609 | + return; 610 | + 611 | + if (flags & XEMBED_MAPPED && !i->tags) { 612 | + i->tags = 1; 613 | + code = XEMBED_WINDOW_ACTIVATE; 614 | + XMapRaised(dpy, i->win); 615 | + setclientstate(i, NormalState); 616 | + } 617 | + else if (!(flags & XEMBED_MAPPED) && i->tags) { 618 | + i->tags = 0; 619 | + code = XEMBED_WINDOW_DEACTIVATE; 620 | + XUnmapWindow(dpy, i->win); 621 | + setclientstate(i, WithdrawnState); 622 | + } 623 | + else 624 | + return; 625 | + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, 626 | + systray->win, XEMBED_EMBEDDED_VERSION); 627 | +} 628 | + 629 | +void 630 | +updatesystray(void) 631 | +{ 632 | + XSetWindowAttributes wa; 633 | + XWindowChanges wc; 634 | + Client *i; 635 | + Monitor *m = systraytomon(NULL); 636 | + unsigned int x = m->mx + m->mw; 637 | + unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; 638 | + unsigned int w = 1; 639 | + 640 | + if (!showsystray) 641 | + return; 642 | + if (systrayonleft) 643 | + x -= sw + lrpad / 2; 644 | + if (!systray) { 645 | + /* init systray */ 646 | + if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) 647 | + die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); 648 | + systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); 649 | + wa.event_mask = ButtonPressMask | ExposureMask; 650 | + wa.override_redirect = True; 651 | + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 652 | + XSelectInput(dpy, systray->win, SubstructureNotifyMask); 653 | + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, 654 | + PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); 655 | + XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); 656 | + XMapRaised(dpy, systray->win); 657 | + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); 658 | + if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { 659 | + sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); 660 | + XSync(dpy, False); 661 | + } 662 | + else { 663 | + fprintf(stderr, "dwm: unable to obtain system tray.\n"); 664 | + free(systray); 665 | + systray = NULL; 666 | + return; 667 | + } 668 | + } 669 | + for (w = 0, i = systray->icons; i; i = i->next) { 670 | + /* make sure the background color stays the same */ 671 | + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 672 | + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); 673 | + XMapRaised(dpy, i->win); 674 | + w += systrayspacing; 675 | + i->x = w; 676 | + XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); 677 | + w += i->w; 678 | + if (i->mon != m) 679 | + i->mon = m; 680 | + } 681 | + w = w ? w + systrayspacing : 1; 682 | + x -= w; 683 | + XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); 684 | + wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; 685 | + wc.stack_mode = Above; wc.sibling = m->barwin; 686 | + XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); 687 | + XMapWindow(dpy, systray->win); 688 | + XMapSubwindows(dpy, systray->win); 689 | + /* redraw background */ 690 | + XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); 691 | + XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); 692 | + XSync(dpy, False); 693 | } 694 | 695 | void 696 | @@ -2075,6 +2408,16 @@ wintoclient(Window w) 697 | return NULL; 698 | } 699 | 700 | +Client * 701 | +wintosystrayicon(Window w) { 702 | + Client *i = NULL; 703 | + 704 | + if (!showsystray || !w) 705 | + return i; 706 | + for (i = systray->icons; i && i->win != w; i = i->next) ; 707 | + return i; 708 | +} 709 | + 710 | Monitor * 711 | wintomon(Window w) 712 | { 713 | @@ -2128,6 +2471,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee) 714 | return -1; 715 | } 716 | 717 | +Monitor * 718 | +systraytomon(Monitor *m) { 719 | + Monitor *t; 720 | + int i, n; 721 | + if(!systraypinning) { 722 | + if(!m) 723 | + return selmon; 724 | + return m == selmon ? m : NULL; 725 | + } 726 | + for(n = 1, t = mons; t && t->next; n++, t = t->next) ; 727 | + for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; 728 | + if(systraypinningfailfirst && n < systraypinning) 729 | + return mons; 730 | + return t; 731 | +} 732 | + 733 | void 734 | zoom(const Arg *arg) 735 | { 736 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /dwm/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 | -------------------------------------------------------------------------------- /extra/dwm.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Name=dwm 4 | Exec=/home/xx0a_q/.xinitrc 5 | Icon=dwm 6 | Type=XSession 7 | -------------------------------------------------------------------------------- /extra/fastfetch.jsonc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-present nnyyxxxx adamperkowski 2 | 3 | { 4 | "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", 5 | "display": { 6 | "color": "red", 7 | "separator": " :", 8 | 9 | "key": { 10 | "width": 17, 11 | "paddingLeft": 2, 12 | "type": "both" 13 | } 14 | }, 15 | 16 | "logo": { 17 | "source": "auto", 18 | "color": { 19 | "1": "red", 20 | "2": "blue" 21 | }, 22 | "padding": { 23 | "top": 1 24 | } 25 | }, 26 | 27 | "modules": [ 28 | "break", 29 | { 30 | "type": "custom", 31 | "format": "\u001b[34m╭─────────────────────────────────────────────────╮\u001b[0m" 32 | }, 33 | { 34 | "type": "users", 35 | "key": "User ", 36 | "keyIcon": " ", 37 | "format": "{name}" 38 | }, 39 | { 40 | "type": "custom", 41 | "format": " \u001b[31m Host\u001b[0m : lunix" 42 | }, 43 | { 44 | "type": "os", 45 | "key": "Distro ", 46 | "keyIcon": " " 47 | }, 48 | { 49 | "type": "kernel", 50 | "key": "Kernel ", 51 | "keyIcon": " " 52 | }, 53 | { 54 | "type": "uptime", 55 | "key": "Uptime ", 56 | "keyIcon": " " 57 | }, 58 | { 59 | "type": "packages", 60 | "key": "Packages", 61 | "keyIcon": " " 62 | }, 63 | { 64 | "type": "wm", 65 | "key": "WM ", 66 | "keyIcon": " " 67 | }, 68 | { 69 | "type": "shell", 70 | "key": "Shell ", 71 | "keyIcon": " " 72 | }, 73 | { 74 | "type": "terminal", 75 | "keyIcon": " " 76 | }, 77 | { 78 | "type": "custom", 79 | "format": "\u001b[34m╰─────────────────────────────────────────────────╯\u001b[0m" 80 | }, 81 | "break" 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /extra/nvim/init.lua: -------------------------------------------------------------------------------- 1 | require('keymap') 2 | require('plug.load') 3 | require('plug.lsp') 4 | require('plug.config') 5 | 6 | vim.opt.number = true 7 | vim.opt.relativenumber = true 8 | 9 | vim.g.rustfmt_autosave = 1 10 | 11 | -- hide all LSP semantic highlights 12 | for _, group in ipairs(vim.fn.getcompletion("@lsp", "highlight")) do 13 | vim.api.nvim_set_hl(0, group, {}) 14 | end 15 | 16 | vim.opt.tabstop = 4 17 | vim.opt.shiftwidth = 4 18 | vim.opt.expandtab = true 19 | -------------------------------------------------------------------------------- /extra/nvim/lua/keymap/init.lua: -------------------------------------------------------------------------------- 1 | local opts = { noremap = true, silent = true } 2 | 3 | vim.keymap.set('n', '', "_dP", opts) 4 | vim.keymap.set('n', 'J', "m .+1", opts) 5 | vim.keymap.set('n', 'K', "m .-2", opts) 6 | vim.keymap.set('n', '', vim.cmd.Ex, opts) 7 | vim.keymap.set('n', '', vim.cmd.UndotreeToggle, opts) 8 | 9 | -------------------------------------------------------------------------------- /extra/nvim/lua/plug/config.lua: -------------------------------------------------------------------------------- 1 | require('catppuccin').setup { 2 | integrations = { 3 | cmp = true, 4 | gitsigns = true, 5 | native_lsp = true 6 | } 7 | } 8 | 9 | local cmp = require('cmp') 10 | cmp.setup { 11 | completion = { 12 | completeopt = 'menu,menuone,preview,noselect', 13 | }, 14 | mapping = cmp.mapping.preset.insert { 15 | [""] = cmp.mapping.select_prev_item(), 16 | [""] = cmp.mapping.select_next_item(), 17 | [""] = cmp.mapping.confirm({ select = false }), 18 | }, 19 | sources = { 20 | { name = 'jule' }, 21 | { name = 'nvim_lsp' }, 22 | { name = 'buffer' }, 23 | { name = 'path' }, 24 | }, 25 | } 26 | 27 | require('ibl').setup { 28 | scope = { 29 | enabled = false 30 | } 31 | } 32 | require('nvim-autopairs').setup {} 33 | 34 | require('gitsigns').setup { 35 | signs = { 36 | add = { text = '┃' }, 37 | change = { text = '┃' }, 38 | delete = { text = '_' }, 39 | topdelete = { text = '‾' }, 40 | changedelete = { text = '~' }, 41 | untracked = { text = '┆' }, 42 | }, 43 | signs_staged = { 44 | add = { text = '┃' }, 45 | change = { text = '┃' }, 46 | delete = { text = '_' }, 47 | topdelete = { text = '‾' }, 48 | changedelete = { text = '~' }, 49 | untracked = { text = '┆' }, 50 | }, 51 | signs_staged_enable = true, 52 | signcolumn = true, -- Toggle with `:Gitsigns toggle_signs` 53 | numhl = false, -- Toggle with `:Gitsigns toggle_numhl` 54 | linehl = false, -- Toggle with `:Gitsigns toggle_linehl` 55 | word_diff = false, -- Toggle with `:Gitsigns toggle_word_diff` 56 | watch_gitdir = { 57 | follow_files = true 58 | }, 59 | auto_attach = true, 60 | attach_to_untracked = false, 61 | current_line_blame = true, -- Toggle with `:Gitsigns toggle_current_line_blame` 62 | current_line_blame_opts = { 63 | virt_text = true, 64 | virt_text_pos = 'eol', -- 'eol' | 'overlay' | 'right_align' 65 | delay = 1000, 66 | ignore_whitespace = false, 67 | virt_text_priority = 100, 68 | use_focus = true, 69 | }, 70 | current_line_blame_formatter = ', - ', 71 | sign_priority = 6, 72 | update_debounce = 100, 73 | status_formatter = nil, -- Use default 74 | max_file_length = 40000, -- Disable if file is longer than this (in lines) 75 | preview_config = { 76 | -- Options passed to nvim_open_win 77 | border = 'single', 78 | style = 'minimal', 79 | relative = 'cursor', 80 | row = 0, 81 | col = 1 82 | }, 83 | } 84 | 85 | require('copilot').setup { 86 | panel = { 87 | enabled = false 88 | }, 89 | suggestion = { 90 | enabled = true, 91 | auto_trigger = true, 92 | keymap = { 93 | accept = '' 94 | } 95 | }, 96 | filetypes = { 97 | markdown = true 98 | } 99 | } 100 | 101 | require('jule').setup { 102 | format_on_save = true, 103 | enable_cmp = true, 104 | } 105 | 106 | vim.cmd.colorscheme 'catppuccin' 107 | vim.g.undotree_SetFocusWhenToggle = true 108 | 109 | if vim.fn.has('persistent_undo') == 1 then 110 | local target_path = vim.fn.expand("~/.vim_undo") 111 | 112 | if vim.fn.isdirectory(target_path) == 0 then 113 | vim.fn.mkdir(target_path, 'p') 114 | end 115 | 116 | vim.o.undodir = target_path 117 | vim.o.undofile = true 118 | end 119 | 120 | require('cord').setup { 121 | display = { 122 | theme = 'catppuccin', 123 | flavor = 'dark', 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /extra/nvim/lua/plug/load.lua: -------------------------------------------------------------------------------- 1 | local Plug = vim.fn['plug#'] 2 | vim.call('plug#begin') 3 | 4 | Plug('neovim/nvim-lspconfig') 5 | 6 | Plug('hrsh7th/nvim-cmp') 7 | Plug('hrsh7th/cmp-nvim-lsp') 8 | Plug('hrsh7th/cmp-buffer') 9 | Plug('hrsh7th/cmp-path') 10 | 11 | Plug('catppuccin/nvim', { ['as'] = 'catppuccin' }) 12 | -- TODO 13 | -- Plug('nvim-lualine/lualine.nvim') 14 | 15 | Plug('lukas-reineke/indent-blankline.nvim') 16 | Plug('windwp/nvim-autopairs') 17 | Plug('mbbill/undotree') 18 | Plug('lewis6991/gitsigns.nvim') 19 | Plug('zbirenbaum/copilot.lua') 20 | Plug('norcalli/nvim-colorizer.lua') 21 | 22 | Plug('vyfor/cord.nvim') 23 | Plug('wakatime/vim-wakatime') 24 | 25 | Plug('julelang/jule.nvim', { ['branch'] = 'main' }) 26 | 27 | vim.call('plug#end') 28 | -------------------------------------------------------------------------------- /extra/nvim/lua/plug/lsp.lua: -------------------------------------------------------------------------------- 1 | vim.diagnostic.config { 2 | signs = false, 3 | virtual_text = { 4 | virt_text_pos = 'right_align', 5 | suffix = ' ', 6 | }, 7 | update_in_insert = true 8 | } 9 | 10 | local lspconfig = require('lspconfig') 11 | local cmp_nvim_lsp = require('cmp_nvim_lsp') 12 | local capabilities = cmp_nvim_lsp.default_capabilities() 13 | 14 | lspconfig.rust_analyzer.setup { 15 | capabilities = capabilities 16 | } 17 | 18 | lspconfig.clangd.setup { 19 | capabilities = capabilities 20 | } 21 | 22 | lspconfig.lua_ls.setup { 23 | capabilities = capabilities, 24 | 25 | on_init = function(client) 26 | if client.workspace_folders then 27 | local path = client.workspace_folders[1].name 28 | if path ~= vim.fn.stdpath('config') and (vim.loop.fs_stat(path..'/.luarc.json') or vim.loop.fs_stat(path..'/.luarc.jsonc')) then 29 | return 30 | end 31 | end 32 | 33 | client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { 34 | runtime = { 35 | version = 'LuaJIT' 36 | }, 37 | workspace = { 38 | checkThirdParty = false, 39 | library = { 40 | vim.env.VIMRUNTIME, 41 | "${3rd}/luv/library" 42 | } 43 | } 44 | }) 45 | end, 46 | 47 | settings = { 48 | Lua = {} 49 | } 50 | } 51 | 52 | lspconfig.jsonls.setup { 53 | capabilities = capabilities 54 | } 55 | 56 | lspconfig.yamlls.setup { 57 | capabilities = capabilities 58 | } 59 | -------------------------------------------------------------------------------- /extra/picom.conf: -------------------------------------------------------------------------------- 1 | corner-radius = 10; 2 | 3 | rounded-corners-exclude = [ "class_g = 'dwm'" ] 4 | 5 | ################################# 6 | # Animations # 7 | ################################# 8 | animations = false; 9 | animation-stiffness-in-tag = 125; 10 | animation-stiffness-tag-change = 90.0; 11 | 12 | animation-window-mass = 0.4; 13 | animation-dampening = 15; 14 | animation-clamping = true; 15 | 16 | animation-for-open-window = "zoom"; 17 | animation-for-unmap-window = "zoom"; 18 | 19 | animation-for-transient-window = "slide-up"; 20 | 21 | enable-fading-prev-tag = true; 22 | enable-fading-next-tag = true; 23 | 24 | animation-exclude = [ 25 | "class_g = 'flameshot'" 26 | ]; 27 | 28 | ################################# 29 | # Shadows # 30 | ################################# 31 | 32 | shadow = false; 33 | 34 | ################################# 35 | # Fading # 36 | ################################# 37 | 38 | fading = false; 39 | fade-in-step = 0.05; 40 | fade-out-step = 0.05; 41 | 42 | ################################# 43 | # Transparency / Opacity # 44 | ################################# 45 | 46 | inactive-opacity = 1; 47 | frame-opacity = 1; 48 | 49 | ################################# 50 | # General Settings # 51 | ################################# 52 | 53 | backend = "glx"; 54 | dithered-present = false; 55 | vsync = true; 56 | mark-wmwin-focused = false; 57 | mark-ovredir-focused = false; 58 | detect-rounded-corners = false; 59 | detect-client-opacity = true; 60 | detect-transient = false; 61 | glx-no-stencil = true; 62 | use-damage = false; 63 | window-shader-fg = "none" 64 | log-level = "warn"; 65 | 66 | wintypes: 67 | { 68 | tooltip = { fade = false; shadow = true; opacity = 0.75; focus = true; full-shadow = false; }; 69 | dock = { shadow = false; clip-shadow-above = true; } 70 | dnd = { shadow = false; } 71 | popup_menu = { opacity = 0.8; } 72 | dropdown_menu = { opacity = 0.8; } 73 | }; 74 | -------------------------------------------------------------------------------- /extra/rofi-catppuccin.rasi: -------------------------------------------------------------------------------- 1 | * { 2 | bg-col: #1e1e2e; 3 | bg-col-light: #1e1e2e; 4 | border-col: #181825; 5 | selected-col: #181825; 6 | blue: #89b4fa; 7 | red: #f38ba8; 8 | fg-col: #cdd6f4; 9 | fg-col2: #f38ba8; 10 | grey: #6c7086; 11 | 12 | width: 600; 13 | font: "FiraCode Nerd Font 12"; 14 | } 15 | 16 | element-text, element-icon , mode-switcher { 17 | background-color: inherit; 18 | text-color: inherit; 19 | } 20 | 21 | window { 22 | height: 600px; 23 | border: 2px; 24 | border-color: @border-col; 25 | background-color: @bg-col; 26 | } 27 | 28 | mainbox { 29 | background-color: @bg-col; 30 | } 31 | 32 | inputbar { 33 | children: [prompt,entry]; 34 | background-color: @bg-col; 35 | border-radius: 5px; 36 | padding: 2px; 37 | } 38 | 39 | prompt { 40 | background-color: @red; 41 | padding: 6px; 42 | text-color: @bg-col; 43 | margin: 20px 0px 0px 20px; 44 | } 45 | 46 | textbox-prompt-colon { 47 | expand: false; 48 | str: ":"; 49 | } 50 | 51 | entry { 52 | padding: 6px; 53 | margin: 20px 0px 0px 10px; 54 | text-color: @fg-col; 55 | background-color: @bg-col; 56 | } 57 | 58 | listview { 59 | border: 0px 0px 0px; 60 | padding: 6px 0px 0px; 61 | margin: 10px 0px 0px 20px; 62 | columns: 2; 63 | lines: 5; 64 | background-color: @bg-col; 65 | } 66 | 67 | element { 68 | padding: 5px; 69 | background-color: @bg-col; 70 | text-color: @fg-col ; 71 | } 72 | 73 | element-icon { 74 | size: 25px; 75 | } 76 | 77 | element selected { 78 | background-color: @selected-col ; 79 | text-color: @fg-col2 ; 80 | } 81 | 82 | mode-switcher { 83 | spacing: 0; 84 | } 85 | 86 | button { 87 | padding: 10px; 88 | background-color: @bg-col-light; 89 | text-color: @grey; 90 | vertical-align: 0.5; 91 | horizontal-align: 0.5; 92 | } 93 | 94 | button selected { 95 | background-color: @bg-col; 96 | text-color: @red; 97 | } 98 | 99 | message { 100 | background-color: @bg-col-light; 101 | margin: 2px; 102 | padding: 2px; 103 | border-radius: 5px; 104 | } 105 | 106 | textbox { 107 | padding: 6px; 108 | margin: 20px 0px 0px 20px; 109 | text-color: @red; 110 | background-color: @bg-col-light; 111 | } 112 | -------------------------------------------------------------------------------- /extra/rofi.rasi: -------------------------------------------------------------------------------- 1 | configuration{ 2 | modi: "run,drun,window"; 3 | icon-theme: "Oranchelo"; 4 | show-icons: true; 5 | terminal: "kitty"; 6 | drun-display-format: "{icon} {name}"; 7 | location: 0; 8 | disable-history: false; 9 | hide-scrollbar: true; 10 | display-drun: "  Apps "; 11 | sidebar-mode: false; 12 | } 13 | 14 | @theme "catppuccin" 15 | -------------------------------------------------------------------------------- /extra/tmux.conf: -------------------------------------------------------------------------------- 1 | unbind C-b 2 | set-option -g prefix C-a 3 | bind-key C-a send-prefix 4 | 5 | bind-key k kill-window 6 | 7 | set -g status-position top 8 | 9 | set -g @catppuccin_window_left_separator "█" 10 | set -g @catppuccin_window_right_separator "█ " 11 | set -g @catppuccin_window_number_position "right" 12 | set -g @catppuccin_window_middle_separator " █" 13 | 14 | set -g @catppuccin_window_default_fill "number" 15 | 16 | set -g @catppuccin_window_current_fill "number" 17 | set -g @catppuccin_window_current_text "#{pane_current_path}" 18 | 19 | set -g @catppuccin_status_modules_right "application session date_time" 20 | set -g @catppuccin_status_left_separator "" 21 | set -g @catppuccin_status_right_separator " " 22 | set -g @catppuccin_status_fill "all" 23 | set -g @catppuccin_status_connect_separator "yes" 24 | 25 | run ~/.config/tmux/plugins/catppuccin/catppuccin.tmux 26 | -------------------------------------------------------------------------------- /extra/trapd00r-catppuccin.zsh-theme: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2022 Robby Russell 2 | # Adam Perkowski 3 | 4 | autoload -U add-zsh-hook 5 | autoload -Uz vcs_info 6 | 7 | local c0=$'\e[m' 8 | local c1=$'\e[38;5;245m' 9 | local c2=$'\e[38;5;250m' 10 | local c3=$'\e[38;5;242m' 11 | local c4=$'\e[38;5;197m' 12 | local c5=$'\e[38;5;225m' 13 | local c6=$'\e[91m' 14 | local c7=$'\e[38;5;242m' 15 | local c8=$'\e[38;5;244m' 16 | local c9=$'\e[38;5;162m' 17 | local c10=$'\e[1m' 18 | local c11=$'\e[38;5;208m\e[1m' 19 | local c12=$'\e[38;5;142m\e[1m' 20 | local c13=$'\e[38;5;196m\e[1m' 21 | 22 | 23 | zsh_path() { 24 | setopt localoptions nopromptsubst 25 | 26 | local colors 27 | colors=$(echoti colors) 28 | 29 | local -A yellow 30 | yellow=( 31 | 1 '%F{228}' 2 '%F{222}' 3 '%F{192}' 4 '%F{186}' 32 | 5 '%F{227}' 6 '%F{221}' 7 '%F{191}' 8 '%F{185}' 33 | 9 '%F{226}' 10 '%F{220}' 11 '%F{190}' 12 '%F{184}' 34 | 13 '%F{214}' 14 '%F{178}' 15 '%F{208}' 16 '%F{172}' 35 | 17 '%F{202}' 18 '%F{166}' 36 | ) 37 | 38 | local dir i=1 39 | for dir (${(s:/:)PWD}); do 40 | if [[ $i -eq 1 ]]; then 41 | if [[ $colors -ge 256 ]]; then 42 | print -Pn "\e[34;49m /%b" 43 | else 44 | print -Pn "\e[34;49m /" 45 | fi 46 | else 47 | if [[ $colors -ge 256 ]]; then 48 | print -Pn "\e[91m » " 49 | else 50 | print -Pn "%F{yellow} > " 51 | fi 52 | fi 53 | 54 | (( i++ )) 55 | 56 | if [[ $colors -ge 256 ]]; then 57 | print -Pn "\e[34;49m$dir" 58 | else 59 | print -Pn "%F{blue}$dir" 60 | fi 61 | done 62 | print -Pn "%f" 63 | } 64 | 65 | 66 | # We don't want to use the extended colorset in the TTY / VC. 67 | if [ "$TERM" = linux ]; then 68 | c1=$'\e[34;1m' 69 | c2=$'\e[35m' 70 | c3=$'\e[31m' 71 | c4=$'\e[31;1m' 72 | c5=$'\e[32m' 73 | c6=$'\e[32;1m' 74 | c7=$'\e[33m' 75 | c8=$'\e[33;1m' 76 | c9=$'\e[34m' 77 | c11=$'\e[35;1m' 78 | c12=$'\e[36m' 79 | c13=$'\e[31;1m' 80 | fi 81 | 82 | zstyle ':vcs_info:*' actionformats \ 83 | '%{$c8%}(%f%s)%{$c7%}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f ' 84 | 85 | zstyle ':vcs_info:*' formats \ 86 | "%{$c8%}%s%%{$c7%}❨ %{$c9%}%{$c6%}%b%{$c7%} ❩%{$reset_color%}%f " 87 | 88 | zstyle ':vcs_info:*' enable git 89 | 90 | add-zsh-hook precmd prompt_jnrowe_precmd 91 | 92 | prompt_jnrowe_precmd () { 93 | vcs_info 94 | if [ "${vcs_info_msg_0_}" = "" ]; then 95 | dir_status="%{$c1%}%n%{$c6%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})" 96 | PROMPT='${dir_status} ${ret_status}%{$reset_color%} 97 | > ' 98 | # modified, to be committed 99 | elif [[ $(git diff --cached --name-status 2>/dev/null ) != "" ]]; then 100 | dir_status="%{$c1%}%n%{$c6%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})" 101 | PROMPT='${vcs_info_msg_0_}%{$30%} %{$bg_bold[red]%}%{$fg_bold[cyan]%}C%{$fg_bold[black]%}OMMIT%{$reset_color%} 102 | ${dir_status}%{$reset_color%} 103 | > ' 104 | elif [[ $(git diff --name-status 2>/dev/null ) != "" ]]; then 105 | dir_status="%{$c1%}%n%{$c6%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})" 106 | PROMPT='${vcs_info_msg_0_}%{$bg_bold[red]%}%{$fg_bold[blue]%}D%{$fg_bold[black]%}IRTY%{$reset_color%} 107 | ${dir_status}%{$reset_color%} 108 | %{$c6%}>%{$c0%} ' 109 | else 110 | dir_status="%{$c1%}%n%{$c6%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})" 111 | PROMPT='${vcs_info_msg_0_} 112 | ${dir_status}%{$reset_color%} 113 | > ' 114 | fi 115 | } 116 | -------------------------------------------------------------------------------- /extra/xinitrc: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | exec i3 4 | 5 | # picom -b & 6 | hsetroot -solid "#1e1e2e" & 7 | xset r rate 120 60 & 8 | # feh --bg-fill ~/Pictures/wallpapers/cyber-city.png & 9 | 10 | while true; do 11 | cpu=$(cat /proc/stat | grep "cpu " | awk '{printf("%.2f\n", 100 - ($5+$6+$7+$8)*100/($1+$2+$3+$4+$5+$6+$7+$8))}') 12 | ram=$(free -m | awk 'NR==2{printf "%.2f%%\n", $3*100/$2 }') 13 | time=$(date "+%I:%M %p") 14 | 15 | status="$cpu% :: $ram :: $time" 16 | 17 | xsetroot -name "$status" 18 | 19 | sleep 5s 20 | done & 21 | 22 | 23 | exec dwm 24 | -------------------------------------------------------------------------------- /extra/zshrc: -------------------------------------------------------------------------------- 1 | export ZSH="$HOME/.oh-my-zsh" 2 | 3 | ZSH_THEME="trapd00r-catppuccin" 4 | 5 | plugins=(git) 6 | 7 | source $ZSH/oh-my-zsh.sh 8 | 9 | source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.plugin.zsh 10 | source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh 11 | 12 | export GPG_TTY=$(tty) 13 | gpgconf --launch gpg-agent 14 | 15 | eval "$(zoxide init zsh)" 16 | 17 | alias diff='diff --color=auto' 18 | alias grep='grep --color=auto' 19 | alias ip='ip -color=auto' 20 | alias ping='prettyping' 21 | 22 | alias sudo="sudo " 23 | alias ls="lsd -hN --group-directories-first --color=auto" 24 | alias la="lsd -lahN --group-directories-first --color=auto" 25 | alias ll="lsd -llhN --group-directories-first --color=auto" 26 | 27 | function ff() { 28 | stamp="$(date +%s)" 29 | kitget --square -o "/tmp/kitget-$stamp" 30 | clear 31 | fastfetch --kitty "/tmp/kitget-$stamp" "$@" 32 | rm -f "/tmp/kitget-$stamp" 33 | } 34 | 35 | alias ga="git add" 36 | alias gc="git commit -m" 37 | alias gp="git push origin" 38 | alias gb="git branch" 39 | alias gpull="git pull origin" 40 | alias gcherry="git cherry-pick -x" 41 | alias gmain="if ! git checkout --track origin/main; then; if ! git checkout main; then git checkout master; fi ; fi" 42 | 43 | function gclone() { git clone "$1" && cd "$(basename $1 .git)" } 44 | function gcco() { 45 | local message="$1" 46 | shift 47 | 48 | for coauthor in "$@"; do 49 | local coauthors="$coauthors 50 | Co-authored-by: $coauthor <${coauthor}@users.noreply.github.com>" 51 | done 52 | 53 | git commit -m "$message" -m "$coauthors" 54 | } 55 | function gupdate-branch { git fetch "$1" main && git merge "$1"/main } 56 | 57 | alias db="distrobox" 58 | alias cp="cp -i" 59 | 60 | alias system-upgrade="rm -rf ~/.cache/paru && sudo pacman -Scc --noconfirm; paru -Scc --noconfirm; paru --noconfirm; paru -Qq | grep '\-git' | paru -S --noconfirm -; rustup update" 61 | alias vencord-upgrade='sh -c "$(curl -sS https://raw.githubusercontent.com/Vendicated/VencordInstaller/main/install.sh)"' 62 | 63 | alias clipin="xsel --input --clipboard" 64 | alias clipout="xsel --output --clipboard" 65 | 66 | alias shred="shred -uvz" 67 | function shreddir() { find "$1" -type f -exec shred -uvz {} \; rm -rf "$1" } 68 | 69 | function b64 { echo "$1" | base64 } 70 | function b64d { echo "$1" | base64 -d } 71 | 72 | function nv() { nvim -u $HOME/.config/nvim/init.lua "$@"; echo -ne "\e[6 q" } 73 | 74 | function command_not_found_handler() { 75 | echo -e "Command \e[91m$1\e[0m not found! \e[91mSTUPID! BONK!\e[0m OwO" >&2 76 | return 127 77 | } 78 | 79 | function cd() { 80 | { z "$@" 2>/dev/null && ls } || echo -e "Directory \e[91m$*\e[0m not found! \e[91mSTUPID! BONK!\e[0m OwO" 81 | } 82 | 83 | ff #; tmux ls 84 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # TODO $DWM_DIR not set handling 4 | 5 | RC='\033[0m' 6 | RED='\033[31m' 7 | YELLOW='\033[33m' 8 | GREEN='\033[32m' 9 | BLUE='\033[34m' 10 | 11 | printf "%b\n" " ${RED}WARNING!${RC}\n 12 | ${RED}!!${RC} This script is fully automated and requires ${RED}!!${RC} 13 | ${RED}!!${RC} no user interaction. Make sure to check the ${RED}!!${RC} 14 | ${RED}!!${RC} contents of install.sh before proceeding. ${RED}!!${RC}\n 15 | ${BLUE}Hit RETURN to proceed${RC}" 16 | read -r dummy 17 | 18 | if ! command -v pacman &> /dev/null; then 19 | printf "%b\n" "${RED}Automated setup only for Arch Linux.${RC}" 20 | exit 1 21 | fi 22 | 23 | if command -v sudo &> /dev/null; then 24 | sudo -v && clear || { printf "%b\n" "${RED}Failed to gain elevation.${RC}"; exit 1; } 25 | SU=sudo 26 | elif command -v doas &> /dev/null; then 27 | doas true && clear || { printf "%b\n" "${RED}Failed to gain elevation.${RC}"; exit 1; } 28 | SU=doas 29 | else 30 | printf "%b\n" "${RED}Escalation tool is required. Install sudo or doas.${RC}" 31 | fi 32 | 33 | if command -v paru &> /dev/null; then 34 | AUR_HELPER=paru 35 | elif command -v yay &> /dev/null; then 36 | AUR_HELPER=yay 37 | else 38 | printf "%b\n" "${YELLOW}Installing paru...${RC}" 39 | $SU pacman -S --needed --noconfirm base-devel git > /dev/null 2>&1 || { printf "%b\n" "${RED}Failed to install build dependencies.${RC}"; exit 1; } 40 | git clone https://aur.archlinux.org/paru-bin.git 41 | cd paru-bin || return 1 42 | makepkg -si --noconfirm 43 | cd .. 44 | rm -rf paru-bin 45 | 46 | AUR_HELPER=paru 47 | printf "%b\n" "${GREEN}Paru installed.${RC}" 48 | fi 49 | 50 | printf "%b\n" "${YELLOW}Installing dependencies...${RC}" 51 | $SU pacman -S --needed --noconfirm base-devel fastfetch lsd zsh xorg xorg-xinit xorg-xset \ 52 | xorg-xsetroot ttf-firacode-nerd pipewire p7zip noto-fonts noto-fonts-cjk \ 53 | noto-fonts-emoji ttf-nerd-fonts-symbols flameshot zsh-syntax-highlighting \ 54 | zsh-autosuggestions hsetroot zoxide gnupg git prettyping neovim npm tmux emptty rofi \ 55 | > /dev/null 2>&1 || { printf "%b\n" "${RED}Failed to install dependencies.${RC}"; exit 1; } 56 | $AUR_HELPER -R --noconfirm picom &> /dev/null 57 | $AUR_HELPER -S --needed --noconfirm picom-ftlabs-git git-extras kitget \ 58 | > /dev/null 2>&1 || { printf "%b\n" "${RED}Failed to install AUR dependencies.${RC}"; exit 1; } 59 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" \ 60 | "" --unattended > /dev/null 2>&1 \ 61 | || printf "%b\n" "${RED}Failed to install Oh My ZSH. It might be already installed.${RC}" 62 | sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim \ 63 | --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' \ 64 | > /dev/null 2>&1 || printf "%b\n" "${RED}Failed to install vim-plug.${RC}" 65 | mkdir -p "$HOME/.config/tmux/plugins" 66 | git clone -b v2.1.1 https://github.com/catppuccin/tmux.git \ 67 | "$HOME/.config/tmux/plugins/catppuccin" \ 68 | > /dev/null 2>&1 || printf "%b\n" "${RED}Failed to install catppuccin for tmux.${RC}" 69 | printf "%b\n" "${GREEN}Dependencies installed.${RC}" 70 | 71 | printf "%b\n" "${YELLOW}Linking files...${RC}" 72 | DWM_DIR=$(pwd) 73 | 74 | if [ -z "$XDG_CONFIG_HOME" ]; then 75 | mkdir "$HOME/.config" &> /dev/null 76 | XDG_CONFIG_HOME="$HOME/.config" 77 | fi 78 | 79 | ln -sf "$DWM_DIR/extra/zshrc" "$HOME/.zshrc" 80 | mkdir "$XDG_CONFIG_HOME/fastfetch" &> /dev/null 81 | ln -sf "$DWM_DIR/extra/fastfetch.jsonc" "$XDG_CONFIG_HOME/fastfetch/config.jsonc" 82 | ln -sf "$DWM_DIR/extra/picom.conf" "$XDG_CONFIG_HOME/picom.conf" 83 | ln -sf "$DWM_DIR/extra/trapd00r-catppuccin.zsh-theme" \ 84 | "$HOME/.oh-my-zsh/custom/themes/trapd00r-catppuccin.zsh-theme" 85 | rm -rf "$XD_CONFIG_HOME/nvim" &> /dev/null 86 | ln -sf "$DWM_DIR/extra/nvim" "$XDG_CONFIG_HOME/nvim" 87 | ln -sf "$DWM_DIR/extra/tmux.conf" "$HOME/.tmux.conf" 88 | mkdir -p "$HOME/.local/share/rofi/themes" 89 | ln -sf "$DWM_DIR/extra/rofi-catppuccin.rasi" "$HOME/.local/share/rofi/themes/catppuccin.rasi" 90 | mkdir -p "$XDG_CONFIG_HOME/rofi" 91 | ln -sf "$DWM_DIR/extra/rofi.rasi" "$XDG_CONFIG_HOME/rofi/config.rasi" 92 | 93 | $SU chmod +x "$DWM_DIR/extra/xinitrc" 94 | ln -sf "$DWM_DIR/extra/xinitrc" "$HOME/.xinitrc" 95 | 96 | sed -i "s/Exec=\/home\/xx0a_q\/.xinitrc/Exec=\/home\/$USER\/.xinitrc/g" \ 97 | "$DWM_DIR/extra/dwm.desktop" 98 | $SU mkdir -p '/usr/share/xsessions' 99 | $SU ln -sf "$DWM_DIR/extra/dwm.desktop" '/usr/share/xsessions/dwm.desktop' 100 | 101 | sed -i '/^DWM_DIR=/d' "$DWM_DIR/extra/zshrc" 102 | echo "DWM_DIR=$DWM_DIR" >> "$DWM_DIR/extra/zshrc" 103 | 104 | # mkdir "$HOME/.images" > /dev/null 105 | # ln -sf "$DWM_DIR/extra/windows-error.jpg" "$HOME/.images/windows-error.jpg" 106 | 107 | printf "%b\n" "${GREEN}Files linked.${RC}" 108 | 109 | printf "%b\n" "${YELLOW}Setting up dependencies...${RC}" 110 | $SU chsh -s /bin/zsh "$USER" > /dev/null 2>&1 \ 111 | || printf "%b\n" "${RED}Failed to change default shell to ZSH.${RC}" 112 | $SU systemctl disable display-manager.service > /dev/null 2>&1 \ 113 | || printf "%b\n" "${RED}Failed to disable display-manager.service.${RC}" 114 | $SU systemctl enable emptty.service > /dev/null 2>&1 \ 115 | || printf "%b\n" "${RED}Failed to enable emptty.service.${RC}" 116 | nvim --headless -c 'PlugInstall' -c 'qa' > /dev/null 2>&1 \ 117 | || printf "%b\n" "${RED}Failed to install Neovim plugins.${RC}" 118 | printf "%b\n" "${GREEN}Dependencies set up.${RC}" 119 | 120 | printf "%b\n" "${YELLOW}Installing dwm...${RC}" 121 | cd "$DWM_DIR/dwm" 122 | $SU make clean install > /dev/null 2>&1 \ 123 | || { printf "%b\n" "${RED}Failed to install dwm.${RC}"; exit 1; } 124 | 125 | printf "%b\n" "${YELLOW}Installing st...${RC}" 126 | cd "$DWM_DIR/st" 127 | $SU make clean install > /dev/null 2>&1 \ 128 | || { printf "%b\n" "${RED}Failed to install st.${RC}"; exit 1; } 129 | 130 | printf "%b\n" "${GREEN}Done.${RC}" 131 | 132 | printf "%b" "${BLUE}Do you want to reboot your system now? (y/N) ${RC}" 133 | read -r input 134 | case $input in 135 | y|Y) 136 | $SU reboot 137 | ;; 138 | *) 139 | printf "%b\n" "Reboot your system manually." 140 | exit 0 141 | ;; 142 | esac 143 | -------------------------------------------------------------------------------- /install_preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamperkowski/dwm/a19f792198747a0a863ec5cdea55a71e22d3a179/install_preview.gif -------------------------------------------------------------------------------- /install_preview.tape: -------------------------------------------------------------------------------- 1 | # VHS documentation 2 | # 3 | # Output: 4 | # Output .gif Create a GIF output at the given 5 | # Output .mp4 Create an MP4 output at the given 6 | # Output .webm Create a WebM output at the given 7 | # 8 | # Require: 9 | # Require Ensure a program is on the $PATH to proceed 10 | # 11 | # Settings: 12 | # Set FontSize Set the font size of the terminal 13 | # Set FontFamily Set the font family of the terminal 14 | # Set Height Set the height of the terminal 15 | # Set Width Set the width of the terminal 16 | # Set LetterSpacing Set the font letter spacing (tracking) 17 | # Set LineHeight Set the font line height 18 | # Set LoopOffset % Set the starting frame offset for the GIF loop 19 | # Set Theme Set the theme of the terminal 20 | # Set Padding Set the padding of the terminal 21 | # Set Framerate Set the framerate of the recording 22 | # Set PlaybackSpeed Set the playback speed of the recording 23 | # Set MarginFill Set the file or color the margin will be filled with. 24 | # Set Margin Set the size of the margin. Has no effect if MarginFill isn't set. 25 | # Set BorderRadius Set terminal border radius, in pixels. 26 | # Set WindowBar Set window bar type. (one of: Rings, RingsRight, Colorful, ColorfulRight) 27 | # Set WindowBarSize Set window bar size, in pixels. Default is 40. 28 | # Set TypingSpeed