diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d221f09 --- /dev/null +++ b/LICENSE @@ -0,0 +1,37 @@ +MIT/X Consortium License + +© 2006-2019 Anselm R Garbe +© 2006-2009 Jukka Salmi +© 2006-2007 Sander van Dijk +© 2007-2011 Peter Hartlich +© 2007-2009 Szabolcs Nagy +© 2007-2009 Christof Musik +© 2007-2009 Premysl Hruby +© 2007-2008 Enno Gottox Boland +© 2008 Martin Hurton +© 2008 Neale Pickett +© 2009 Mate Nagy +© 2010-2016 Hiltjo Posthuma +© 2010-2012 Connor Lane Smith +© 2011 Christoph Lohmann <20h@r-36.net> +© 2015-2016 Quentin Rameau +© 2015-2016 Eric Pruitt +© 2016-2017 Markus Teich + +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 index de784d7..77bcbc0 100644 --- a/Makefile +++ b/Makefile @@ -15,51 +15,37 @@ options: @echo "CC = ${CC}" .c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< + ${CC} -c ${CFLAGS} $< ${OBJ}: config.h config.mk config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ + cp config.def.h $@ dwm: ${OBJ} - @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + ${CC} -o $@ ${OBJ} ${LDFLAGS} clean: - @echo cleaning - @rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz + rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz dist: clean - @echo creating dist tarball - @mkdir -p dwm-${VERSION} - @cp -R LICENSE Makefile README config.def.h config.mk \ + 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} - @tar -cf dwm-${VERSION}.tar dwm-${VERSION} - @gzip dwm-${VERSION}.tar - @rm -rf dwm-${VERSION} + tar -cf dwm-${VERSION}.tar dwm-${VERSION} + gzip dwm-${VERSION}.tar + rm -rf dwm-${VERSION} install: all - @echo installing executable file to ${DESTDIR}${PREFIX}/bin - @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dwm ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/dwm - @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 - @mkdir -p ${DESTDIR}${MANPREFIX}/man1 - @sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 - -config: - @mkdir -p ${HOME}/.config/dunst - @cp -rv dunstrc ${HOME}/.config/dunst/dunstrc - @cp -rv Xinitrc ${HOME}/.xinitrc + 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: - @echo removing executable file from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/dwm - @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/dwm.1 + rm -f ${DESTDIR}${PREFIX}/bin/dwm\ + ${DESTDIR}${MANPREFIX}/man1/dwm.1 .PHONY: all options clean dist install uninstall diff --git a/README b/README new file mode 100644 index 0000000..95d4fd0 --- /dev/null +++ b/README @@ -0,0 +1,48 @@ +dwm - dynamic window manager +============================ +dwm is an extremely fast, small, and dynamic window manager for X. + + +Requirements +------------ +In order to build dwm you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dwm is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dwm (if +necessary as root): + + make clean install + + +Running dwm +----------- +Add the following line to your .xinitrc to start dwm using startx: + + exec dwm + +In order to connect dwm to a specific display, make sure that +the DISPLAY environment variable is set correctly, e.g.: + + DISPLAY=foo.bar:1 exec dwm + +(This will start dwm on display :1 of the host foo.bar.) + +In order to display status info in the bar, you can do something +like this in your .xinitrc: + + while xsetroot -name "`date` `uptime | sed 's/.*,//'`" + do + sleep 1 + done & + exec dwm + + +Configuration +------------- +The configuration of dwm is done by creating a custom config.h +and (re)compiling the source code. diff --git a/config.def.h b/config.def.h index ccea5ca..2d824d1 100644 --- a/config.def.h +++ b/config.def.h @@ -2,7 +2,6 @@ /* appearance */ static const unsigned int borderpx = 1; /* border pixel of windows */ -static const unsigned int gappx = 5; /* gaps between windows */ static const unsigned int snap = 32; /* snap pixel */ static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ static const unsigned int systrayspacing = 2; /* systray spacing */ @@ -32,13 +31,8 @@ static const Rule rules[] = { * WM_NAME(STRING) = title */ /* class instance title tags mask isfloating monitor */ - { "Chromium", NULL, NULL, 1 << 1, False, -1 }, - { "Opera", NULL, NULL, 1 << 1, False, -1 }, - { NULL, NULL, "Audacious", 1 << 4, False, -1 }, - { "Thunar", NULL, NULL, 1 << 5, False, -1 }, - { "Thunderbird", NULL, NULL, 1 << 3, False, -1 }, - { "Pidgin", NULL, NULL, 1 << 2, False, -1 }, - { "qbittorent", NULL, NULL, 1 << 5, False, -1 }, + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ @@ -67,18 +61,10 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *termcmd[] = { "xterm", NULL }; -static const char *print_screen_cmd[] = { "scrot", "%Y-%m-%d-%H%M%S.png", "-e", "mv $f ~/images/screenshots", NULL }; -static const char *cmdlock[] = { "slock", NULL }; +static const char *termcmd[] = { "st", NULL }; static Key keys[] = { /* modifier key function argument */ - {0 , 0x1008ff02 , spawn, SHCMD ("xbacklight -inc 10")}, - {0 , 0x1008ff03 , spawn, SHCMD ("xbacklight -dec 10")}, - {0 , 0x1008ff11 , spawn, SHCMD ("pactl set-sink-volume 0 -5%")}, - {0 , 0x1008ff12 , spawn, SHCMD ("pactl set-sink-mute 0 toggle")}, - {0 , 0x1008ff13 , spawn, SHCMD ("pactl set-sink-volume 0 +5%")}, - { MODKEY|ShiftMask, XK_l, spawn, {.v = cmdlock } }, { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY, XK_b, togglebar, {0} }, @@ -102,9 +88,6 @@ static Key keys[] = { { MODKEY, XK_period, focusmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - { MODKEY, XK_minus, setgaps, {.i = -1 } }, - { MODKEY, XK_equal, setgaps, {.i = +1 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff --git a/config.h b/config.h index 031d644..d466fe5 100644 --- a/config.h +++ b/config.h @@ -68,15 +68,19 @@ static const char *ranger[] = { "st", "-ce", "ranger", NULL }; static const char *mixer[] = { "st", "-ce", "pulsemixer", NULL }; static const char *dmenumount[] = { "dmenumount", NULL }; static const char *dmenuumount[] = { "dmenuumount", NULL }; -static const char *cmusplay[] = { "cmus-remote", "-u", NULL }; -static const char *cmusnext[] = { "cmus-remote", "-n", NULL }; -static const char *cmusprev[] = { "cmus-remote", "-r", NULL }; +static const char *cmusplay[] = { "cmus-control", "play", NULL }; +static const char *cmusnext[] = { "cmus-control", "next", NULL }; +static const char *cmusprev[] = { "cmus-control", "prev", NULL }; static const char *shutdownpress[] = {"shut-sup-rest", "NULL" }; static const char *screenswitcher[] = { "screen-switcher", "NULL" }; static const char *volumeup[]= {"volume", "up", "NULL"}; static const char *volumedown[]= {"volume", "down", "NULL"}; static const char *volumetoggle[]= {"volume", "toggle", "NULL"}; +/* commands spawned when clicking statusbar, the mouse button pressed is exported as BUTTON */ +static char *statuscmds[] = { "notify-send Mouse$BUTTON" }; +static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; + static Key keys[] = { {0, 0x1008ff02, spawn, SHCMD ("sudo light -A 10")}, {0, 0x1008ff03, spawn, SHCMD ("sudo light -U 10")}, @@ -150,7 +154,9 @@ static Button buttons[] = { { ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkStatusText, 0, Button1, spawn, {.v = statuscmd } }, + { ClkStatusText, 0, Button2, spawn, {.v = statuscmd } }, + { ClkStatusText, 0, Button3, spawn, {.v = statuscmd } }, { ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, diff --git a/config.mk b/config.mk index b672a0b..9989ae9 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # dwm version -VERSION = 6.1 +VERSION = 6.2 # Customize below to fit your system @@ -10,6 +10,9 @@ MANPREFIX = ${PREFIX}/share/man X11INC = /usr/include/X11 X11LIB = /usr/lib/X11 +#X11INC = /usr/X11R6/include +#X11LIB = /usr/X11R6/lib + # Xinerama, comment if you don't want it XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA @@ -25,10 +28,10 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} +LDFLAGS = ${LIBS} # Solaris #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" diff --git a/drw.c b/drw.c index 10829e8..c1c265c 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); } @@ -200,7 +201,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) Clr *ret; /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(Clr)))) + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) return NULL; for (i = 0; i < clrcount; i++) @@ -337,6 +338,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp 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); @@ -419,4 +421,3 @@ drw_cur_free(Drw *drw, Cur *cursor) XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } - diff --git a/dwm.1 b/dwm.1 index 13b3729..ddc8321 100644 --- a/dwm.1 +++ b/dwm.1 @@ -33,7 +33,7 @@ dwm draws a small border around windows to indicate the focus state. .SH OPTIONS .TP .B \-v -prints version information to standard output, then exits. +prints version information to stderr, then exits. .SH USAGE .SS Status bar .TP diff --git a/dwm.c b/dwm.c index 78fdbff..6e4ea5f 100644 --- a/dwm.c +++ b/dwm.c @@ -138,7 +138,6 @@ struct Monitor { int by; /* bar geometry */ int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ - int gappx; /* gaps between windows */ unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; @@ -182,6 +181,7 @@ static void clientmessage(XEvent *e); static void configure(Client *c); static void configurenotify(XEvent *e); static void configurerequest(XEvent *e); +static void copyvalidchars(char *text, char *rawtext); static Monitor *createmon(void); static void destroynotify(XEvent *e); static void detach(Client *c); @@ -224,7 +224,6 @@ static void resizemouse(const Arg *arg); static void resizerequest(XEvent *e); static void restack(Monitor *m); static void run(void); -static void runAutostart(void); static void scan(void); static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); static void sendmon(Client *c, Monitor *m); @@ -232,7 +231,6 @@ static void setclientstate(Client *c, long state); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void fullscreen(const Arg *arg); -static void setgaps(const Arg *arg); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); @@ -276,7 +274,10 @@ static void zoom(const Arg *arg); /* variables */ static Systray *systray = NULL; static const char broken[] = "broken"; -static char stext[512]; +static char stext[256]; +static char rawstext[256]; +static int statuscmdn; +static char lastbutton[] = "-"; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ @@ -457,11 +458,12 @@ attachstack(Client *c) void buttonpress(XEvent *e) { - unsigned int i, x, click; + unsigned int i, x, click, occ = 0; Arg arg = {0}; Client *c; Monitor *m; XButtonPressedEvent *ev = &e->xbutton; + *lastbutton = '0' + ev->button; click = ClkRootWin; /* focus monitor if necessary */ @@ -472,23 +474,38 @@ buttonpress(XEvent *e) } if (ev->window == selmon->barwin) { i = x = 0; - unsigned int occ = 0; - for(c = m->clients; c; c = c->next) - occ |= c->tags; + for (c = m->clients; c; c = c->next) + occ |= c->tags == 255 ? 0 : c->tags; do { /* do not reserve space for vacant tags */ - if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) + if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue; - x += TEXTW(tags[i]); + x += TEXTW(tags[i]); } while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { + if (i < LENGTH(tags)) { click = ClkTagBar; arg.ui = 1 << i; } else if (ev->x < x + blw) click = ClkLtSymbol; - else if (ev->x > selmon->ww - TEXTW(stext)) + else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad - getsystraywidth() )) { click = ClkStatusText; - else + char *text = rawstext; + int i = -1; + char ch; + statuscmdn = 0; + while (text[++i]) { + if ((unsigned char)text[i] < ' ') { + ch = text[i]; + text[i] = '\0'; + x += TEXTW(text) - lrpad; + text[i] = ch; + text += i+1; + i = -1; + if (x >= ev->x) break; + if (ch <= LENGTH(statuscmds)) statuscmdn = ch - 1; + } + } + } else click = ClkWinTitle; } else if ((c = wintoclient(ev->window))) { focus(c); @@ -581,7 +598,12 @@ clientmessage(XEvent *e) c->mon = selmon; c->next = systray->icons; systray->icons = c; - XGetWindowAttributes(dpy, c->win, &wa); + if (!XGetWindowAttributes(dpy, c->win, &wa)) { + /* use sane defaults */ + wa.width = bh; + wa.height = bh; + wa.border_width = 0; + } c->x = c->oldx = c->y = c->oldy = 0; c->w = c->oldw = wa.width; c->h = c->oldh = wa.height; @@ -722,6 +744,20 @@ configurerequest(XEvent *e) XSync(dpy, False); } +void +copyvalidchars(char *text, char *rawtext) +{ + int i = -1, j = 0; + + while(rawtext[++i]) { + if ((unsigned char)rawtext[i] >= ' ') { + text[j++] = rawtext[i]; + } + } + text[j] = '\0'; +} + + Monitor * createmon(void) { @@ -733,7 +769,6 @@ createmon(void) m->nmaster = nmaster; m->showbar = showbar; m->topbar = topbar; - m->gappx = gappx; m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); @@ -796,7 +831,7 @@ dirtomon(int dir) void drawbar(Monitor *m) { - int x, w, sw = 0, stw = 0; + int x, w, tw = 0, stw = 0; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; @@ -808,22 +843,22 @@ drawbar(Monitor *m) /* 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]); - sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ - drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); - } + tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ + drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); + } resizebarwin(m); for (c = m->clients; c; c = c->next) { occ |= c->tags == 255 ? 0 : c->tags; - if (c->isurgent) + if (c->isurgent) urg |= c->tags; } x = 0; for (i = 0; i < LENGTH(tags); i++) { - /* do not draw vacant tags */ - if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) - continue; - w = TEXTW(tags[i]); + /* do not draw vacant tags */ + if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) + continue; + w = TEXTW(tags[i]); drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); x += w; @@ -832,7 +867,7 @@ drawbar(Monitor *m) drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - if ((w = m->ww - sw - stw - x) > bh) { + if ((w = m->ww - tw - stw - x) > bh) { if (m->sel) { drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); @@ -1555,12 +1590,6 @@ run(void) handler[ev.type](&ev); /* call handler */ } -void -runAutostart(void) { - system("cd ~/.dwm; ./autostart_blocking.sh"); - system("cd ~/.dwm; ./autostart.sh &"); -} - void scan(void) { @@ -1688,16 +1717,6 @@ setfullscreen(Client *c, int fullscreen) } } -void -setgaps(const Arg *arg) -{ - if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) - selmon->gappx = 0; - else - selmon->gappx += arg->i; - arrange(selmon); -} - Layout *last_layout; void fullscreen(const Arg *arg) @@ -1711,8 +1730,6 @@ fullscreen(const Arg *arg) togglebar(arg); } - - void setlayout(const Arg *arg) { @@ -1736,7 +1753,7 @@ setmfact(const Arg *arg) if (!arg || !selmon->lt[selmon->sellt]->arrange) return; f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.1 || f > 0.9) + if (f < 0.05 || f > 0.95) return; selmon->mfact = f; arrange(selmon); @@ -1866,6 +1883,10 @@ spawn(const Arg *arg) { if (arg->v == dmenucmd) dmenumon[0] = '0' + selmon->num; + else if (arg->v == statuscmd) { + statuscmd[2] = statuscmds[statuscmdn]; + setenv("BUTTON", lastbutton, 1); + } if (fork() == 0) { if (dpy) close(ConnectionNumber(dpy)); @@ -1908,16 +1929,18 @@ tile(Monitor *m) if (n > m->nmaster) mw = m->nmaster ? m->ww * m->mfact : 0; else - mw = m->ww - m->gappx; - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); - my += HEIGHT(c) + m->gappx; + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); + if (my + HEIGHT(c) < m->wh) + my += HEIGHT(c); } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); - ty += HEIGHT(c) + m->gappx; + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); + if (ty + HEIGHT(c) < m->wh) + ty += HEIGHT(c); } } @@ -2235,8 +2258,10 @@ updatesizehints(Client *c) void updatestatus(void) { - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext))) strcpy(stext, "dwm-"VERSION); + else + copyvalidchars(stext, rawstext); drawbar(selmon); updatesystray(); } @@ -2253,7 +2278,7 @@ updatesystrayicongeom(Client *i, int w, int h) else i->w = (int) ((float)bh * ((float)w / (float)h)); applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); - /* force icons into the systray dimenons if they don't want to */ + /* force icons into the systray dimensions if they don't want to */ if (i->h > bh) { if (i->w == i->h) i->w = bh; @@ -2527,11 +2552,10 @@ main(int argc, char *argv[]) checkotherwm(); setup(); #ifdef __OpenBSD__ - if (pledge("stdio proc exec", NULL) == -1) + if (pledge("stdio rpath proc exec", NULL) == -1) die("pledge"); #endif /* __OpenBSD__ */ scan(); - runAutostart(); run(); cleanup(); XCloseDisplay(dpy);