Update to dwm 6.4

This commit is contained in:
Alexander Rosenberg 2023-02-21 09:49:45 -08:00
parent 7ddd92b211
commit dc22a8b02c
Signed by: Zander671
GPG Key ID: 5FD0394ADBD72730
6 changed files with 135 additions and 125 deletions

View File

@ -17,6 +17,7 @@ MIT/X Consortium License
© 2015-2016 Quentin Rameau <quinq@fifth.space> © 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com> © 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de> © 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
© 2020-2022 Chris Down <chris@chrisdown.name>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),

View File

@ -68,7 +68,7 @@ static const char *runcmd[] = { "dmenu_run", NULL };
static const char *termcmd[] = { "alacritty", NULL }; static const char *termcmd[] = { "alacritty", NULL };
static const char *browsercmd[] = { "firefox", NULL }; static const char *browsercmd[] = { "firefox", NULL };
static Key keys[] = { static const Key keys[] = {
/* modifier key function argument */ /* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = runcmd } }, { MODKEY, XK_p, spawn, {.v = runcmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
@ -112,7 +112,7 @@ static Key keys[] = {
/* button definitions */ /* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = { static const Button buttons[] = {
/* click event mask button function argument */ /* click event mask button function argument */
{ ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} },
@ -125,4 +125,3 @@ static Button buttons[] = {
{ ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} },
}; };

92
drw.c
View File

@ -133,19 +133,6 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
die("no font specified."); die("no font specified.");
} }
/* Do not allow using color fonts. This is a workaround for a BadLength
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
* https://lists.suckless.org/dev/1701/30932.html
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
}
font = ecalloc(1, sizeof(Fnt)); font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont; font->xfont = xfont;
font->pattern = pattern; font->pattern = pattern;
@ -251,12 +238,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
int int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) 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 i, ty, ellipsis_x = 0;
int ty; unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
unsigned int ew;
XftDraw *d = NULL; XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont; Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h; int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0; long utf8codepoint = 0;
const char *utf8str; const char *utf8str;
@ -264,13 +249,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcPattern *fcpattern; FcPattern *fcpattern;
FcPattern *match; FcPattern *match;
XftResult result; 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; return 0;
if (!render) { if (!render) {
w = ~w; w = invert ? invert : ~invert;
} else { } else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
@ -282,8 +271,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
} }
usedfont = drw->fonts; usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "...");
while (1) { while (1) {
utf8strlen = 0; ew = ellipsis_len = utf8strlen = 0;
utf8str = text; utf8str = text;
nextfont = NULL; nextfont = NULL;
while (*text) { while (*text) {
@ -291,9 +282,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) { for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) { 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; utf8strlen += utf8charlen;
text += utf8charlen; text += utf8charlen;
ew += tmpw;
} else { } else {
nextfont = curfont; nextfont = curfont;
} }
@ -301,36 +310,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; break;
else else
charexists = 0; charexists = 0;
} }
if (utf8strlen) { 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) { if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)buf, len); usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
} }
x += ew; x += ew;
w -= ew; w -= ew;
} }
} if (render && overflow)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
if (!*text) { if (!*text || overflow) {
break; break;
} else if (nextfont) { } else if (nextfont) {
charexists = 0; charexists = 0;
@ -340,6 +338,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
* character must be drawn. */ * character must be drawn. */
charexists = 1; 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(); fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint); FcCharSetAddChar(fccharset, utf8codepoint);
@ -351,7 +355,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
fcpattern = FcPatternDuplicate(drw->fonts->pattern); fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern); FcDefaultSubstitute(fcpattern);
@ -368,6 +371,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
curfont->next = usedfont; curfont->next = usedfont;
} else { } else {
xfont_free(usedfont); xfont_free(usedfont);
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
no_match:
usedfont = drw->fonts; usedfont = drw->fonts;
} }
} }
@ -397,6 +402,15 @@ drw_fontset_getwidth(Drw *drw, const char *text)
return drw_text(drw, 0, 0, 0, 0, 0, text, 0); 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 void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{ {

1
drw.h
View File

@ -35,6 +35,7 @@ void drw_free(Drw *drw);
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set); void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text); 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); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */ /* Colorscheme abstraction */

62
dwm.c
View File

@ -106,7 +106,7 @@ struct Client {
float cfact; float cfact;
int x, y, w, h; int x, y, w, h;
int oldx, oldy, oldw, oldh; 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; int bw, oldbw;
unsigned int tags; unsigned int tags;
int isfixed, iscentered, isfloating, isalwaysontop, isurgent, neverfocus, oldstate, isfullscreen; int isfixed, iscentered, isfloating, isalwaysontop, isurgent, neverfocus, oldstate, isfullscreen;
@ -209,7 +209,7 @@ static void monocle(Monitor *m);
static void motionnotify(XEvent *e); static void motionnotify(XEvent *e);
static void movemouse(const Arg *arg); static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c); static Client *nexttiled(Client *c);
static void pop(Client *); static void pop(Client *c);
static void propertynotify(XEvent *e); static void propertynotify(XEvent *e);
static void quit(const Arg *arg); static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h); static Monitor *recttomon(int x, int y, int w, int h);
@ -238,7 +238,7 @@ static void spawn(const Arg *arg);
static Monitor *systraytomon(Monitor *m); static Monitor *systraytomon(Monitor *m);
static void tag(const Arg *arg); static void tag(const Arg *arg);
static void tagmon(const Arg *arg); static void tagmon(const Arg *arg);
static void tile(Monitor *); static void tile(Monitor *m);
static void togglebar(const Arg *arg); static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg); static void togglefloating(const Arg *arg);
static void togglealwaysontop(const Arg *arg); static void togglealwaysontop(const Arg *arg);
@ -275,7 +275,7 @@ static const char broken[] = "broken";
static char stext[256]; static char stext[256];
static int screen; static int screen;
static int sw, sh; /* X display screen geometry width, height */ 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 lrpad; /* sum of left and right padding for text */
static int (*xerrorxlib)(Display *, XErrorEvent *); static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0; static unsigned int numlockmask = 0;
@ -381,6 +381,8 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
if (*w < bh) if (*w < bh)
*w = bh; *w = bh;
if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { 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 */ /* see last two sentences in ICCCM 4.1.2.3 */
baseismin = c->basew == c->minw && c->baseh == c->minh; baseismin = c->basew == c->minw && c->baseh == c->minh;
if (!baseismin) { /* temporarily remove base dimensions */ if (!baseismin) { /* temporarily remove base dimensions */
@ -474,7 +476,7 @@ buttonpress(XEvent *e)
if (i < LENGTH(tags)) { if (i < LENGTH(tags)) {
click = ClkTagBar; click = ClkTagBar;
arg.ui = 1 << i; arg.ui = 1 << i;
} else if (ev->x < x + blw) } else if (ev->x < x + TEXTW(selmon->ltsymbol))
click = ClkLtSymbol; click = ClkLtSymbol;
else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
click = ClkStatusText; click = ClkStatusText;
@ -530,6 +532,7 @@ cleanup(void)
drw_cur_free(drw, cursor[i]); drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors); i++) for (i = 0; i < LENGTH(colors); i++)
free(scheme[i]); free(scheme[i]);
free(scheme);
XDestroyWindow(dpy, wmcheckwin); XDestroyWindow(dpy, wmcheckwin);
drw_free(drw); drw_free(drw);
XSync(dpy, False); XSync(dpy, False);
@ -829,7 +832,7 @@ drawbar(Monitor *m)
urg & 1 << i); urg & 1 << i);
x += w; x += w;
} }
w = blw = TEXTW(m->ltsymbol); w = TEXTW(m->ltsymbol);
drw_setscheme(drw, scheme[SchemeTagsNorm]); drw_setscheme(drw, scheme[SchemeTagsNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
@ -1040,14 +1043,12 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
text[0] = '\0'; text[0] = '\0';
if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
return 0; return 0;
if (name.encoding == XA_STRING) if (name.encoding == XA_STRING) {
strncpy(text, (char *)name.value, size - 1); strncpy(text, (char *)name.value, size - 1);
else { } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
strncpy(text, *list, size - 1); strncpy(text, *list, size - 1);
XFreeStringList(list); XFreeStringList(list);
} }
}
text[size - 1] = '\0'; text[size - 1] = '\0';
XFree(name.value); XFree(name.value);
return 1; return 1;
@ -1170,14 +1171,12 @@ manage(Window w, XWindowAttributes *wa)
applyrules(c); applyrules(c);
} }
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
c->x = c->mon->mx + c->mon->mw - WIDTH(c); c->x = c->mon->wx + c->mon->ww - WIDTH(c);
if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
c->y = c->mon->my + c->mon->mh - HEIGHT(c); c->y = c->mon->wy + c->mon->wh - HEIGHT(c);
c->x = MAX(c->x, c->mon->mx); c->x = MAX(c->x, c->mon->wx);
/* only fix client y-offset, if the client center might cover the bar */ c->y = MAX(c->y, c->mon->wy);
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);
c->bw = borderpx; c->bw = borderpx;
wc.border_width = c->bw; wc.border_width = c->bw;
@ -1230,9 +1229,7 @@ maprequest(XEvent *e)
updatesystray(); updatesystray();
} }
if (!XGetWindowAttributes(dpy, ev->window, &wa)) if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect)
return;
if (wa.override_redirect)
return; return;
if (!wintoclient(ev->window)) if (!wintoclient(ev->window))
manage(ev->window, &wa); manage(ev->window, &wa);
@ -1377,7 +1374,7 @@ propertynotify(XEvent *e)
arrange(c->mon); arrange(c->mon);
break; break;
case XA_WM_NORMAL_HINTS: case XA_WM_NORMAL_HINTS:
updatesizehints(c); c->hintsvalid = 0;
break; break;
case XA_WM_HINTS: case XA_WM_HINTS:
updatewmhints(c); updatewmhints(c);
@ -1827,7 +1824,6 @@ setup(void)
focus(NULL); focus(NULL);
} }
void void
seturgent(Client *c, int urg) seturgent(Client *c, int urg)
{ {
@ -1875,9 +1871,7 @@ spawn(const Arg *arg)
close(ConnectionNumber(dpy)); close(ConnectionNumber(dpy));
setsid(); setsid();
execvp(((char **)arg->v)[0], (char **)arg->v); execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
} }
} }
@ -2047,6 +2041,7 @@ unmanage(Client *c, int destroyed)
wc.border_width = c->oldbw; wc.border_width = c->oldbw;
XGrabServer(dpy); /* avoid race conditions */ XGrabServer(dpy); /* avoid race conditions */
XSetErrorHandler(xerrordummy); XSetErrorHandler(xerrordummy);
XSelectInput(dpy, c->win, NoEventMask);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState); setclientstate(c, WithdrawnState);
@ -2156,8 +2151,9 @@ updategeom(void)
memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
XFree(info); XFree(info);
nn = j; nn = j;
if (n <= nn) { /* new monitors available */
for (i = 0; i < (nn - n); i++) { /* new monitors if nn > n */
for (i = n; i < nn; i++) {
for (m = mons; m && m->next; m = m->next); for (m = mons; m && m->next; m = m->next);
if (m) if (m)
m->next = createmon(); m->next = createmon();
@ -2177,7 +2173,7 @@ updategeom(void)
m->mh = m->wh = unique[i].height; m->mh = m->wh = unique[i].height;
updatebarpos(m); updatebarpos(m);
} }
} else { /* less monitors available nn < n */ /* removed monitors if n > nn */
for (i = nn; i < n; i++) { 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)) { while ((c = m->clients)) {
@ -2192,7 +2188,6 @@ updategeom(void)
selmon = mons; selmon = mons;
cleanupmon(m); cleanupmon(m);
} }
}
free(unique); free(unique);
} else } else
#endif /* XINERAMA */ #endif /* XINERAMA */
@ -2270,6 +2265,7 @@ updatesizehints(Client *c)
} else } else
c->maxa = c->mina = 0.0; c->maxa = c->mina = 0.0;
c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
c->hintsvalid = 1;
} }
void void
@ -2548,11 +2544,9 @@ zoom(const Arg *arg)
{ {
Client *c = selmon->sel; Client *c = selmon->sel;
if (!selmon->lt[selmon->sellt]->arrange if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating)
|| (selmon->sel && selmon->sel->isfloating))
return; return;
if (c == nexttiled(selmon->clients)) if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
if (!c || !(c = nexttiled(c->next)))
return; return;
pop(c); pop(c);
} }

23
util.c
View File

@ -6,18 +6,9 @@
#include "util.h" #include "util.h"
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
void void
die(const char *fmt, ...) { die(const char *fmt, ...)
{
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@ -33,3 +24,13 @@ die(const char *fmt, ...) {
exit(1); exit(1);
} }
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}