diff --git a/LICENSE b/LICENSE index ae76d4e..007ab53 100644 --- a/LICENSE +++ b/LICENSE @@ -18,7 +18,7 @@ MIT/X Consortium License © 2015-2016 Eric Pruitt © 2016-2017 Markus Teich © 2020-2022 Chris Down -© 2021-2022 Ivan Polyakov +© 2021-2024 Ivan Polyakov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/README.md b/README.md index 94d710c..bc91b07 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ dwm === -Vilor's dwm based on [dwm 6.4](README.dwm.md) +Vilor's dwm based on [dwm 6.5](README.dwm.md) Used patches ------------ diff --git a/config.def.h b/config.def.h index 1ec45d8..fe0b4a5 100644 --- a/config.def.h +++ b/config.def.h @@ -2,20 +2,31 @@ #include -/* appearance */ +/*** appearance ***/ static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ -static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ -static const unsigned int systrayspacing = 2; /* systray spacing */ -static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const int showsystray = 1; /* 0 means no systray */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = { "monospace:size=10" }; static const char dmenufont[] = "monospace:size=10"; -/* default theme +/** systray **/ +/* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ +static const unsigned int systraypinning = 0; +/* 0: systray in the right corner, >0: systray on left of status text */ +static const unsigned int systrayonleft = 0; +/* systray spacing */ +static const unsigned int systrayspacing = 2; +/* + * 1: if pinning fails, display systray on the first monitor, + * False: display systray on the last monitor + */ +static const int systraypinningfailfirst = 1; +/* 0 means no systray */ +static const int showsystray = 1; + +/** default theme **/ +/* static const char col_gray1[] = "#222222"; static const char col_gray2[] = "#444444"; static const char col_gray3[] = "#bbbbbb"; @@ -23,45 +34,53 @@ static const char col_gray4[] = "#eeeeee"; static const char col_cyan[] = "#005577"; */ -/* my theme */ +/** my theme **/ static const char col_gray1[] = "#2e3440"; static const char col_gray2[] = "#444444"; static const char col_gray3[] = "#bbbbbb"; static const char col_gray4[] = "#eeeeee"; static const char col_cyan[] = "#9b3e46"; + static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, }; -/* tagging */ +/** tagging **/ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, 1, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, }; -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +/*** layout(s) ***/ +/* factor of master area size [0.05..0.95] */ +static const float mfact = 0.55; + +/* number of clients in master area */ +static const int nmaster = 1; + +/* 1 means respect size hints in tiled resizals */ +static const int resizehints = 0; + +/* 1 will force focus on the fullscreen window */ +static const int lockfullscreen = 1; static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, }; -/* key definitions */ +/*** key definitions ***/ #define MODKEY Mod4Mask #define TAGKEYS(KEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ @@ -72,81 +91,89 @@ static const Layout layouts[] = { /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } -/* commands */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +/** commands **/ +/* component of dmenucmd, manipulated in spawn() */ +static char dmenumon[2] = "0"; +static const char *dmenucmd[] = { + "dmenu_run", "-m", dmenumon, "-fn", dmenufont, + "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, + NULL +}; static const char *termcmd[] = { "st", NULL }; - static const char *volupcmd[] = -{ "/usr/bin/amixer", "set", "Master", "5%+", NULL }; + { "/usr/bin/amixer", "set", "Master", "5%+", NULL }; static const char *voldowncmd[] = -{ "/usr/bin/amixer", "set", "Master", "5%-", NULL }; + { "/usr/bin/amixer", "set", "Master", "5%-", NULL }; static const char *mutevolcmd[] = -{ "/usr/bin/amixer", "set", "Master", "toggle", NULL }; + { "/usr/bin/amixer", "set", "Master", "toggle", NULL }; static const char *mutemiccmd[] = -{ "/usr/bin/amixer", "set", "Capture", "toggle", NULL }; + { "/usr/bin/amixer", "set", "Capture", "toggle", NULL }; static const char *brightnessupcmd[] = { "xbacklight", "-inc", "10", NULL }; static const char *brightnessdowncmd[] = { "xbacklight", "-dec", "10", NULL }; static const char *screenshotcmd[] = { "flameshot", "gui", NULL }; static const Key keys[] = { - /* modifier key function argument */ - { 0, XF86XK_AudioRaiseVolume, spawn, { .v = volupcmd } }, - { 0, XF86XK_AudioLowerVolume, spawn, { .v = voldowncmd } }, - { 0, XF86XK_AudioMute, spawn, { .v = mutevolcmd } }, - { 0, XF86XK_AudioMicMute, spawn, { .v = mutemiccmd } }, - { 0, XF86XK_MonBrightnessUp, spawn, { .v = brightnessupcmd } }, - { 0, XF86XK_MonBrightnessDown, spawn, { .v = brightnessdowncmd } }, - { 0, XK_Print, spawn, { .v = screenshotcmd } }, - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, + /* modifier key function argument */ + { 0, XF86XK_AudioRaiseVolume, spawn, {.v = volupcmd } }, + { 0, XF86XK_AudioLowerVolume, spawn, {.v = voldowncmd } }, + { 0, XF86XK_AudioMute, spawn, {.v = mutevolcmd } }, + { 0, XF86XK_AudioMicMute, spawn, {.v = mutemiccmd } }, + { 0, XF86XK_MonBrightnessUp, spawn, {.v = brightnessupcmd } }, + { 0, XF86XK_MonBrightnessDown, spawn, {.v = brightnessdowncmd } }, + { 0, XK_Print, spawn, {.v = screenshotcmd } }, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, }; -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +/*** button definitions ***/ +/* + * click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + * ClkClientWin, or ClkRootWin + */ static const Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; diff --git a/config.mk b/config.mk index ef8acf7..8efca9a 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # dwm version -VERSION = 6.4 +VERSION = 6.5 # Customize below to fit your system @@ -26,7 +26,7 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} diff --git a/dwm.c b/dwm.c index 7223d62..f9e7e4a 100644 --- a/dwm.c +++ b/dwm.c @@ -230,7 +230,6 @@ static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); static void showhide(Client *c); -static void sigchld(int unused); static void spawn(const Arg *arg); static Monitor *systraytomon(Monitor *m); static void tag(const Arg *arg); @@ -289,6 +288,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { [MapRequest] = maprequest, [MotionNotify] = motionnotify, [PropertyNotify] = propertynotify, + [ResizeRequest] = resizerequest, [UnmapNotify] = unmapnotify }; static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; @@ -443,7 +443,6 @@ attach(Client *c) void attachstack(Client *c) { -static Atom wmatom[WMLast], netatom[NetLast]; c->snext = c->mon->stack; c->mon->stack = c; } @@ -881,7 +880,7 @@ expose(XEvent *e) XExposeEvent *ev = &e->xexpose; if (ev->count == 0 && (m = wintomon(ev->window))) { - drawbar(m); + drawbar(m); if (m == selmon) updatesystray(); } @@ -977,8 +976,8 @@ getatomprop(Client *c, Atom prop) req = xatom[XembedInfo]; if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; if (da == xatom[XembedInfo] && dl == 2) atom = ((Atom *)p)[1]; XFree(p); @@ -986,6 +985,16 @@ getatomprop(Client *c, Atom prop) return atom; } +unsigned int +getsystraywidth() +{ + unsigned int w = 0; + Client *i; + if(showsystray) + for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; + return w ? w + systrayspacing : 1; +} + int getrootptr(int *x, int *y) { @@ -1014,16 +1023,6 @@ getstate(Window w) return result; } -unsigned int -getsystraywidth() -{ - unsigned int w = 0; - Client *i; - if(showsystray) - for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; - return w ? w + systrayspacing : 1; -} - int gettextprop(Window w, Atom atom, char *text, unsigned int size) { @@ -1073,16 +1072,26 @@ grabkeys(void) { updatenumlockmask(); { - unsigned int i, j; + unsigned int i, j, k; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; + int start, end, skip; + KeySym *syms; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); + XDisplayKeycodes(dpy, &start, &end); + syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); + if (!syms) + return; + for (k = start; k <= end; k++) + for (i = 0; i < LENGTH(keys); i++) + /* skip modifier codes, we do that ourselves */ + if (keys[i].keysym == syms[(k - start) * skip]) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, k, + keys[i].mod | modifiers[j], + root, True, + GrabModeAsync, GrabModeAsync); + XFree(syms); } } @@ -1619,11 +1628,12 @@ sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, lo exists = protocols[n] == proto; XFree(protocols); } - } + } else { exists = True; mt = proto; } + if (exists) { ev.type = ClientMessage; ev.xclient.window = w; @@ -1714,9 +1724,16 @@ setup(void) int i; XSetWindowAttributes wa; Atom utf8string; + struct sigaction sa; + + /* do not transform children into zombies when they terminate */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); - /* clean up any zombies immediately */ - sigchld(0); + /* clean up any zombies (inherited from .xinitrc etc) immediately */ + while (waitpid(-1, NULL, WNOHANG) > 0); /* init screen */ screen = DefaultScreen(dpy); @@ -1818,21 +1835,23 @@ showhide(Client *c) } } -void -sigchld(int unused) -{ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); - while (0 < waitpid(-1, NULL, WNOHANG)); -} - void spawn(const Arg *arg) { + struct sigaction sa; + + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; if (fork() == 0) { if (dpy) close(ConnectionNumber(dpy)); setsid(); + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); + execvp(((char **)arg->v)[0], (char **)arg->v); die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); } @@ -2206,6 +2225,7 @@ updatestatus(void) updatesystray(); } + void updatesystrayicongeom(Client *i, int w, int h) {