commit badc13c5fe0f1cccb605ac1c608cc32608d0b7c3
parent b707bc8662abe0380301a3820b43711a7ec512da
Author: ssnf <ssnf@ssnf.xyz>
Date: Mon, 28 Nov 2022 17:53:56 +0000
merge upstream changes
Diffstat:
A | LICENSE | | | 38 | ++++++++++++++++++++++++++++++++++++++ |
M | Makefile | | | 8 | ++------ |
M | config.h | | | 1 | + |
M | config.mk | | | 6 | +++++- |
M | drw.c | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
M | drw.h | | | 5 | +++-- |
D | dwm.1 | | | 0 | |
M | dwm.c | | | 208 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
M | util.c | | | 22 | +++++++++++----------- |
9 files changed, 227 insertions(+), 168 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,38 @@
+MIT/X Consortium License
+
+© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
+© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
+© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
+© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
+© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
+© 2007-2009 Christof Musik <christof at sendfax dot de>
+© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
+© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
+© 2008 Martin Hurton <martin dot hurton at gmail dot com>
+© 2008 Neale Pickett <neale dot woozle dot org>
+© 2009 Mate Nagy <mnagy at port70 dot net>
+© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
+© 2010-2012 Connor Lane Smith <cls@lubutu.com>
+© 2011 Christoph Lohmann <20h@r-36.net>
+© 2015-2016 Quentin Rameau <quinq@fifth.space>
+© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
+© 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
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
@@ -28,7 +28,7 @@ clean:
dist: clean
mkdir -p dwm-${VERSION}
cp -R LICENSE Makefile README config.def.h config.mk\
- dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
+ drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
rm -rf dwm-${VERSION}
@@ -37,12 +37,8 @@ install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f dwm ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
- mkdir -p ${DESTDIR}${MANPREFIX}/man1
- sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
uninstall:
- rm -f ${DESTDIR}${PREFIX}/bin/dwm\
- ${DESTDIR}${MANPREFIX}/man1/dwm.1
+ rm -f ${DESTDIR}${PREFIX}/bin/dwm
.PHONY: all options clean dist install uninstall
diff --git a/config.h b/config.h
@@ -45,6 +45,7 @@ static const Rule rules[] = {
static const float mfact = 0.5; /* 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 */
static const Layout layouts[] = {
/* symbol arrange function */
diff --git 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,6 +18,10 @@ XINERAMAFLAGS = -DXINERAMA
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
+# OpenBSD (uncomment)
+#FREETYPEINC = ${X11INC}/freetype2
+#MANPREFIX = ${PREFIX}/man
+
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res -lXrender
diff --git 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);
}
@@ -132,19 +133,6 @@ xfont_create(Drw* drw, const char* fontname, FcPattern* fontpattern)
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->xfont = xfont;
font->pattern = pattern;
@@ -248,12 +236,10 @@ drw_rect(Drw* drw, int x, int y, uint w, uint h, int filled, int invert)
int
drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, int invert)
{
- char buf[1024];
- int ty;
- uint ew;
- XftDraw* d = NULL;
- Fnt* usedfont, *curfont, *nextfont;
- size_t i, len;
+ int i, ty, ellipsis_x = 0;
+ unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
+ XftDraw *d = NULL;
+ Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char* utf8str;
@@ -261,13 +247,17 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
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);
@@ -277,8 +267,10 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
}
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) {
@@ -286,9 +278,27 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
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;
}
@@ -296,36 +306,25 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
}
}
- 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;
@@ -335,6 +334,12 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
* 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);
@@ -346,7 +351,6 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
- FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
@@ -363,6 +367,8 @@ drw_text(Drw* drw, int x, int y, uint w, uint h, uint lpad, const char* text, in
curfont->next = usedfont;
} else {
xfont_free(usedfont);
+ nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
+no_match:
usedfont = drw->fonts;
}
}
@@ -392,6 +398,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, uint len, uint* w, uint* h)
{
diff --git a/drw.h b/drw.h
@@ -35,8 +35,9 @@ void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt* drw_fontset_create(Drw* drw, const char* fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
-uint drw_fontset_getwidth(Drw* drw, const char* text);
-void drw_font_getexts(Fnt* font, const char* text, uint len, uint* w, uint* h);
+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 */
void drw_clr_create(Drw* drw, Color* dest, const char* clrname, uint alpha);
diff --git a/dwm.1 b/dwm.1
diff --git a/dwm.c b/dwm.c
@@ -100,23 +100,25 @@ typedef struct {
const Arg arg;
} Button;
-typedef struct Client {
- char name[256];
- float mina, maxa;
- int x, y, w, h;
- int oldx, oldy, oldw, oldh;
- int basew, baseh, incw, inch, maxw, maxh, minw, minh;
- int bw, oldbw;
- uint tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate;
- int isfullscreen, isterminal, noswallow;
- pid_t pid;
- struct Client* next;
- struct Client* snext;
- struct Client* swallowing;
- struct Monitor* mon;
- Window win;
-} Client;
+typedef struct Monitor Monitor;
+typedef struct Client Client;
+struct Client {
+ char name[256];
+ float mina, maxa;
+ int x, y, w, h;
+ int oldx, oldy, oldw, oldh;
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
+ int bw, oldbw;
+ unsigned int tags;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+ Window win;
+ int isterminal, noswallow;
+ pid_t pid;
+ Client* swallowing;
+};
typedef struct {
uint mod;
@@ -130,7 +132,7 @@ typedef struct {
void (*arrange)(struct Monitor*);
} Layout;
-typedef struct Monitor {
+struct Monitor {
float mfact;
int nmaster;
int num;
@@ -152,7 +154,7 @@ typedef struct Monitor {
struct Monitor* next;
Window barwin;
const Layout* lt[2];
-} Monitor;
+};
typedef struct {
const char* class;
@@ -189,7 +191,6 @@ static void drawbar(Monitor* m);
static void drawbars(void);
static void enternotify(XEvent* e);
static void expose(XEvent* e);
-static void fibonacci(Monitor *m);
static void focus(Client* c);
static void focusin(XEvent* e);
static void focusmon(const Arg* arg);
@@ -206,6 +207,7 @@ static void killclient(const Arg* arg);
static void manage(Window w, XWindowAttributes* wa);
static void mappingnotify(XEvent* e);
static void maprequest(XEvent* e);
+static void monocle(Monitor* m);
static void motionnotify(XEvent* e);
static void movemouse(const Arg* arg);
static Client* nexttiled(Client* c);
@@ -233,15 +235,14 @@ static void sigchld(int unused);
static void spawn(const Arg* arg);
static void tag(const Arg* arg);
static void tagmon(const Arg* arg);
+static void tile(Monitor* m);
static void togglebar(const Arg* arg);
static void togglefloating(const Arg* arg);
-static void togglefullscr(const Arg* arg);
static void toggletag(const Arg* arg);
static void toggleview(const Arg* arg);
static void unfocus(Client* c, int setfocus);
static void unmanage(Client* c, int destroyed);
static void unmapnotify(XEvent* e);
-static void updatebar(void);
static void updatebarpos(Monitor* m);
static void updatebars(void);
static void updateclientlist(void);
@@ -258,32 +259,30 @@ static Monitor* wintomon(Window w);
static int xerror(Display* dpy, XErrorEvent* error_event);
static int xerrordummy(Display* dpy, XErrorEvent* error_event);
static int xerrorstart(Display* dpy, XErrorEvent* error_event);
-static void xinitvisual();
static void zoom(const Arg* arg);
-/* swallow */
+static void fibonacci(Monitor *m);
static pid_t getparentprocess(pid_t p);
static int isdescprocess(pid_t p, pid_t c);
static Client* swallowingclient(Window w);
static Client* termforwin(const Client* c);
+static void togglefullscr(const Arg* arg);
+static void updatebar(void);
static pid_t winpid(Window w);
+static void xinitvisual();
/* variables */
static const char broken[] = "broken";
static char stext[256];
-static int scanner;
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 vp; /* vertical padding for bar */
-static int sp; /* side padding for bar */
static int (*xerrorxlib)(Display*, XErrorEvent*);
static uint numlockmask = 0;
-static void (*handler[LASTEvent])(XEvent*) = {
- [ButtonPress] = buttonpress,
- [ButtonRelease] = keyrelease,
- [ClientMessage] = clientmessage,
+static void (*handler[LASTEvent]) (XEvent *) = {
+ [ButtonPress] = buttonpress,
+ [ClientMessage] = clientmessage,
[ConfigureRequest] = configurerequest,
[ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify,
@@ -296,7 +295,8 @@ static void (*handler[LASTEvent])(XEvent*) = {
[MapRequest] = maprequest,
[MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify,
- [UnmapNotify] = unmapnotify
+ [UnmapNotify] = unmapnotify,
+ [ButtonRelease] = keyrelease
};
static Atom wmatom[WMLast], netatom[NetLast];
static int running = 1;
@@ -307,11 +307,13 @@ static Drw* drw;
static Monitor* mons, *selmon;
static Window root, wmcheckwin;
-static xcb_connection_t* xcon;
-
static Visual* visual;
static int depth;
static Colormap cmap;
+static int scanner;
+static int vp; /* vertical padding for bar */
+static int sp; /* side padding for bar */
+static xcb_connection_t* xcon;
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -457,6 +459,8 @@ 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 */
@@ -557,9 +561,9 @@ buttonpress(XEvent* e)
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
- } else if (ev->x < x + blw)
+ } else if (ev->x < x)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
+ else if (ev->x > selmon->ww - (int)TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
@@ -614,6 +618,7 @@ 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);
@@ -845,6 +850,9 @@ drawbar(Monitor* m)
Client* c;
+ if (!m->showbar)
+ return;
+
/* draw status first so it can be overdrawn by tags later */
tw = 0;
if (m == selmon && *stext) { /* status is only drawn on selected monitor */
@@ -1067,7 +1075,7 @@ focusstack(const Arg* arg)
{
Client* c, *i;
- if (!selmon->sel)
+ if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
return;
if (arg->i > sizeof(arg))
return;
@@ -1155,13 +1163,13 @@ gettextprop(Window w, Atom atom, char* text, uint size)
return 0;
if (!name.nitems)
return 0;
- if (name.encoding == XA_STRING)
- strncpy(text, (char*)name.value, size - 1);
- else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success) {
- if (n > 0 && *list) {
- strncpy(text, *list, size - 1);
- XFreeStringList(list);
- }
+ 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);
}
text[size - 1] = '\0';
XFree(name.value);
@@ -1289,11 +1297,12 @@ manage(Window w, XWindowAttributes* wa)
applyrules(c);
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);
+
+ 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);
/* only fix client y-offset, if the client center might cover the bar */
c->y = MAX(c->y,
((c->mon->by == c->mon->my)
@@ -1351,12 +1360,9 @@ void
maprequest(XEvent* e)
{
static XWindowAttributes wa;
- XMapRequestEvent* ev;
+ XMapRequestEvent* ev = &e->xmaprequest;
- 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);
@@ -1480,8 +1486,8 @@ propertynotify(XEvent* e)
default:
break;
case XA_WM_TRANSIENT_FOR:
- if (!c->isfloating &&
- (XGetTransientForHint(dpy, c->win, &trans))
+ if (!c->isfloating
+ && XGetTransientForHint(dpy, c->win, &trans)
&& (c->isfloating = (wintoclient(trans)) != NULL)
)
arrange(c->mon);
@@ -1958,10 +1964,8 @@ spawn(const Arg* arg)
if (dpy)
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);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
}
}
@@ -2080,6 +2084,7 @@ 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);
@@ -2195,47 +2200,46 @@ updategeom()
unique = ecalloc(nn, sizeof(XineramaScreenInfo));
for (i = 0, j = 0; i < nn; ++i)
if (isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
+ memcpy(&unique[j++], &info[i],
+ sizeof(XineramaScreenInfo)
+ );
XFree(info);
nn = j;
- if (n <= nn) { /* new mons 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 mons 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);
+ /* removed monitors if n > nn */
+ 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);
}
free(unique);
} else
@@ -2314,6 +2318,7 @@ updatesizehints(Client* c)
} else
c->maxa = c->mina = 0.0;
c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
+ c->hintsvalid = 1;
}
void
@@ -2580,11 +2585,10 @@ 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
@@ -5,18 +5,8 @@
#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;
@@ -31,3 +21,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;
+}