dwm

my dwm build
Log | Files | Refs | LICENSE

commit badc13c5fe0f1cccb605ac1c608cc32608d0b7c3
parent b707bc8662abe0380301a3820b43711a7ec512da
Author: ssnf <ssnf@ssnf.xyz>
Date:   Mon, 28 Nov 2022 17:53:56 +0000

merge upstream changes

Diffstat:
ALICENSE | 38++++++++++++++++++++++++++++++++++++++
MMakefile | 8++------
Mconfig.h | 1+
Mconfig.mk | 6+++++-
Mdrw.c | 107+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mdrw.h | 5+++--
Ddwm.1 | 0
Mdwm.c | 208++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mutil.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; +}