Bump to 6.4

This commit is contained in:
iStagnant 2023-02-24 23:31:26 +02:00
parent a4d1695e53
commit 787a8bc10d
7 changed files with 168 additions and 131 deletions

View file

@ -63,6 +63,7 @@ static const Rule rules[] = {
static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ 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 nmaster = 1; /* number of clients in master area */
static int resizehints = 0; /* 1 means respect size hints in tiled resizals */ static int resizehints = 0; /* 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" #include "vanitygaps.c"
static const Layout layouts[] = { static const Layout layouts[] = {
@ -133,7 +134,7 @@ ResourcePref resources[] = {
#include <X11/XF86keysym.h> #include <X11/XF86keysym.h>
#include "shiftview.c" #include "shiftview.c"
static Key keys[] = { static const Key keys[] = {
/* modifier key function argument */ /* modifier key function argument */
STACKKEYS(MODKEY, focus) STACKKEYS(MODKEY, focus)
STACKKEYS(MODKEY|ShiftMask, push) STACKKEYS(MODKEY|ShiftMask, push)
@ -308,7 +309,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 */
#ifndef __OpenBSD__ #ifndef __OpenBSD__
{ ClkWinTitle, 0, Button2, zoom, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} },

View file

@ -1,5 +1,5 @@
# dwm version # dwm version
VERSION = 6.2 VERSION = 6.4
# Customize below to fit your system # Customize below to fit your system
@ -18,6 +18,7 @@ XINERAMAFLAGS = -DXINERAMA
FREETYPELIBS = -lfontconfig -lXft FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2 FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment) # OpenBSD (uncomment)
#MANPREFIX = ${PREFIX}/man
#FREETYPEINC = ${X11INC}/freetype2 #FREETYPEINC = ${X11INC}/freetype2
# includes and libs # includes and libs
@ -25,7 +26,7 @@ INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res
# flags # 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 = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS} LDFLAGS = ${LIBS}

89
drw.c
View file

@ -95,6 +95,7 @@ drw_free(Drw *drw)
{ {
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc); XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw); free(drw);
} }
@ -239,12 +240,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;
@ -252,13 +251,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);
@ -270,8 +273,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) {
@ -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) { 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;
} }
@ -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; break;
else else
charexists = 0; charexists = 0;
} }
if (utf8strlen) { if (utf8strlen) {
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); if (render) {
/* shorten text if necessary */ ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
drw_font_getexts(usedfont, utf8str, len, &ew, NULL); usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
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;
} }
x += 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;
@ -328,6 +340,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);
@ -356,6 +374,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;
} }
} }
@ -385,6 +405,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, char *fonts[], size_t fontcount); Fnt *drw_fontset_create(Drw* drw, 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 */

2
dwm.1
View file

@ -28,7 +28,7 @@ dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS .SH OPTIONS
.TP .TP
.B \-v .B \-v
prints version information to standard output, then exits. prints version information to stderr, then exits.
.SH USAGE .SH USAGE
.SS Status bar .SS Status bar
.TP .TP

174
dwm.c
View file

@ -117,7 +117,7 @@ struct Client {
float mina, maxa; float mina, maxa;
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, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky;
@ -236,7 +236,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 pushstack(const Arg *arg); static void pushstack(const Arg *arg);
static void quit(const Arg *arg); static void quit(const Arg *arg);
@ -259,7 +259,6 @@ static void setmfact(const Arg *arg);
static void setup(void); static void setup(void);
static void seturgent(Client *c, int urg); static void seturgent(Client *c, int urg);
static void showhide(Client *c); static void showhide(Client *c);
static void sigchld(int unused);
#ifndef __OpenBSD__ #ifndef __OpenBSD__
static int getdwmblockspid(); static int getdwmblockspid();
static void sigdwmblocks(const Arg *arg); static void sigdwmblocks(const Arg *arg);
@ -316,7 +315,7 @@ static int dwmblockssig;
pid_t dwmblockspid = 0; pid_t dwmblockspid = 0;
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;
@ -431,6 +430,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 */
@ -587,9 +588,9 @@ 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 > (x = selmon->ww - TEXTW(stext) + lrpad)) { else if (ev->x > (x = selmon->ww - (int)TEXTW(stext) + lrpad)) {
click = ClkStatusText; click = ClkStatusText;
char *text = rawstext; char *text = rawstext;
@ -653,6 +654,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);
@ -888,6 +890,9 @@ drawbar(Monitor *m)
unsigned int i, occ = 0, urg = 0; unsigned int i, occ = 0, urg = 0;
Client *c; Client *c;
if(!m->showbar)
return;
/* draw status first so it can be overdrawn by tags later */ /* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */ if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
@ -911,7 +916,7 @@ drawbar(Monitor *m)
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
x += w; x += w;
} }
w = blw = TEXTW(m->ltsymbol); w = TEXTW(m->ltsymbol);
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
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);
@ -1027,7 +1032,7 @@ focusstack(const Arg *arg)
int i = stackpos(arg); int i = stackpos(arg);
Client *c, *p; Client *c, *p;
if (i < 0 || !selmon->sel || selmon->sel->isfullscreen) if(i < 0 || !selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
return; return;
for(p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c)); for(p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c));
@ -1106,13 +1111,11 @@ 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);
@ -1145,16 +1148,26 @@ grabkeys(void)
{ {
updatenumlockmask(); updatenumlockmask();
{ {
unsigned int i, j; unsigned int i, j, k;
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
KeyCode code; int start, end, skip;
KeySym *syms;
XUngrabKey(dpy, AnyKey, AnyModifier, root); XUngrabKey(dpy, AnyKey, AnyModifier, root);
for (i = 0; i < LENGTH(keys); i++) XDisplayKeycodes(dpy, &start, &end);
if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
for (j = 0; j < LENGTH(modifiers); j++) if (!syms)
XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, return;
True, GrabModeAsync, GrabModeAsync); 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);
} }
} }
@ -1267,14 +1280,12 @@ manage(Window w, XWindowAttributes *wa)
term = termforwin(c); term = termforwin(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;
@ -1346,9 +1357,7 @@ maprequest(XEvent *e)
static XWindowAttributes wa; static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest; XMapRequestEvent *ev = &e->xmaprequest;
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);
@ -1846,9 +1855,16 @@ setup(void)
int i; int i;
XSetWindowAttributes wa; XSetWindowAttributes wa;
Atom utf8string; Atom utf8string;
struct sigaction sa;
/* clean up any zombies immediately */ /* do not transform children into zombies when they terminate */
sigchld(0); 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(SIGHUP, sighup);
signal(SIGTERM, sigterm); signal(SIGTERM, sigterm);
@ -1915,7 +1931,6 @@ setup(void)
focus(NULL); focus(NULL);
} }
void void
seturgent(Client *c, int urg) seturgent(Client *c, int urg)
{ {
@ -1951,14 +1966,6 @@ 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 void
sighup(int unused) sighup(int unused)
{ {
@ -2000,9 +2007,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);
} }
} }
@ -2167,6 +2172,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);
@ -2267,42 +2273,42 @@ 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 (m = mons; m && m->next; m = m->next); for (i = n; i < nn; i++) {
if (m) for (m = mons; m && m->next; m = m->next);
m->next = createmon(); if (m)
else m->next = createmon();
mons = 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++) /* removed monitors if n > nn */
if (i >= n for (i = nn; i < n; i++) {
|| unique[i].x_org != m->mx || unique[i].y_org != m->my for (m = mons; m && m->next; m = m->next);
|| unique[i].width != m->mw || unique[i].height != m->mh) while ((c = m->clients)) {
{ dirty = 1;
dirty = 1; m->clients = c->next;
m->num = i; detachstack(c);
m->mx = m->wx = unique[i].x_org; c->mon = mons;
m->my = m->wy = unique[i].y_org; attach(c);
m->mw = m->ww = unique[i].width; attachstack(c);
m->mh = m->wh = unique[i].height;
updatebarpos(m);
}
} else { /* less monitors available nn < n */
for (i = nn; i < n; i++) {
for (m = mons; m && m->next; m = m->next);
while ((c = m->clients)) {
dirty = 1;
m->clients = c->next;
detachstack(c);
c->mon = mons;
attach(c);
attachstack(c);
}
if (m == selmon)
selmon = mons;
cleanupmon(m);
} }
if (m == selmon)
selmon = mons;
cleanupmon(m);
} }
free(unique); free(unique);
} else } else
@ -2631,12 +2637,10 @@ 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;
if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
return; return;
if (c == nexttiled(selmon->clients))
if (!c || !(c = nexttiled(c->next)))
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;
}