From aa0d4fb092382f4fb8f1691434c9c3c1cb8b108b Mon Sep 17 00:00:00 2001 From: Gustaf Rydholm Date: Fri, 5 May 2023 00:52:35 +0200 Subject: Bump to 6.4 --- config.h | 333 +++++++++++++++++++++++++++----------------------------------- config.mk | 6 +- drw.c | 88 +++++++++++------ drw.h | 1 + dwm.c | 248 ++++++++++++++++++++++++++-------------------- util.c | 23 ++--- 6 files changed, 358 insertions(+), 341 deletions(-) diff --git a/config.h b/config.h index a136a1c..296f219 100644 --- a/config.h +++ b/config.h @@ -3,115 +3,102 @@ /* Constants */ #define TERMINAL "st" #define TERMCLASS "St" +#define BROWSER "firefox" /* appearance */ -static unsigned int borderpx = 1; /* border pixel of windows */ -static unsigned int snap = 32; /* snap pixel */ -static unsigned int gappih = 20; /* horiz inner gap between windows */ -static unsigned int gappiv = 10; /* vert inner gap between windows */ -static unsigned int gappoh = - 10; /* horiz outer gap between windows and screen edge */ -static unsigned int gappov = - 30; /* vert outer gap between windows and screen edge */ -static int swallowfloating = - 0; /* 1 means swallow floating windows by default */ -static int smartgaps = - 0; /* 1 means no outer gap when there is only one window */ -static int showbar = 1; /* 0 means no bar */ -static int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { - "monospace:size=8", - "Material Design Icons:pixelsize=12:antialias=true:autohint=true"}; - -static char normbgcolor[] = "#000000"; +static unsigned int borderpx = 1; /* border pixel of windows */ +static unsigned int snap = 32; /* snap pixel */ +static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ +static const unsigned int gappih = 20; /* horiz inner gap between windows */ +static const unsigned int gappiv = 10; /* vert inner gap between windows */ +static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */ +static int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +static int showbar = 1; /* 0 means no bar */ +static int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=8", "Symbols Nerd Font:style=2048-em:pixelsize=12:antialias=true:autohint=true" }; +static const char dmenufont[] = "monospace:size=8"; +static char normbgcolor[] = "#000000"; static char normbordercolor[] = "#000000"; -static char normfgcolor[] = "#eeeeee"; -static char selfgcolor[] = "#eeeeee"; -static char selbordercolor[] = "#000000"; -static char selbgcolor[] = "#000000"; - +static char normfgcolor[] = "#eeeeee"; +static char selfgcolor[] = "#eeeeee"; +static char selbordercolor[] = "#373737"; +static char selbgcolor[] = "#373737"; static char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = {normfgcolor, normbgcolor, normbordercolor}, - [SchemeSel] = {selfgcolor, selbgcolor, selbordercolor}, + /* fg bg border */ + [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, + [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, }; typedef struct { - const char *name; - const void *cmd; + const char *name; + const void *cmd; } Sp; -const char *spcmd1[] = {TERMINAL, "-n", "spterm", "-g", "120x34", NULL}; -const char *spcmd2[] = {TERMINAL, "-n", "spcalc", "-f", "monospace:size=16", - "-g", "50x20", "-e", "bc", "-lq", - NULL}; +const char *spcmd1[] = {TERMINAL, "-n", "spterm", "-g", "120x34", NULL }; +const char *spcmd2[] = {TERMINAL, "-n", "spcalc", "-f", "monospace:size=16", "-g", "50x20", "-e", "bc", "-lq", NULL }; static Sp scratchpads[] = { - /* name cmd */ - {"spterm", spcmd1}, - {"spcalc", spcmd2}, + /* name cmd */ + {"spterm", spcmd1}, + {"spcalc", spcmd2}, }; /* tagging */ -static const char *tags[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; +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 isterminal - noswallow monitor */ - {"$BROWSER", NULL, NULL, 1 << 8, 0, 0, -1, -1}, - {"St", NULL, NULL, 0, 0, 1, 0, -1}, - {NULL, NULL, "Event Tester", 0, 0, 0, 1, -1}, /* xev */ + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating isterminal noswallow monitor */ + { BROWSER, NULL, NULL, 1 << 8, 0, 0, -1, -1 }, + { TERMCLASS, NULL, NULL, 0, 0, 1, 0, -1 }, + { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ }; /* layout(s) */ -static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static int nmaster = 1; /* number of clients in master area */ -static int resizehints = 0; /* 1 means respect size hints in tiled resizals */ +static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static int nmaster = 1; /* number of clients in master area */ +static int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ -#define FORCE_VSPLIT \ - 1 /* nrowgrid layout: force two clients to always split vertically */ +#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ #include "vanitygaps.c" static const Layout layouts[] = { - /* symbol arrange function */ - {"[]=", tile}, /* Default: Master on left, slaves on right */ - {"TTT", bstack}, /* Master on top, slaves on bottom */ - - {"[@]", spiral}, /* Fibonacci spiral */ - {"[\\]", dwindle}, /* Decreasing in size right and leftward */ - - {"[D]", deck}, /* Master on left, slaves in monocle-like mode on right */ - {"[M]", monocle}, /* All windows on top of eachother */ - - {"|M|", centeredmaster}, /* Master in middle, slaves on sides */ - {">M>", centeredfloatingmaster}, /* Same but master floats */ - - {"><>", NULL}, /* no layout function means floating behavior */ - {NULL, NULL}, + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "[M]", monocle }, + { "[@]", spiral }, + { "[\\]", dwindle }, + { "H[]", deck }, + { "TTT", bstack }, + { "|M|", centeredmaster }, + { ">M>", centeredfloatingmaster }, + { "><>", NULL }, /* no layout function means floating behavior */ + { NULL, NULL }, }; /* key definitions */ #define MODKEY Mod4Mask -#define TAGKEYS(KEY, TAG) \ - {MODKEY, KEY, view, {.ui = 1 << TAG}}, \ - {MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \ - {MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \ - {MODKEY | ControlMask | ShiftMask, KEY, toggletag, {.ui = 1 << TAG}}, -#define STACKKEYS(MOD, ACTION) \ - {MOD, XK_j, ACTION##stack, {.i = INC(+1)}}, \ - {MOD, XK_k, ACTION##stack, {.i = INC(-1)}}, \ - {MOD, XK_v, ACTION##stack, {.i = 0}}, +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, +#define STACKKEYS(MOD,ACTION) \ + { MOD, XK_j, ACTION##stack, {.i = INC(+1) } }, \ + { MOD, XK_k, ACTION##stack, {.i = INC(-1) } }, \ + { MOD, XK_h, ACTION##stack, {.i = 0}}, /* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) \ - { \ - .v = (const char *[]) { "/bin/sh", "-c", cmd, NULL } \ - } +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static const char *termcmd[] = {TERMINAL, NULL}; +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; +static const char *termcmd[] = { TERMINAL, NULL }; +static const char *passmenucmd[] = { "passmenu", NULL }; /* * Xresources preferences to load at startup @@ -139,116 +126,84 @@ ResourcePref resources[] = { }; #include "shiftview.c" -#include - -static Key keys[] = { - /* modifier key function argument */ - STACKKEYS(MODKEY, focus) STACKKEYS(MODKEY | ShiftMask, push){ - MODKEY, XK_grave, spawn, SHCMD("dmenuunicode")}, - TAGKEYS(XK_1, 0) TAGKEYS(XK_2, 1) TAGKEYS(XK_3, 2) TAGKEYS(XK_4, 3) - TAGKEYS(XK_5, 4) TAGKEYS(XK_6, 5) TAGKEYS(XK_7, 6) TAGKEYS(XK_8, 7) - TAGKEYS(XK_9, 8){MODKEY, XK_0, view, {.ui = ~0}}, - {MODKEY | ShiftMask, XK_0, tag, {.ui = ~0}}, - {MODKEY, XK_BackSpace, spawn, SHCMD("sysact")}, - {MODKEY | ShiftMask, XK_BackSpace, spawn, SHCMD("sysact")}, - {MODKEY | ShiftMask, XK_q, spawn, SHCMD("sysact")}, - {MODKEY, XK_Tab, view, {0}}, - {MODKEY, XK_q, killclient, {0}}, - {MODKEY, XK_w, spawn, SHCMD("$BROWSER")}, - {MODKEY, XK_r, spawn, SHCMD(TERMINAL " -e lf")}, - {MODKEY | ShiftMask, XK_r, spawn, SHCMD(TERMINAL " -e btm")}, - {MODKEY, XK_space, spawn, SHCMD("dmenu_run")}, - {MODKEY, XK_p, spawn, SHCMD("scrot -s -q 100 screenshot.png")}, - {MODKEY | ShiftMask, XK_s, spawn, SHCMD("slock")}, - {MODKEY, XK_e, spawn, - SHCMD(TERMINAL " -e neomutt ; pkill -RTMIN+12 dwmblocks; rmdir ~/.abook")}, - {MODKEY | ShiftMask, XK_e, spawn, - SHCMD(TERMINAL " -e abook -C ~/.config/abook/abookrc --datafile " - "~/.config/abook/addressbook")}, - {MODKEY | ShiftMask, XK_n, spawn, - SHCMD(TERMINAL " -e newsboat; pkill -RTMIN+6 dwmblocks")}, - {MODKEY | ControlMask, XK_l, spawn, SHCMD("layouthandler")}, - {MODKEY, XK_t, setlayout, {.v = &layouts[0]}}, /* tile */ - {MODKEY | ShiftMask, XK_t, setlayout, {.v = &layouts[1]}}, /* bstack */ - {MODKEY, XK_y, setlayout, {.v = &layouts[2]}}, /* spiral */ - {MODKEY | ShiftMask, XK_y, setlayout, {.v = &layouts[3]}}, /* dwindle */ - {MODKEY, XK_u, setlayout, {.v = &layouts[4]}}, /* deck */ - {MODKEY | ShiftMask, XK_u, setlayout, {.v = &layouts[5]}}, /* monocle */ - {MODKEY, XK_i, setlayout, {.v = &layouts[6]}}, /* centeredmaster */ - {MODKEY | ShiftMask, - XK_i, - setlayout, - {.v = &layouts[7]}}, /* centeredfloatingmaster */ - {MODKEY, XK_o, incnmaster, {.i = +1}}, - {MODKEY | ShiftMask, XK_o, incnmaster, {.i = -1}}, - {MODKEY, XK_backslash, view, {0}}, - {MODKEY, XK_a, togglegaps, {0}}, - {MODKEY | ShiftMask, XK_a, defaultgaps, {0}}, - {MODKEY, XK_s, togglesticky, {0}}, - {MODKEY, XK_f, togglefullscr, {0}}, - {MODKEY | ShiftMask, XK_f, setlayout, {.v = &layouts[8]}}, - {MODKEY, XK_g, shiftview, {.i = -1}}, - {MODKEY | ShiftMask, XK_g, shifttag, {.i = -1}}, - {MODKEY, XK_h, setmfact, {.f = -0.05}}, - {MODKEY, XK_l, setmfact, {.f = +0.05}}, - {MODKEY, XK_semicolon, shiftview, {.i = 1}}, - {MODKEY | ShiftMask, XK_semicolon, shifttag, {.i = 1}}, - {MODKEY, XK_apostrophe, togglescratch, {.ui = 1}}, - {MODKEY, XK_Return, spawn, {.v = termcmd}}, - {MODKEY | ShiftMask, XK_Return, togglescratch, {.ui = 0}}, - {MODKEY, XK_z, incrgaps, {.i = +3}}, - {MODKEY, XK_x, incrgaps, {.i = -3}}, - {MODKEY, XK_b, togglebar, {0}}, - {MODKEY | ShiftMask, XK_b, spawn, SHCMD("bookmarkthis")}, - {MODKEY, XK_n, spawn, - SHCMD("xdotool type $(grep -v '^#' ~/.local/share/snippets | dmenu " - "-i -l 50 | cut -d' ' -f1)")}, - {MODKEY | ShiftMask, XK_space, togglefloating, {0}}, - {MODKEY | ShiftMask, XK_m, spawn, - SHCMD("pamixer -t; kill -44 $(pidof dwmblocks)")}, - {MODKEY, XK_minus, spawn, - SHCMD("pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)")}, - {MODKEY | ShiftMask, XK_minus, spawn, - SHCMD("pamixer --allow-boost -d 15; kill -44 $(pidof dwmblocks)")}, - {MODKEY, XK_equal, spawn, - SHCMD("pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)")}, - {MODKEY | ShiftMask, XK_equal, spawn, - SHCMD("pamixer --allow-boost -i 15; kill -44 $(pidof dwmblocks)")}, - {0, XF86XK_AudioMute, spawn, - SHCMD("pamixer -t; kill -44 $(pidof dwmblocks)")}, - {0, XF86XK_AudioRaiseVolume, spawn, - SHCMD("pamixer --allow-boost -i 3; kill -44 $(pidof dwmblocks)")}, - {0, XF86XK_AudioLowerVolume, spawn, - SHCMD("pamixer --allow-boost -d 3; kill -44 $(pidof dwmblocks)")}, + +static const Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_space, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_space, spawn, {.v = passmenucmd } }, + { MODKEY, XK_t, spawn, {.v = termcmd } }, + { MODKEY|ShiftMask, XK_b, togglebar, {0} }, + STACKKEYS(MODKEY, focus) + STACKKEYS(MODKEY|ShiftMask, push) + { MODKEY, XK_o, incnmaster, {.i = +1 } }, + { MODKEY|ShiftMask, XK_o, incnmaster, {.i = -1 } }, + { MODKEY, XK_l, setmfact, {.f = -0.05} }, + { MODKEY, XK_h, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY|ShiftMask, XK_a, defaultgaps, {0} }, + { MODKEY, XK_a, togglegaps, {0} }, + { MODKEY, XK_x, incrgaps, {.i = +3} }, + { MODKEY|ShiftMask, XK_x, incrgaps, {.i = -3} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_Tab, shiftview, {.i = -1}}, + { MODKEY, XK_q, killclient, {0} }, + { MODKEY|ShiftMask, XK_l, setlayout, {.v = &layouts[0]} }, + { MODKEY|ShiftMask, XK_u, setlayout, {.v = &layouts[1]} }, + { MODKEY|ShiftMask, XK_y, setlayout, {.v = &layouts[5]} }, + { MODKEY, XK_s, togglesticky, {0} }, + { MODKEY, XK_f, setfullscreen, {0} }, + { MODKEY, XK_z, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_z, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_BackSpace, spawn, SHCMD("sysact") }, + { MODKEY, XK_m, spawn, SHCMD("mailsync") }, + { MODKEY|ShiftMask, XK_m, spawn, SHCMD("remaps") }, + { MODKEY, XK_p, spawn, SHCMD("scrot -s -q 100 screenshot.png") }, + { MODKEY|ShiftMask, XK_s, spawn, SHCMD("slock") }, + { MODKEY, XK_w, spawn, SHCMD("$BROWSER") }, + { MODKEY, XK_r, spawn, SHCMD(TERMINAL " -e lf") }, + { MODKEY|ShiftMask, XK_r, spawn, SHCMD(TERMINAL " -e btm") }, + { MODKEY, XK_n, spawn, SHCMD(TERMINAL " -e newsboat; pkill -RTMIN+6 dwmblocks") }, + { MODKEY, XK_e, spawn, SHCMD(TERMINAL " -e neomutt ; pkill -RTMIN+12 dwmblocks; rmdir ~/.abook") }, + { MODKEY, XK_i, spawn, SHCMD(TERMINAL " -e abook -C ~/.config/abook/abookrc --datafile ~/.config/abook/addressbook") }, + { MODKEY|ControlMask, XK_l, spawn, SHCMD("layouthandler") }, + /* Bookmarks */ + { MODKEY, XK_b, spawn, SHCMD("bookmarkthis")}, + { MODKEY|XK_space, XK_space, spawn, SHCMD("xdotool type $(grep -v '^#' ~/.local/share/snippets | dmenu -i -l 50 | cut -d' ' -f1)")}, + /* Audio */ + { MODKEY|ShiftMask, XK_t, spawn, SHCMD("pamixer -t; kill -44 $(pidof dwmblocks)")}, + { MODKEY, XK_minus, spawn, SHCMD("pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)") }, + { MODKEY|ShiftMask, XK_minus, spawn, SHCMD("pamixer --allow-boost -d 15; kill -44 $(pidof dwmblocks)") }, + { MODKEY, XK_equal, spawn, SHCMD("pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)") }, + { MODKEY|ShiftMask, XK_equal, spawn, SHCMD("pamixer --allow-boost -i 15; kill -44 $(pidof dwmblocks)") }, + 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) }; /* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - * ClkClientWin, or ClkRootWin */ -static Button buttons[] = { -/* click event mask button function argument - */ -#ifndef __OpenBSD__ - {ClkWinTitle, 0, Button2, zoom, {0}}, - {ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1}}, - {ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2}}, - {ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3}}, - {ClkStatusText, 0, Button4, sigdwmblocks, {.i = 4}}, - {ClkStatusText, 0, Button5, sigdwmblocks, {.i = 5}}, - {ClkStatusText, ShiftMask, Button1, sigdwmblocks, {.i = 6}}, -#endif - {ClkStatusText, ShiftMask, Button3, spawn, - SHCMD(TERMINAL " -e nvim ~/.local/src/dwmblocks/config.h")}, - {ClkClientWin, MODKEY, Button1, movemouse, {0}}, - {ClkClientWin, MODKEY, Button2, defaultgaps, {0}}, - {ClkClientWin, MODKEY, Button3, resizemouse, {0}}, - {ClkClientWin, MODKEY, Button4, incrgaps, {.i = +1}}, - {ClkClientWin, MODKEY, Button5, incrgaps, {.i = -1}}, - {ClkTagBar, 0, Button1, view, {0}}, - {ClkTagBar, 0, Button3, toggleview, {0}}, - {ClkTagBar, MODKEY, Button1, tag, {0}}, - {ClkTagBar, MODKEY, Button3, toggletag, {0}}, - {ClkTagBar, 0, Button4, shiftview, {.i = -1}}, - {ClkTagBar, 0, Button5, shiftview, {.i = 1}}, - {ClkRootWin, 0, Button2, togglebar, {0}}, +/* 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} }, }; + diff --git a/config.mk b/config.mk index ff9e508..ea07628 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # dwm version -VERSION = 6.2 +VERSION = 6.4 # Customize below to fit your system @@ -18,15 +18,15 @@ XINERAMAFLAGS = -DXINERAMA FREETYPELIBS = -lfontconfig -lXft FREETYPEINC = /usr/include/freetype2 # OpenBSD (uncomment) +#MANPREFIX = ${PREFIX}/man #FREETYPEINC = ${X11INC}/freetype2 -#KVMLIB = -lkvm # includes and libs INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} # 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/drw.c b/drw.c index 56175a8..49422e4 100644 --- a/drw.c +++ b/drw.c @@ -95,6 +95,7 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); free(drw); } @@ -239,12 +240,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { - char buf[1024]; - int ty; - unsigned int ew; + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; XftDraw *d = NULL; Fnt *usedfont, *curfont, *nextfont; - size_t i, len; int utf8strlen, utf8charlen, render = x || y || w || h; long utf8codepoint = 0; const char *utf8str; @@ -252,13 +251,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp FcPattern *fcpattern; FcPattern *match; XftResult result; - int charexists = 0; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -270,8 +273,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); while (1) { - utf8strlen = 0; + ew = ellipsis_len = utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { @@ -279,9 +284,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp for (curfont = drw->fonts; curfont; curfont = curfont->next) { charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); if (charexists) { - if (curfont == usedfont) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; + ew += tmpw; } else { nextfont = curfont; } @@ -289,36 +312,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } } - if (!charexists || nextfont) + if (overflow || !charexists || nextfont) break; else charexists = 0; } if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); } + x += ew; + w -= ew; } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - if (!*text) { + if (!*text || overflow) { break; } else if (nextfont) { charexists = 0; @@ -327,6 +339,11 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp /* Regardless of whether or not a fallback font is found, the * character must be drawn. */ charexists = 1; + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); @@ -356,6 +373,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp curfont->next = usedfont; } else { xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; + no_match: usedfont = drw->fonts; } } @@ -385,6 +404,15 @@ drw_fontset_getwidth(Drw *drw, const char *text) return drw_text(drw, 0, 0, 0, 0, 0, text, 0); } +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { diff --git a/drw.h b/drw.h index 09617cf..000fb09 100644 --- a/drw.h +++ b/drw.h @@ -35,6 +35,7 @@ void drw_free(Drw *drw); Fnt *drw_fontset_create(Drw* drw, char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colorscheme abstraction */ diff --git a/dwm.c b/dwm.c index 72282e9..6c3fe93 100644 --- a/dwm.c +++ b/dwm.c @@ -128,7 +128,7 @@ struct Client { float mina, maxa; int x, y, w, h; int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int bw, oldbw; unsigned int tags; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, @@ -244,7 +244,7 @@ static void monocle(Monitor *m); static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); static Client *nexttiled(Client *c); -static void pop(Client *); +static void pop(Client *c); static void propertynotify(XEvent *e); static void pushstack(const Arg *arg); static void quit(const Arg *arg); @@ -322,7 +322,7 @@ static int dwmblockssig; pid_t dwmblockspid = 0; static int screen; static int sw, sh; /* X display screen geometry width, height */ -static int bh, blw = 0; /* bar geometry */ +static int bh; /* bar height */ static int lrpad; /* sum of left and right padding for text */ static int (*xerrorxlib)(Display *, XErrorEvent *); static unsigned int numlockmask = 0; @@ -435,6 +435,8 @@ int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) { if (*w < bh) *w = bh; if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + if (!c->hintsvalid) + updatesizehints(c); /* see last two sentences in ICCCM 4.1.2.3 */ baseismin = c->basew == c->minw && c->baseh == c->minh; if (!baseismin) { /* temporarily remove base dimensions */ @@ -579,9 +581,9 @@ void buttonpress(XEvent *e) { if (i < LENGTH(tags)) { click = ClkTagBar; arg.ui = 1 << i; - } else if (ev->x < x + blw) + } else if (ev->x < x + TEXTW(selmon->ltsymbol)) click = ClkLtSymbol; - else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) { + else if (ev->x > (x = selmon->ww - (int)TEXTW(stext) + lrpad)) { click = ClkStatusText; char *text = rawstext; @@ -644,6 +646,7 @@ void cleanup(void) { drw_cur_free(drw, cursor[i]); for (i = 0; i < LENGTH(colors); i++) free(scheme[i]); + free(scheme); XDestroyWindow(dpy, wmcheckwin); drw_free(drw); XSync(dpy, False); @@ -727,7 +730,8 @@ void configurenotify(XEvent *e) { } } -void configurerequest(XEvent *e) { +void +configurerequest(XEvent *e) { Client *c; Monitor *m; XConfigureRequestEvent *ev = &e->xconfigurerequest; @@ -778,7 +782,8 @@ void configurerequest(XEvent *e) { XSync(dpy, False); } -void copyvalidchars(char *text, char *rawtext) { +void +copyvalidchars(char *text, char *rawtext) { int i = -1, j = 0; while (rawtext[++i]) { @@ -789,7 +794,8 @@ void copyvalidchars(char *text, char *rawtext) { text[j] = '\0'; } -Monitor *createmon(void) { +Monitor * +createmon(void) { Monitor *m; m = ecalloc(1, sizeof(Monitor)); @@ -808,7 +814,8 @@ Monitor *createmon(void) { return m; } -void destroynotify(XEvent *e) { +void +destroynotify(XEvent *e) { Client *c; XDestroyWindowEvent *ev = &e->xdestroywindow; @@ -819,7 +826,8 @@ void destroynotify(XEvent *e) { unmanage(c->swallowing, 1); } -void detach(Client *c) { +void +detach(Client *c) { Client **tc; for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next) @@ -827,7 +835,8 @@ void detach(Client *c) { *tc = c->next; } -void detachstack(Client *c) { +void +detachstack(Client *c) { Client **tc, *t; for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext) @@ -841,7 +850,8 @@ void detachstack(Client *c) { } } -Monitor *dirtomon(int dir) { +Monitor * +dirtomon(int dir) { Monitor *m = NULL; if (dir > 0) { @@ -856,13 +866,17 @@ Monitor *dirtomon(int dir) { return m; } -void drawbar(Monitor *m) { +void +drawbar(Monitor *m) { int x, w, tw = 0; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; Client *c; + if(!m->showbar) + return; + /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ drw_setscheme(drw, scheme[SchemeNorm]); @@ -887,7 +901,7 @@ void drawbar(Monitor *m) { drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); x += w; } - w = blw = TEXTW(m->ltsymbol); + w = TEXTW(m->ltsymbol); drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); @@ -905,14 +919,16 @@ void drawbar(Monitor *m) { drw_map(drw, m->barwin, 0, 0, m->ww, bh); } -void drawbars(void) { +void +drawbars(void) { Monitor *m; for (m = mons; m; m = m->next) drawbar(m); } -void enternotify(XEvent *e) { +void +enternotify(XEvent *e) { Client *c; Monitor *m; XCrossingEvent *ev = &e->xcrossing; @@ -930,7 +946,8 @@ void enternotify(XEvent *e) { focus(c); } -void expose(XEvent *e) { +void +expose(XEvent *e) { Monitor *m; XExposeEvent *ev = &e->xexpose; @@ -938,7 +955,8 @@ void expose(XEvent *e) { drawbar(m); } -void focus(Client *c) { +void +focus(Client *c) { if (!c || !ISVISIBLE(c)) for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext) ; @@ -963,14 +981,16 @@ void focus(Client *c) { } /* there are some broken focus acquiring clients needing extra handling */ -void focusin(XEvent *e) { +void +focusin(XEvent *e) { XFocusChangeEvent *ev = &e->xfocus; if (selmon->sel && ev->window != selmon->sel->win) setfocus(selmon->sel); } -void focusmon(const Arg *arg) { +void +focusmon(const Arg *arg) { Monitor *m; if (!mons->next) @@ -982,11 +1002,12 @@ void focusmon(const Arg *arg) { focus(NULL); } -void focusstack(const Arg *arg) { +void +focusstack(const Arg *arg) { int i = stackpos(arg); Client *c, *p; - if (i < 0 || !selmon->sel || selmon->sel->isfullscreen) + if (i < 0 || !selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) return; for (p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c)); @@ -996,7 +1017,8 @@ void focusstack(const Arg *arg) { restack(selmon); } -Atom getatomprop(Client *c, Atom prop) { +Atom +getatomprop(Client *c, Atom prop) { int di; unsigned long dl; unsigned char *p = NULL; @@ -1012,7 +1034,8 @@ Atom getatomprop(Client *c, Atom prop) { } #ifndef __OpenBSD__ -int getdwmblockspid() { +int +getdwmblockspid() { char buf[16]; FILE *fp = popen("pidof -s dwmblocks", "r"); fgets(buf, sizeof(buf), fp); @@ -1023,7 +1046,8 @@ int getdwmblockspid() { } #endif -int getrootptr(int *x, int *y) { +int +getrootptr(int *x, int *y) { int di; unsigned int dui; Window dummy; @@ -1031,7 +1055,8 @@ int getrootptr(int *x, int *y) { return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); } -long getstate(Window w) { +long +getstate(Window w) { int format; long result = -1; unsigned char *p = NULL; @@ -1048,7 +1073,8 @@ long getstate(Window w) { return result; } -int gettextprop(Window w, Atom atom, char *text, unsigned int size) { +int +gettextprop(Window w, Atom atom, char *text, unsigned int size) { char **list = NULL; int n; XTextProperty name; @@ -1058,21 +1084,19 @@ int gettextprop(Window w, Atom atom, char *text, unsigned int size) { text[0] = '\0'; if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) return 0; - if (name.encoding == XA_STRING) + if (name.encoding == XA_STRING) { strncpy(text, (char *)name.value, size - 1); - else { - if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && - *list) { - strncpy(text, *list, size - 1); - XFreeStringList(list); - } + } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { + strncpy(text, *list, size - 1); + XFreeStringList(list); } text[size - 1] = '\0'; XFree(name.value); return 1; } -void grabbuttons(Client *c, int focused) { +void +grabbuttons(Client *c, int focused) { updatenumlockmask(); { unsigned int i, j; @@ -1091,24 +1115,36 @@ void grabbuttons(Client *c, int focused) { } } -void grabkeys(void) { +void +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); } } -void incnmaster(const Arg *arg) { +void +incnmaster(const Arg *arg) { selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); arrange(selmon); } @@ -1124,7 +1160,8 @@ static int isuniquegeom(XineramaScreenInfo *unique, size_t n, } #endif /* XINERAMA */ -void keypress(XEvent *e) { +void +keypress(XEvent *e) { unsigned int i; KeySym keysym; XKeyEvent *ev; @@ -1137,7 +1174,8 @@ void keypress(XEvent *e) { keys[i].func(&(keys[i].arg)); } -void killclient(const Arg *arg) { +void +killclient(const Arg *arg) { if (!selmon->sel) return; if (!sendevent(selmon->sel, wmatom[WMDelete])) { @@ -1151,7 +1189,8 @@ void killclient(const Arg *arg) { } } -void manage(Window w, XWindowAttributes *wa) { +void +manage(Window w, XWindowAttributes *wa) { Client *c, *t = NULL, *term = NULL; Window trans = None; XWindowChanges wc; @@ -1176,17 +1215,12 @@ void manage(Window w, XWindowAttributes *wa) { term = termforwin(c); } - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, - ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) && - (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) - ? bh - : c->mon->my); + if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) + c->x = c->mon->wx + c->mon->ww - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) + c->y = c->mon->wy + c->mon->wh - HEIGHT(c); + c->x = MAX(c->x, c->mon->wx); + c->y = MAX(c->y, c->mon->wy); c->bw = borderpx; wc.border_width = c->bw; @@ -1223,7 +1257,8 @@ void manage(Window w, XWindowAttributes *wa) { focus(NULL); } -void mappingnotify(XEvent *e) { +void +mappingnotify(XEvent *e) { XMappingEvent *ev = &e->xmapping; XRefreshKeyboardMapping(ev); @@ -1231,13 +1266,12 @@ void mappingnotify(XEvent *e) { grabkeys(); } -void maprequest(XEvent *e) { +void +maprequest(XEvent *e) { static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; - if (!XGetWindowAttributes(dpy, ev->window, &wa)) - return; - if (wa.override_redirect) + if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) return; if (!wintoclient(ev->window)) manage(ev->window, &wa); @@ -1704,9 +1738,16 @@ void setup(void) { int i; XSetWindowAttributes wa; Atom utf8string; + struct sigaction sa; - /* clean up any zombies immediately */ - sigchld(0); + /* 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 (inherited from .xinitrc etc) immediately */ + while (waitpid(-1, NULL, WNOHANG) > 0); signal(SIGHUP, sighup); signal(SIGTERM, sigterm); @@ -1784,7 +1825,8 @@ void seturgent(Client *c, int urg) { XFree(wmh); } -void showhide(Client *c) { +void +showhide(Client *c) { if (!c) return; if (ISVISIBLE(c)) { @@ -1805,14 +1847,8 @@ void 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 sighup(int unused) { +void +sighup(int unused) { Arg a = {.i = 1}; quit(&a); } @@ -1845,9 +1881,7 @@ void spawn(const Arg *arg) { close(ConnectionNumber(dpy)); setsid(); execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); - perror(" failed"); - exit(EXIT_SUCCESS); + die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); } } @@ -1981,6 +2015,7 @@ void unmanage(Client *c, int destroyed) { wc.border_width = c->oldbw; XGrabServer(dpy); /* avoid race conditions */ XSetErrorHandler(xerrordummy); + XSelectInput(dpy, c->win, NoEventMask); XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ XUngrabButton(dpy, AnyButton, AnyModifier, c->win); setclientstate(c, WithdrawnState); @@ -2070,30 +2105,30 @@ int updategeom(void) { memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); XFree(info); nn = j; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next) - ; - if (m) - m->next = createmon(); - else - mons = createmon(); + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n || unique[i].x_org != m->mx || unique[i].y_org != m->my || - unique[i].width != m->mw || unique[i].height != m->mh) { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ + /* removed monitors if n > nn */ for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next) - ; + for (m = mons; m && m->next; m = m->next); while ((c = m->clients)) { dirty = 1; m->clients = c->next; @@ -2101,11 +2136,10 @@ int updategeom(void) { c->mon = mons; attach(c); attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); } + if (m == selmon) + selmon = mons; + cleanupmon(m); } free(unique); } else @@ -2390,12 +2424,10 @@ int xerrorstart(Display *dpy, XErrorEvent *ee) { void zoom(const Arg *arg) { Client *c = selmon->sel; - if (!selmon->lt[selmon->sellt]->arrange || - (selmon->sel && selmon->sel->isfloating)) + if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) + return; + if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) return; - if (c == nexttiled(selmon->clients)) - if (!c || !(c = nexttiled(c->next))) - return; pop(c); } diff --git a/util.c b/util.c index fe044fc..96b82c9 100644 --- a/util.c +++ b/util.c @@ -6,18 +6,9 @@ #include "util.h" -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} - void -die(const char *fmt, ...) { +die(const char *fmt, ...) +{ va_list ap; va_start(ap, fmt); @@ -33,3 +24,13 @@ die(const char *fmt, ...) { exit(1); } + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} -- cgit v1.2.3-70-g09d2