diff options
-rw-r--r-- | LICENSE | 27 | ||||
-rw-r--r-- | config.def.h | 21 | ||||
-rw-r--r-- | config.h | 53 | ||||
-rw-r--r-- | drw.c | 519 | ||||
-rw-r--r-- | drw.h | 70 | ||||
-rw-r--r-- | dwm.c | 1768 | ||||
-rw-r--r-- | util.c | 26 | ||||
-rw-r--r-- | util.h | 7 |
8 files changed, 990 insertions, 1501 deletions
@@ -1,7 +1,7 @@ -<<<<<<< HEAD MIT/X Consortium License -© 2006-2011 Anselm R Garbe <anselm@garbe.us> +© 2006-2014 Anselm R Garbe <anselm@garbe.us> +© 2010-2014 Hiltjo Posthuma <hiltjo@codemadness.org> © 2007-2011 Peter Hartlich <sgkkr at hartlich dot com> © 2010-2011 Connor Lane Smith <cls@lubutu.com> © 2006-2009 Jukka Salmi <jukka at salmi dot ch> @@ -31,26 +31,3 @@ 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. -======= -The MIT License (MIT) - -Copyright (c) 2014 FreeArtMan - -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. ->>>>>>> 41fe4babc896a28ea5e08230762cdecd9772de73 diff --git a/config.def.h b/config.def.h index 875885b..7054c06 100644 --- a/config.def.h +++ b/config.def.h @@ -1,7 +1,10 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; +static const char *fonts[] = { + "monospace:size=10" +}; +static const char dmenufont[] = "monospace:size=10"; static const char normbordercolor[] = "#444444"; static const char normbgcolor[] = "#222222"; static const char normfgcolor[] = "#bbbbbb"; @@ -10,8 +13,8 @@ static const char selbgcolor[] = "#005577"; static const char selfgcolor[] = "#eeeeee"; static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ -static const Bool showbar = True; /* False means no bar */ -static const Bool topbar = True; /* False means bottom bar */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; @@ -22,14 +25,14 @@ static const Rule rules[] = { * WM_NAME(STRING) = title */ /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, True, -1 }, - { "Firefox", NULL, NULL, 1 << 8, False, -1 }, + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const Layout layouts[] = { /* symbol arrange function */ @@ -51,7 +54,7 @@ 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", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; static const char *termcmd[] = { "st", NULL }; static Key keys[] = { @@ -1,15 +1,10 @@ /* See LICENSE file for copyright and license details. */ -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "kconfig.h" /* appearance */ -#ifdef CONFIG_DWM_PANGO -static const char font[] = "Sans 8"; -#else -static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -#endif +static const char *fonts[] = { + "monospace:size=10" +}; +static const char dmenufont[] = "monospace:size=10"; static const char normbordercolor[] = "#444444"; static const char normbgcolor[] = "#222222"; static const char normfgcolor[] = "#bbbbbb"; @@ -18,34 +13,26 @@ static const char selbgcolor[] = "#005577"; static const char selfgcolor[] = "#eeeeee"; static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ -static const Bool showbar = True; /* False means no bar */ -static const Bool topbar = True; /* False means bottom bar */ -#ifdef CONFIG_DWM_OPACITY -static const double defaultopacity = 0.75; -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY -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 */ -static const Bool systraypinningfailfirst = True; /* True: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const Bool showsystray = True; /* False means no systray */ -#endif -#ifdef CONFIG_DWM_PANGO -static const Bool statusmarkup = True; /* True means use pango markup in status message */ -#endif +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, True, -1 }, - { "Firefox", NULL, NULL, 1 << 8, False, -1 }, + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const Layout layouts[] = { /* symbol arrange function */ @@ -67,18 +54,13 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; -static const char *termcmd[] = { "uxterm", NULL }; +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; +static const char *termcmd[] = { "st", NULL }; static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, -#ifdef CONFIG_DWM_OPACITY - { MODKEY|ShiftMask, XK_s, spawn, SHCMD("transset-df -a --dec .1") }, - { MODKEY|ShiftMask, XK_d, spawn, SHCMD("transset-df -a --inc .1") }, - { MODKEY|ShiftMask, XK_f, spawn, SHCMD("transset-df -a .75") }, -#endif { MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, @@ -129,4 +111,3 @@ static Button buttons[] = { { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; -#endif @@ -3,20 +3,69 @@ #include <stdlib.h> #include <string.h> #include <X11/Xlib.h> +#include <X11/Xft/Xft.h> #include "drw.h" #include "util.h" -#ifdef CONFIG_DWM_PANGO -//char stext[512]; -//extern Bool statusmarkup; -#endif +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { - Drw *drw = (Drw *)calloc(1, sizeof(Drw)); - if(!drw) - return NULL; +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw; + + drw = ecalloc(1, sizeof(Drw)); drw->dpy = dpy; drw->screen = screen; drw->root = root; @@ -24,289 +73,325 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->h = h; drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->gc = XCreateGC(dpy, root, 0, NULL); + drw->fontcount = 0; XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + return drw; } void -drw_resize(Drw *drw, unsigned int w, unsigned int h) { - if(!drw) - return; +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ drw->w = w; drw->h = h; - if(drw->drawable != 0) + if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); } void -drw_free(Drw *drw) { +drw_free(Drw *drw) +{ + size_t i; + + for (i = 0; i < drw->fontcount; i++) + drw_font_free(drw->fonts[i]); XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); free(drw); } -Fnt * -drw_font_create(Display *dpy, const char *fontname) { +/* This function is an implementation detail. Library users should use + * drw_font_create instead. + */ +static Fnt * +drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ Fnt *font; - char *def, **missing; - int n; - - font = (Fnt *)calloc(1, sizeof(Fnt)); - if(!font) - return NULL; - -#ifdef CONFIG_DWM_PANGO - PangoFontMap *fontmap; - PangoContext *context; - PangoFontDescription *desc; - PangoFontMetrics *metrics; - - int screen = DefaultScreen(dpy); - fontmap = pango_xft_get_font_map(dpy, screen); - context = pango_font_map_create_context(fontmap); - desc = pango_font_description_from_string(fontname); - font->layout = pango_layout_new(context); - pango_layout_set_font_description(font->layout, desc); - - metrics = pango_context_get_metrics(context, desc, NULL); - font->ascent = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE; - font->descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; - font->h = font->ascent + font->descent; - - pango_font_metrics_unref(metrics); - g_object_unref(context); -#else - font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def); - if(missing) { - while(n--) - fprintf(stderr, "drw: missing fontset: %s\n", missing[n]); - XFreeStringList(missing); - } - if(font->set) { - XFontStruct **xfonts; - char **font_names; - XExtentsOfFontSet(font->set); - n = XFontsOfFontSet(font->set, &xfonts, &font_names); - while(n--) { - font->ascent = MAX(font->ascent, (*xfonts)->ascent); - font->descent = MAX(font->descent,(*xfonts)->descent); - xfonts++; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield same + * the same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in + * missing-character-rectangles being drawn, at least with some fonts. + */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + return NULL; } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font pattern.\n"); + return NULL; + } + } else { + die("no font specified.\n"); } - else { - if(!(font->xfont = XLoadQueryFont(dpy, fontname)) - && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) - die("error, cannot load font: '%s'\n", fontname); - font->ascent = font->xfont->ascent; - font->descent = font->xfont->descent; - } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->ascent = xfont->ascent; + font->descent = xfont->descent; font->h = font->ascent + font->descent; -#endif + font->dpy = drw->dpy; + return font; } +Fnt* +drw_font_create(Drw *drw, const char *fontname) +{ + return drw_font_xcreate(drw, fontname, NULL); +} + +void +drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) +{ + size_t i; + Fnt *font; + + for (i = 0; i < fontcount; i++) { + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { + die("font cache exhausted.\n"); + } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { + drw->fonts[drw->fontcount++] = font; + } + } +} + void -drw_font_free(Display *dpy, Fnt *font) { - if(!font) +drw_font_free(Fnt *font) +{ + if (!font) return; -#ifdef CONFIG_DWM_PANGO - g_object_unref(font->layout); -#else - if(font->set) - XFreeFontSet(dpy, font->set); - else - XFreeFont(dpy, font->xfont); -#endif + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); free(font); } Clr * -#ifdef CONFIG_DWM_PANGO -drw_clr_create(Drw *drw, const char *clrname, XftColor *color) { -#else -drw_clr_create(Drw *drw, const char *clrname) { -#endif +drw_clr_create(Drw *drw, const char *clrname) +{ Clr *clr; - Colormap cmap; -#ifdef CONFIG_DWM_PANGO - Visual *vis = DefaultVisual(drw->dpy, drw->screen); -#else - XColor color; -#endif - - if(!drw) - return NULL; - clr = (Clr *)calloc(1, sizeof(Clr)); - if(!clr) - return NULL; - cmap = DefaultColormap(drw->dpy, drw->screen); - -#ifdef CONFIG_DWM_PANGO - if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, color)) -#else - if(!XAllocNamedColor(drw->dpy, cmap, clrname, &color, &color)) -#endif + clr = ecalloc(1, sizeof(Clr)); + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, &clr->rgb)) die("error, cannot allocate color '%s'\n", clrname); - -#ifdef CONFIG_DWM_PANGO - clr->rgb = color->pixel; -#else - clr->rgb = color.pixel; -#endif + clr->pix = clr->rgb.pixel; return clr; } void -drw_clr_free(Clr *clr) { - if(clr) - free(clr); +drw_clr_free(Clr *clr) +{ + free(clr); } void -drw_setfont(Drw *drw, Fnt *font) { - if(drw) - drw->font = font; +drw_setscheme(Drw *drw, ClrScheme *scheme) +{ + drw->scheme = scheme; } void -drw_setscheme(Drw *drw, ClrScheme *scheme) { - if(drw && scheme) - drw->scheme = scheme; -} - -void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) { - int dx; - - if(!drw || !drw->font || !drw->scheme) +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) +{ + if (!drw->scheme) return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : drw->scheme->fg->rgb); - dx = (drw->font->ascent + drw->font->descent + 2) / 4; - if(filled) - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx+1, dx+1); - else if(empty) - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx, dx); + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); + else if (empty) + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); } -void -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) { -#ifdef CONFIG_DWM_PANGO - char buf[512]; -#else - char buf[256]; -#endif - int i, tx, ty, th, len, olen; +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) +{ + char buf[1024]; + int tx, ty, th; Extnts tex; + XftDraw *d = NULL; + Fnt *curfont, *nextfont; + size_t i, len; + int utf8strlen, utf8charlen, render; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0; + + if (!drw->scheme || !drw->fontcount) + return 0; + + if (!(render = x || y || w || h)) { + w = ~w; + } else { + XSetForeground(drw->dpy, drw->gc, invert ? + drw->scheme->fg->pix : drw->scheme->bg->pix); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + } - if(!drw || !drw->scheme) - return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->rgb : drw->scheme->bg->rgb); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - if(!text || !drw->font) - return; - olen = strlen(text); - drw_font_getexts(drw->font, text, olen, &tex); - th = drw->font->ascent + drw->font->descent; -#ifdef CONFIG_DWM_PANGO - ty = y + (h / 2) - (th / 2); -#else - ty = y + (h / 2) - (th / 2) + drw->font->ascent; -#endif - tx = x + (h / 2); - /* shorten text if necessary */ - /* shorten text if necessary (this could wreak havoc with pango markup but fortunately - dc.w is adjusted to the width of the status text and not the other way around) */ - for(len = MIN(olen, sizeof buf); len && (tex.w > w - tex.h || w < tex.h); len--) - drw_font_getexts(drw->font, text, len, &tex); - if(!len) - return; - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); -#ifdef CONFIG_DWM_PANGO - //if(text == stext && statusmarkup) - // pango_layout_set_markup(drw->font->layout, buf, len); - //else - pango_layout_set_text(drw->font->layout, buf, len); - //pango_xft_render_layout(drw->xft.drawable, - // (struct XftColor*)(invert ? drw->scheme->bg->rgb : drw->scheme->fg->rgb), - // drw->font->layout, x * PANGO_SCALE, y * PANGO_SCALE); - //if(text == stext && statusmarkup) /* clear markup attributes */ - // pango_layout_set_attributes(drw->font->layout, NULL); -#else - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : drw->scheme->fg->rgb); - if(drw->font->set) - XmbDrawString(drw->dpy, drw->drawable, drw->font->set, drw->gc, tx, ty, buf, len); - else - XDrawString(drw->dpy, drw->drawable, drw->gc, tx, ty, buf, len); -#endif + curfont = drw->fonts[0]; + while (1) { + utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (i = 0; i < drw->fontcount; i++) { + charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint); + if (charexists) { + if (drw->fonts[i] == curfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + } else { + nextfont = drw->fonts[i]; + } + break; + } + } + + if (!charexists || (nextfont && nextfont != curfont)) + break; + else + charexists = 0; + } + + if (utf8strlen) { + drw_font_getexts(curfont, utf8str, utf8strlen, &tex); + /* shorten text if necessary */ + for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) + drw_font_getexts(curfont, utf8str, len, &tex); + + if (len) { + memcpy(buf, utf8str, len); + buf[len] = '\0'; + if (len < utf8strlen) + for (i = len; i && i > len - 3; buf[--i] = '.'); + + if (render) { + th = curfont->ascent + curfont->descent; + ty = y + (h / 2) - (th / 2) + curfont->ascent; + tx = x + (h / 2); + XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); + } + x += tex.w; + w -= tex.w; + } + } + + if (!*text) { + break; + } else if (nextfont) { + charexists = 0; + curfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. + */ + charexists = 1; + + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) + continue; + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts[0]->pattern) { + /* Refer to the comment in drw_font_xcreate for more + * information. */ + die("the first font in the cache must be loaded from a font string.\n"); + } + + fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + curfont = drw_font_xcreate(drw, NULL, match); + if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { + drw->fonts[drw->fontcount++] = curfont; + } else { + drw_font_free(curfont); + curfont = drw->fonts[0]; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x; } void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { - if(!drw) - return; +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XSync(drw->dpy, False); } - void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { - if(!font || !text) - return; +drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) +{ + XGlyphInfo ext; -#ifdef CONFIG_DWM_PANGO - PangoRectangle r; - //if(text == stext && statusmarkup) - // pango_layout_set_markup(font->layout, text, len); - //else - pango_layout_set_text(font->layout, text, len); - pango_layout_get_extents(font->layout, 0, &r); - //if(text == stext && statusmarkup) /* clear markup attributes */ - // pango_layout_set_attributes(font->layout, NULL); - tex->h = r.height; - tex->w = r.width / PANGO_SCALE; -#else - XRectangle r; - if(font->set) { - XmbTextExtents(font->set, text, len, NULL, &r); - tex->w = r.width; - tex->h = r.height; - } - else { - tex->h = font->ascent + font->descent; - tex->w = XTextWidth(font->xfont, text, len); - } -#endif + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + tex->h = font->h; + tex->w = ext.xOff; } unsigned int -drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { +drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) +{ Extnts tex; - if(!font) - return -1; drw_font_getexts(font, text, len, &tex); + return tex.w; } Cur * -drw_cur_create(Drw *drw, int shape) { - Cur *cur = (Cur *)calloc(1, sizeof(Cur)); +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; - if(!drw || !cur) - return NULL; + cur = ecalloc(1, sizeof(Cur)); cur->cursor = XCreateFontCursor(drw->dpy, shape); + return cur; } void -drw_cur_free(Drw *drw, Cur *cursor) { - if(!drw || !cursor) +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) return; XFreeCursor(drw->dpy, cursor->cursor); free(cursor); @@ -1,21 +1,9 @@ /* See LICENSE file for copyright and license details. */ - -#include "kconfig.h" - -#ifdef CONFIG_DWM_PANGO -#include <X11/Xft/Xft.h> -#include <pango/pango.h> -#include <pango/pangoxft.h> +#define DRW_FONT_CACHE_SIZE 32 typedef struct { - XftColor norm[4]; - XftColor sel[4]; - XftDraw *drawable; -} Xft; -#endif - -typedef struct { - unsigned long rgb; + unsigned long pix; + XftColor rgb; } Clr; typedef struct { @@ -23,15 +11,12 @@ typedef struct { } Cur; typedef struct { + Display *dpy; int ascent; int descent; unsigned int h; -#ifdef CONFIG_DWM_PANGO - PangoLayout *layout; -#else - XFontSet set; - XFontStruct *xfont; -#endif + XftFont *xfont; + FcPattern *pattern; } Fnt; typedef struct { @@ -48,10 +33,8 @@ typedef struct { Drawable drawable; GC gc; ClrScheme *scheme; -#ifdef CONFIG_DWM_PANGO - Xft xft; -#endif - Fnt *font; + size_t fontcount; + Fnt *fonts[DRW_FONT_CACHE_SIZE]; } Drw; typedef struct { @@ -60,35 +43,32 @@ typedef struct { } Extnts; /* Drawable abstraction */ -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); -void drw_resize(Drw *drw, unsigned int w, unsigned int h); -void drw_free(Drw *drw); +Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); +void drw_resize(Drw *, unsigned int, unsigned int); +void drw_free(Drw *); /* Fnt abstraction */ -Fnt *drw_font_create(Display *dpy, const char *fontname); -void drw_font_free(Display *dpy, Fnt *font); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *extnts); -unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int len); +Fnt *drw_font_create(Drw *, const char *); +void drw_load_fonts(Drw *, const char *[], size_t); +void drw_font_free(Fnt *); +void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); +unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); /* Colour abstraction */ -#ifdef CONFIG_DWM_PANGO -Clr *drw_clr_create(Drw *drw, const char *clrname, XftColor *color); -#else -Clr *drw_clr_create(Drw *drw, const char *clrname); -#endif -void drw_clr_free(Clr *clr); +Clr *drw_clr_create(Drw *, const char *); +void drw_clr_free(Clr *); /* Cursor abstraction */ -Cur *drw_cur_create(Drw *drw, int shape); -void drw_cur_free(Drw *drw, Cur *cursor); +Cur *drw_cur_create(Drw *, int); +void drw_cur_free(Drw *, Cur *); /* Drawing context manipulation */ -void drw_setfont(Drw *drw, Fnt *font); -void drw_setscheme(Drw *drw, ClrScheme *scheme); +void drw_setfont(Drw *, Fnt *); +void drw_setscheme(Drw *, ClrScheme *); /* Drawing functions */ -void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert); -void drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert); +void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); +int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int); /* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); +void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); @@ -22,8 +22,8 @@ */ #include <errno.h> #include <locale.h> -#include <stdarg.h> #include <signal.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -39,11 +39,10 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif /* XINERAMA */ - +#include <X11/Xft/Xft.h> #include "drw.h" #include "util.h" -//#include "config.h" /* macros */ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) @@ -56,47 +55,17 @@ #define WIDTH(X) ((X)->w + 2 * (X)->bw) #define HEIGHT(X) ((X)->h + 2 * (X)->bw) #define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_font_getexts_width(drw->font, X, strlen(X)) + drw->font->h) - -#ifdef CONFIG_DWM_SYSTEMTRAY -#define SYSTEM_TRAY_REQUEST_DOCK 0 -#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 - -/* XEMBED messages */ -#define XEMBED_EMBEDDED_NOTIFY 0 -#define XEMBED_WINDOW_ACTIVATE 1 -#define XEMBED_FOCUS_IN 4 -#define XEMBED_MODALITY_ON 10 - -#define XEMBED_MAPPED (1 << 0) -#define XEMBED_WINDOW_ACTIVATE 1 -#define XEMBED_WINDOW_DEACTIVATE 2 - -#define VERSION_MAJOR 0 -#define VERSION_MINOR 0 -#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR -#endif +#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, -#ifdef CONFIG_DWM_OPACITY - NetWMWindowsOpacity, -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY - NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, -#endif NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -#ifdef CONFIG_DWM_SYSTEMTRAY -enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ -#endif - - typedef union { int i; @@ -123,7 +92,7 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; Client *next; Client *snext; Monitor *mon; @@ -142,10 +111,6 @@ typedef struct { void (*arrange)(Monitor *); } Layout; - -#ifdef CONFIG_DWM_PERTAG - typedef struct Pertag Pertag; -#endif struct Monitor { char ltsymbol[16]; float mfact; @@ -157,18 +122,14 @@ struct Monitor { unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; - Bool showbar; - Bool topbar; + int showbar; + int topbar; Client *clients; Client *sel; Client *stack; Monitor *next; Window barwin; const Layout *lt[2]; - -#ifdef CONFIG_DWM_PERTAG - Pertag *pertag; -#endif }; typedef struct { @@ -176,21 +137,13 @@ typedef struct { const char *instance; const char *title; unsigned int tags; - Bool isfloating; + int isfloating; int monitor; } Rule; -#ifdef CONFIG_DWM_SYSTEMTRAY -typedef struct Systray Systray; -struct Systray { - Window win; - Client *icons; -}; -#endif - /* function declarations */ static void applyrules(Client *c); -static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); static void arrange(Monitor *m); static void arrangemon(Monitor *m); static void attach(Client *c); @@ -217,10 +170,10 @@ static void focus(Client *c); static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); -static Bool getrootptr(int *x, int *y); +static int getrootptr(int *x, int *y); static long getstate(Window w); -static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -static void grabbuttons(Client *c, Bool focused); +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +static void grabbuttons(Client *c, int focused); static void grabkeys(void); static void incnmaster(const Arg *arg); static void keypress(XEvent *e); @@ -236,21 +189,17 @@ static void pop(Client *); static void propertynotify(XEvent *e); static void quit(const Arg *arg); static Monitor *recttomon(int x, int y, int w, int h); -static void resize(Client *c, int x, int y, int w, int h, Bool interact); +static void resize(Client *c, int x, int y, int w, int h, int interact); static void resizeclient(Client *c, int x, int y, int w, int h); static void resizemouse(const Arg *arg); static void restack(Monitor *m); static void run(void); static void scan(void); -#ifdef CONFIG_DWM_SYSTEMTRAY -static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); -#else -static Bool sendevent(Client *c, Atom proto); -#endif +static int sendevent(Client *c, Atom proto); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); -static void setfullscreen(Client *c, Bool fullscreen); +static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); @@ -264,10 +213,10 @@ static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); -static void unfocus(Client *c, Bool setfocus); -static void unmanage(Client *c, Bool destroyed); +static void unfocus(Client *c, int setfocus); +static void unmanage(Client *c, int destroyed); static void unmapnotify(XEvent *e); -static Bool updategeom(void); +static int updategeom(void); static void updatebarpos(Monitor *m); static void updatebars(void); static void updateclientlist(void); @@ -284,29 +233,10 @@ static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); static void zoom(const Arg *arg); -#ifdef CONFIG_DWM_OPACITY -static void opacity(Client *c, double opacity); -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY -static Atom getatomprop(Client *c, Atom prop); -static unsigned int getsystraywidth(); -static void removesystrayicon(Client *i); -static void resizebarwin(Monitor *m); -static void resizerequest(XEvent *e); -static Monitor *systraytomon(Monitor *m); -static void updatesystray(void); -static void updatesystrayicongeom(Client *i, int w, int h); -static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); -static Client *wintosystrayicon(Window w); -#endif /* variables */ static const char broken[] = "broken"; -#ifdef CONFIG_DWM_PANGO -static char stext[512]; -#else static char stext[256]; -#endif static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ @@ -326,48 +256,27 @@ static void (*handler[LASTEvent]) (XEvent *) = { [MapRequest] = maprequest, [MotionNotify] = motionnotify, [PropertyNotify] = propertynotify, -#ifdef CONFIG_DWM_SYSTEMTRAY - [ResizeRequest] = resizerequest, -#endif [UnmapNotify] = unmapnotify }; static Atom wmatom[WMLast], netatom[NetLast]; -static Bool running = True; +static int running = 1; static Cur *cursor[CurLast]; static ClrScheme scheme[SchemeLast]; static Display *dpy; static Drw *drw; -static Fnt *fnt; static Monitor *mons, *selmon; static Window root; -#ifdef CONFIG_DWM_SYSTEMTRAY -static Systray *systray = NULL; -static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; -static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; -#endif - /* configuration, allows nested code to access above variables */ #include "config.h" -#ifdef CONFIG_DWM_PERTAG -typedef struct Pertag { - unsigned int curtag, prevtag; /* current and previous tag */ - int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ - float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ - unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ - const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ - Bool showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ - Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ -} Pertag; -#endif - /* compile-time check if all tags fit into an unsigned int bit array. */ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; /* function implementations */ void -applyrules(Client *c) { +applyrules(Client *c) +{ const char *class, *instance; unsigned int i; const Rule *r; @@ -375,131 +284,137 @@ applyrules(Client *c) { XClassHint ch = { NULL, NULL }; /* rule matching */ - c->isfloating = c->tags = 0; + c->isfloating = 0; + c->tags = 0; XGetClassHint(dpy, c->win, &ch); class = ch.res_class ? ch.res_class : broken; instance = ch.res_name ? ch.res_name : broken; - for(i = 0; i < LENGTH(rules); i++) { + for (i = 0; i < LENGTH(rules); i++) { r = &rules[i]; - if((!r->title || strstr(c->name, r->title)) + if ((!r->title || strstr(c->name, r->title)) && (!r->class || strstr(class, r->class)) && (!r->instance || strstr(instance, r->instance))) { c->isfloating = r->isfloating; c->tags |= r->tags; - for(m = mons; m && m->num != r->monitor; m = m->next); - if(m) + for (m = mons; m && m->num != r->monitor; m = m->next); + if (m) c->mon = m; } } - if(ch.res_class) + if (ch.res_class) XFree(ch.res_class); - if(ch.res_name) + if (ch.res_name) XFree(ch.res_name); c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; } -Bool -applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact) { - Bool baseismin; +int +applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) +{ + int baseismin; Monitor *m = c->mon; /* set minimum possible */ *w = MAX(1, *w); *h = MAX(1, *h); - if(interact) { - if(*x > sw) + if (interact) { + if (*x > sw) *x = sw - WIDTH(c); - if(*y > sh) + if (*y > sh) *y = sh - HEIGHT(c); - if(*x + *w + 2 * c->bw < 0) + if (*x + *w + 2 * c->bw < 0) *x = 0; - if(*y + *h + 2 * c->bw < 0) + if (*y + *h + 2 * c->bw < 0) *y = 0; - } - else { - if(*x >= m->wx + m->ww) + } else { + if (*x >= m->wx + m->ww) *x = m->wx + m->ww - WIDTH(c); - if(*y >= m->wy + m->wh) + if (*y >= m->wy + m->wh) *y = m->wy + m->wh - HEIGHT(c); - if(*x + *w + 2 * c->bw <= m->wx) + if (*x + *w + 2 * c->bw <= m->wx) *x = m->wx; - if(*y + *h + 2 * c->bw <= m->wy) + if (*y + *h + 2 * c->bw <= m->wy) *y = m->wy; } - if(*h < bh) + if (*h < bh) *h = bh; - if(*w < bh) + if (*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) { /* 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 */ + if (!baseismin) { /* temporarily remove base dimensions */ *w -= c->basew; *h -= c->baseh; } /* adjust for aspect limits */ - if(c->mina > 0 && c->maxa > 0) { - if(c->maxa < (float)*w / *h) + if (c->mina > 0 && c->maxa > 0) { + if (c->maxa < (float)*w / *h) *w = *h * c->maxa + 0.5; - else if(c->mina < (float)*h / *w) + else if (c->mina < (float)*h / *w) *h = *w * c->mina + 0.5; } - if(baseismin) { /* increment calculation requires this */ + if (baseismin) { /* increment calculation requires this */ *w -= c->basew; *h -= c->baseh; } /* adjust for increment value */ - if(c->incw) + if (c->incw) *w -= *w % c->incw; - if(c->inch) + if (c->inch) *h -= *h % c->inch; /* restore base dimensions */ *w = MAX(*w + c->basew, c->minw); *h = MAX(*h + c->baseh, c->minh); - if(c->maxw) + if (c->maxw) *w = MIN(*w, c->maxw); - if(c->maxh) + if (c->maxh) *h = MIN(*h, c->maxh); } return *x != c->x || *y != c->y || *w != c->w || *h != c->h; } void -arrange(Monitor *m) { - if(m) +arrange(Monitor *m) +{ + if (m) showhide(m->stack); - else for(m = mons; m; m = m->next) + else for (m = mons; m; m = m->next) showhide(m->stack); - if(m) { + if (m) { arrangemon(m); restack(m); - } else for(m = mons; m; m = m->next) + } else for (m = mons; m; m = m->next) arrangemon(m); } void -arrangemon(Monitor *m) { +arrangemon(Monitor *m) +{ strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) + if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); } void -attach(Client *c) { +attach(Client *c) +{ c->next = c->mon->clients; c->mon->clients = c; } void -attachstack(Client *c) { +attachstack(Client *c) +{ c->snext = c->mon->stack; c->mon->stack = c; } void -buttonpress(XEvent *e) { +buttonpress(XEvent *e) +{ unsigned int i, x, click; Arg arg = {0}; Client *c; @@ -508,39 +423,38 @@ buttonpress(XEvent *e) { click = ClkRootWin; /* focus monitor if necessary */ - if((m = wintomon(ev->window)) && m != selmon) { - unfocus(selmon->sel, True); + if ((m = wintomon(ev->window)) && m != selmon) { + unfocus(selmon->sel, 1); selmon = m; focus(NULL); } - if(ev->window == selmon->barwin) { + if (ev->window == selmon->barwin) { i = x = 0; do x += TEXTW(tags[i]); - while(ev->x >= x && ++i < LENGTH(tags)); - if(i < LENGTH(tags)) { + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { click = ClkTagBar; arg.ui = 1 << i; - } - else if(ev->x < x + blw) + } else if (ev->x < x + blw) click = ClkLtSymbol; - else if(ev->x > selmon->ww - TEXTW(stext)) + else if (ev->x > selmon->ww - TEXTW(stext)) click = ClkStatusText; else click = ClkWinTitle; - } - else if((c = wintoclient(ev->window))) { + } else if ((c = wintoclient(ev->window))) { focus(c); click = ClkClientWin; } - for(i = 0; i < LENGTH(buttons); i++) - if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); } void -checkotherwm(void) { +checkotherwm(void) +{ xerrorxlib = XSetErrorHandler(xerrorstart); /* this causes an error if some other window manager is running */ XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); @@ -550,36 +464,28 @@ checkotherwm(void) { } void -cleanup(void) { +cleanup(void) +{ Arg a = {.ui = ~0}; Layout foo = { "", NULL }; Monitor *m; + size_t i; view(&a); selmon->lt[selmon->sellt] = &foo; - for(m = mons; m; m = m->next) - while(m->stack) - unmanage(m->stack, False); + for (m = mons; m; m = m->next) + while (m->stack) + unmanage(m->stack, 0); XUngrabKey(dpy, AnyKey, AnyModifier, root); - while(mons) + while (mons) cleanupmon(mons); -#ifdef CONFIG_DWM_SYSTEMTRAY - if(showsystray) { - XUnmapWindow(dpy, systray->win); - XDestroyWindow(dpy, systray->win); - free(systray); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < SchemeLast; i++) { + drw_clr_free(scheme[i].border); + drw_clr_free(scheme[i].bg); + drw_clr_free(scheme[i].fg); } -#endif - drw_cur_free(drw, cursor[CurNormal]); - drw_cur_free(drw, cursor[CurResize]); - drw_cur_free(drw, cursor[CurMove]); - drw_font_free(dpy, fnt); - drw_clr_free(scheme[SchemeNorm].border); - drw_clr_free(scheme[SchemeNorm].bg); - drw_clr_free(scheme[SchemeNorm].fg); - drw_clr_free(scheme[SchemeSel].border); - drw_clr_free(scheme[SchemeSel].bg); - drw_clr_free(scheme[SchemeSel].fg); drw_free(drw); XSync(dpy, False); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); @@ -587,13 +493,14 @@ cleanup(void) { } void -cleanupmon(Monitor *mon) { +cleanupmon(Monitor *mon) +{ Monitor *m; - if(mon == mons) + if (mon == mons) mons = mons->next; else { - for(m = mons; m && m->next != mon; m = m->next); + for (m = mons; m && m->next != mon; m = m->next); m->next = mon->next; } XUnmapWindow(dpy, mon->barwin); @@ -602,11 +509,12 @@ cleanupmon(Monitor *mon) { } void -clearurgent(Client *c) { +clearurgent(Client *c) +{ XWMHints *wmh; - c->isurgent = False; - if(!(wmh = XGetWMHints(dpy, c->win))) + c->isurgent = 0; + if (!(wmh = XGetWMHints(dpy, c->win))) return; wmh->flags &= ~XUrgencyHint; XSetWMHints(dpy, c->win, wmh); @@ -614,78 +522,29 @@ clearurgent(Client *c) { } void -clientmessage(XEvent *e) { +clientmessage(XEvent *e) +{ XClientMessageEvent *cme = &e->xclient; Client *c = wintoclient(cme->window); -#ifdef CONFIG_DWM_PERTAG - int i; -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY - XWindowAttributes wa; - XSetWindowAttributes swa; -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY - if(showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { - /* add systray icons */ - if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { - if(!(c = (Client *)calloc(1, sizeof(Client)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Client)); - c->win = cme->data.l[2]; - c->mon = selmon; - c->next = systray->icons; - systray->icons = c; - XGetWindowAttributes(dpy, c->win, &wa); - c->x = c->oldx = c->y = c->oldy = 0; - c->w = c->oldw = wa.width; - c->h = c->oldh = wa.height; - c->oldbw = wa.border_width; - c->bw = 0; - c->isfloating = True; - /* reuse tags field as mapped status */ - c->tags = 1; - updatesizehints(c); - updatesystrayicongeom(c, wa.width, wa.height); - XAddToSaveSet(dpy, c->win); - XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); - XReparentWindow(dpy, c->win, systray->win, 0, 0); - /* use parents background color */ - swa.background_pixel = scheme[SchemeNorm].bg->rgb; - XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - /* FIXME not sure if I have to send these events, too */ - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - XSync(dpy, False); - resizebarwin(selmon); - updatesystray(); - setclientstate(c, NormalState); - } - return; - } -#endif - if(!c) + + if (!c) return; - if(cme->message_type == netatom[NetWMState]) { - if(cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) + if (cme->message_type == netatom[NetWMState]) { + if (cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } - else if(cme->message_type == netatom[NetActiveWindow]) { - if(!ISVISIBLE(c)) { + } else if (cme->message_type == netatom[NetActiveWindow]) { + if (!ISVISIBLE(c)) { c->mon->seltags ^= 1; c->mon->tagset[c->mon->seltags] = c->tags; - #ifdef CONFIG_DWM_PERTAG - for(i=0; !(c->tags & 1 << i); i++); - view(&(Arg){.ui = 1 << i}); - #endif } pop(c); } } void -configure(Client *c) { +configure(Client *c) +{ XConfigureEvent ce; ce.type = ConfigureNotify; @@ -703,28 +562,22 @@ configure(Client *c) { } void -configurenotify(XEvent *e) { +configurenotify(XEvent *e) +{ Monitor *m; XConfigureEvent *ev = &e->xconfigure; - Bool dirty; + int dirty; - // TODO: updategeom handling sucks, needs to be simplified - if(ev->window == root) { + /* TODO: updategeom handling sucks, needs to be simplified */ + if (ev->window == root) { dirty = (sw != ev->width || sh != ev->height); sw = ev->width; sh = ev->height; - if(updategeom() || dirty) { + if (updategeom() || dirty) { drw_resize(drw, sw, bh); updatebars(); - for(m = mons; m; m = m->next) - #ifdef CONFIG_DWM_SYSTEMTRAY - resizebarwin(m); - #else + for (m = mons; m; m = m->next) XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); - #endif - #ifdef CONFIG_DWM_PANGO - //XftDrawChange(drw->xft->drawable, drw->drawable); - #endif focus(NULL); arrange(NULL); } @@ -732,46 +585,45 @@ configurenotify(XEvent *e) { } void -configurerequest(XEvent *e) { +configurerequest(XEvent *e) +{ Client *c; Monitor *m; XConfigureRequestEvent *ev = &e->xconfigurerequest; XWindowChanges wc; - if((c = wintoclient(ev->window))) { - if(ev->value_mask & CWBorderWidth) + if ((c = wintoclient(ev->window))) { + if (ev->value_mask & CWBorderWidth) c->bw = ev->border_width; - else if(c->isfloating || !selmon->lt[selmon->sellt]->arrange) { + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { m = c->mon; - if(ev->value_mask & CWX) { + if (ev->value_mask & CWX) { c->oldx = c->x; c->x = m->mx + ev->x; } - if(ev->value_mask & CWY) { + if (ev->value_mask & CWY) { c->oldy = c->y; c->y = m->my + ev->y; } - if(ev->value_mask & CWWidth) { + if (ev->value_mask & CWWidth) { c->oldw = c->w; c->w = ev->width; } - if(ev->value_mask & CWHeight) { + if (ev->value_mask & CWHeight) { c->oldh = c->h; c->h = ev->height; } - if((c->x + c->w) > m->mx + m->mw && c->isfloating) + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ - if((c->y + c->h) > m->my + m->mh && c->isfloating) + if ((c->y + c->h) > m->my + m->mh && c->isfloating) c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) configure(c); - if(ISVISIBLE(c)) + if (ISVISIBLE(c)) XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - } - else + } else configure(c); - } - else { + } else { wc.x = ev->x; wc.y = ev->y; wc.width = ev->width; @@ -785,14 +637,11 @@ configurerequest(XEvent *e) { } Monitor * -createmon(void) { +createmon(void) +{ Monitor *m; -#ifdef CONFIG_DWM_PERTAG - int i; -#endif - if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); + m = ecalloc(1, sizeof(Monitor)); m->tagset[0] = m->tagset[1] = 1; m->mfact = mfact; m->nmaster = nmaster; @@ -801,104 +650,77 @@ createmon(void) { m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -#ifdef CONFIG_DWM_PERTAG - if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); - m->pertag->curtag = m->pertag->prevtag = 1; - for(i=0; i <= LENGTH(tags); i++) { - /* init nmaster */ - m->pertag->nmasters[i] = m->nmaster; - - /* init mfacts */ - m->pertag->mfacts[i] = m->mfact; - - /* init layouts */ - m->pertag->ltidxs[i][0] = m->lt[0]; - m->pertag->ltidxs[i][1] = m->lt[1]; - m->pertag->sellts[i] = m->sellt; - - /* init showbar */ - m->pertag->showbars[i] = m->showbar; - - /* swap focus and zoomswap*/ - m->pertag->prevzooms[i] = NULL; - } -#endif return m; } void -destroynotify(XEvent *e) { +destroynotify(XEvent *e) +{ Client *c; XDestroyWindowEvent *ev = &e->xdestroywindow; - if((c = wintoclient(ev->window))) - unmanage(c, True); -#ifdef CONFIG_DWM_SYSTEMTRAY - else if((c = wintosystrayicon(ev->window))) { - removesystrayicon(c); - resizebarwin(selmon); - updatesystray(); - } -#endif + if ((c = wintoclient(ev->window))) + unmanage(c, 1); } void -detach(Client *c) { +detach(Client *c) +{ Client **tc; - for(tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); *tc = c->next; } void -detachstack(Client *c) { +detachstack(Client *c) +{ Client **tc, *t; - for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); *tc = c->snext; - if(c == c->mon->sel) { - for(t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); + if (c == c->mon->sel) { + for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); c->mon->sel = t; } } Monitor * -dirtomon(int dir) { +dirtomon(int dir) +{ Monitor *m = NULL; - if(dir > 0) { - if(!(m = selmon->next)) + if (dir > 0) { + if (!(m = selmon->next)) m = mons; - } - else if(selmon == mons) - for(m = mons; m->next; m = m->next); + } else if (selmon == mons) + for (m = mons; m->next; m = m->next); else - for(m = mons; m->next != selmon; m = m->next); + for (m = mons; m->next != selmon; m = m->next); return m; } void -drawbar(Monitor *m) { - int x, xx, w; +drawbar(Monitor *m) +{ + int x, xx, w, dx; unsigned int i, occ = 0, urg = 0; Client *c; -#ifdef CONFIG_DWM_SYSTEMTRAY - resizebarwin(m); -#endif - for(c = m->clients; c; c = c->next) { + dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; + + for (c = m->clients; c; c = c->next) { occ |= c->tags; - if(c->isurgent) + if (c->isurgent) urg |= c->tags; } x = 0; - for(i = 0; i < LENGTH(tags); i++) { + for (i = 0; i < LENGTH(tags); i++) { w = TEXTW(tags[i]); drw_setscheme(drw, m->tagset[m->seltags] & 1 << i ? &scheme[SchemeSel] : &scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, tags[i], urg & 1 << i); - drw_rect(drw, x, 0, w, bh, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, + drw_rect(drw, x + 1, 1, dx, dx, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, urg & 1 << i); x += w; } @@ -907,100 +729,87 @@ drawbar(Monitor *m) { drw_text(drw, x, 0, w, bh, m->ltsymbol, 0); x += w; xx = x; - if(m == selmon) { /* status is only drawn on selected monitor */ + if (m == selmon) { /* status is only drawn on selected monitor */ w = TEXTW(stext); x = m->ww - w; - if(x < xx) { + if (x < xx) { x = xx; w = m->ww - xx; } drw_text(drw, x, 0, w, bh, stext, 0); - } - else + } else x = m->ww; -#ifdef CONFIG_DWM_SYSTEMTRAY - if(showsystray && m == systraytomon(m)) { - x -= getsystraywidth(); - } -#endif - if((w = x - xx) > bh) { + if ((w = x - xx) > bh) { x = xx; - if(m->sel) { + if (m->sel) { drw_setscheme(drw, m == selmon ? &scheme[SchemeSel] : &scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, m->sel->name, 0); - drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, 0); - } - else { + drw_rect(drw, x + 1, 1, dx, dx, m->sel->isfixed, m->sel->isfloating, 0); + } else { drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, NULL, 0); + drw_rect(drw, x, 0, w, bh, 1, 0, 1); } } drw_map(drw, m->barwin, 0, 0, m->ww, bh); } void -drawbars(void) { +drawbars(void) +{ Monitor *m; - for(m = mons; m; m = m->next) + for (m = mons; m; m = m->next) drawbar(m); -#ifdef CONFIG_DWM_SYSTEMTRAY - updatesystray(); -#endif } void -enternotify(XEvent *e) { +enternotify(XEvent *e) +{ Client *c; Monitor *m; XCrossingEvent *ev = &e->xcrossing; - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; c = wintoclient(ev->window); m = c ? c->mon : wintomon(ev->window); - if(m != selmon) { - unfocus(selmon->sel, True); + if (m != selmon) { + unfocus(selmon->sel, 1); selmon = m; - } - else if(!c || c == selmon->sel) + } else if (!c || c == selmon->sel) return; focus(c); } void -expose(XEvent *e) { +expose(XEvent *e) +{ Monitor *m; XExposeEvent *ev = &e->xexpose; - if(ev->count == 0 && (m = wintomon(ev->window))){ + if (ev->count == 0 && (m = wintomon(ev->window))) drawbar(m); - #ifdef CONFIG_DWM_SYSTEMTRAY - if(m == selmon) - updatesystray(); - #endif - } } void -focus(Client *c) { - if(!c || !ISVISIBLE(c)) - for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - /* was if(selmon->sel) */ - if(selmon->sel && selmon->sel != c) - unfocus(selmon->sel, False); - if(c) { - if(c->mon != selmon) +focus(Client *c) +{ + if (!c || !ISVISIBLE(c)) + for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); + /* was if (selmon->sel) */ + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) { + if (c->mon != selmon) selmon = c->mon; - if(c->isurgent) + if (c->isurgent) clearurgent(c); detachstack(c); attachstack(c); - grabbuttons(c, True); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->rgb); + grabbuttons(c, 1); + XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->pix); setfocus(c); - } - else { + } else { XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); XDeleteProperty(dpy, root, netatom[NetActiveWindow]); } @@ -1008,87 +817,76 @@ focus(Client *c) { drawbars(); } +/* there are some broken focus acquiring clients */ void -focusin(XEvent *e) { /* there are some broken focus acquiring clients */ +focusin(XEvent *e) +{ XFocusChangeEvent *ev = &e->xfocus; - if(selmon->sel && ev->window != selmon->sel->win) + if (selmon->sel && ev->window != selmon->sel->win) setfocus(selmon->sel); } void -focusmon(const Arg *arg) { +focusmon(const Arg *arg) +{ Monitor *m; - if(!mons->next) + if (!mons->next) return; - if((m = dirtomon(arg->i)) == selmon) + if ((m = dirtomon(arg->i)) == selmon) return; - unfocus(selmon->sel, False); /* s/True/False/ fixes input focus issues + unfocus(selmon->sel, 0); /* s/1/0/ fixes input focus issues in gedit and anjuta */ selmon = m; focus(NULL); } void -focusstack(const Arg *arg) { +focusstack(const Arg *arg) +{ Client *c = NULL, *i; - if(!selmon->sel) + if (!selmon->sel) return; - if(arg->i > 0) { - for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); - if(!c) - for(c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } - else { - for(i = selmon->clients; i != selmon->sel; i = i->next) - if(ISVISIBLE(i)) + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + if (!c) + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + } else { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i)) c = i; - if(!c) - for(; i; i = i->next) - if(ISVISIBLE(i)) + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i)) c = i; } - if(c) { + if (c) { focus(c); restack(selmon); } } Atom -getatomprop(Client *c, Atom prop) { +getatomprop(Client *c, Atom prop) +{ int di; unsigned long dl; unsigned char *p = NULL; Atom da, atom = None; -#ifdef CONFIG_DWM_SYSTEMTRAY - /* FIXME getatomprop should return the number of items and a pointer to - * the stored data instead of this workaround */ - Atom req = XA_ATOM; - if(prop == xatom[XembedInfo]) - req = xatom[XembedInfo]; -#endif - - if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, -#ifdef CONFIG_DWM_SYSTEMTRAY - req, -#else - XA_ATOM, -#endif + + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, &da, &di, &dl, &dl, &p) == Success && p) { atom = *(Atom *)p; - #ifdef CONFIG_DWM_SYSTEMTRAY - if(da == xatom[XembedInfo] && dl == 2) - atom = ((Atom *)p)[1]; - #endif XFree(p); } return atom; } -Bool -getrootptr(int *x, int *y) { +int +getrootptr(int *x, int *y) +{ int di; unsigned int dui; Window dummy; @@ -1097,71 +895,74 @@ getrootptr(int *x, int *y) { } long -getstate(Window w) { +getstate(Window w) +{ int format; long result = -1; unsigned char *p = NULL; unsigned long n, extra; Atom real; - if(XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], + if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], &real, &format, &n, &extra, (unsigned char **)&p) != Success) return -1; - if(n != 0) + if (n != 0) result = *p; XFree(p); return result; } -Bool -gettextprop(Window w, Atom atom, char *text, unsigned int size) { +int +gettextprop(Window w, Atom atom, char *text, unsigned int size) +{ char **list = NULL; int n; XTextProperty name; - if(!text || size == 0) - return False; + if (!text || size == 0) + return 0; text[0] = '\0'; XGetTextProperty(dpy, w, &name, atom); - if(!name.nitems) - return False; - if(name.encoding == XA_STRING) + 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 && n > 0 && *list) { + if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { strncpy(text, *list, size - 1); XFreeStringList(list); } } text[size - 1] = '\0'; XFree(name.value); - return True; + return 1; } void -grabbuttons(Client *c, Bool focused) { +grabbuttons(Client *c, int focused) +{ updatenumlockmask(); { unsigned int i, j; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if(focused) { - for(i = 0; i < LENGTH(buttons); i++) - if(buttons[i].click == ClkClientWin) - for(j = 0; j < LENGTH(modifiers); j++) + if (focused) { + for (i = 0; i < LENGTH(buttons); i++) + if (buttons[i].click == ClkClientWin) + for (j = 0; j < LENGTH(modifiers); j++) XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - } - else + } else XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); } } void -grabkeys(void) { +grabkeys(void) +{ updatenumlockmask(); { unsigned int i, j; @@ -1169,60 +970,55 @@ grabkeys(void) { KeyCode code; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) - if((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for(j = 0; j < LENGTH(modifiers); j++) + for (i = 0; i < LENGTH(keys); i++) + if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); } } void -incnmaster(const Arg *arg) { - -#ifdef CONFIG_DWM_PERTAG - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); -#else +incnmaster(const Arg *arg) +{ selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); -#endif arrange(selmon); } #ifdef XINERAMA -static Bool -isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { - while(n--) - if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org +static int +isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) +{ + while (n--) + if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org && unique[n].width == info->width && unique[n].height == info->height) - return False; - return True; + return 0; + return 1; } #endif /* XINERAMA */ void -keypress(XEvent *e) { +keypress(XEvent *e) +{ unsigned int i; KeySym keysym; XKeyEvent *ev; ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for(i = 0; i < LENGTH(keys); i++) - if(keysym == keys[i].keysym + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) keys[i].func(&(keys[i].arg)); } void -killclient(const Arg *arg) { - if(!selmon->sel) +killclient(const Arg *arg) +{ + if (!selmon->sel) return; -#ifdef CONFIG_DWM_SYSTEMTRAY - if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { -#else - if(!sendevent(selmon->sel, wmatom[WMDelete])) { -#endif + if (!sendevent(selmon->sel, wmatom[WMDelete])) { XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); @@ -1234,23 +1030,19 @@ killclient(const Arg *arg) { } void -manage(Window w, XWindowAttributes *wa) { +manage(Window w, XWindowAttributes *wa) +{ Client *c, *t = NULL; Window trans = None; XWindowChanges wc; - if(!(c = calloc(1, sizeof(Client)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Client)); + c = ecalloc(1, sizeof(Client)); c->win = w; updatetitle(c); -#ifdef CONFIG_DWM_OPACITY - opacity(c, defaultopacity); -#endif - if(XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { c->mon = t->mon; c->tags = t->tags; - } - else { + } else { c->mon = selmon; applyrules(c); } @@ -1261,9 +1053,9 @@ manage(Window w, XWindowAttributes *wa) { c->h = c->oldh = wa->height; c->oldbw = wa->border_width; - if(c->x + WIDTH(c) > c->mon->mx + c->mon->mw) + 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) + 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); /* only fix client y-offset, if the client center might cover the bar */ @@ -1273,16 +1065,16 @@ manage(Window w, XWindowAttributes *wa) { wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc); - XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->rgb); + XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->pix); configure(c); /* propagates border_width, if size doesn't change */ updatewindowtype(c); updatesizehints(c); updatewmhints(c); XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, False); - if(!c->isfloating) + grabbuttons(c, 0); + if (!c->isfloating) c->isfloating = c->oldstate = trans != None || c->isfixed; - if(c->isfloating) + if (c->isfloating) XRaiseWindow(dpy, c->win); attach(c); attachstack(c); @@ -1291,7 +1083,7 @@ manage(Window w, XWindowAttributes *wa) { XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ setclientstate(c, NormalState); if (c->mon == selmon) - unfocus(selmon->sel, False); + unfocus(selmon->sel, 0); c->mon->sel = c; arrange(c->mon); XMapWindow(dpy, c->win); @@ -1299,59 +1091,55 @@ manage(Window w, XWindowAttributes *wa) { } void -mappingnotify(XEvent *e) { +mappingnotify(XEvent *e) +{ XMappingEvent *ev = &e->xmapping; XRefreshKeyboardMapping(ev); - if(ev->request == MappingKeyboard) + if (ev->request == MappingKeyboard) grabkeys(); } void -maprequest(XEvent *e) { +maprequest(XEvent *e) +{ static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; -#ifdef CONFIG_DWM_SYSTEMTRAY - Client *i; - if((i = wintosystrayicon(ev->window))) { - sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); - resizebarwin(selmon); - updatesystray(); - } -#endif - if(!XGetWindowAttributes(dpy, ev->window, &wa)) + if (!XGetWindowAttributes(dpy, ev->window, &wa)) return; - if(wa.override_redirect) + if (wa.override_redirect) return; - if(!wintoclient(ev->window)) + if (!wintoclient(ev->window)) manage(ev->window, &wa); } void -monocle(Monitor *m) { +monocle(Monitor *m) +{ unsigned int n = 0; Client *c; - for(c = m->clients; c; c = c->next) - if(ISVISIBLE(c)) + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) n++; - if(n > 0) /* override layout symbol */ + if (n > 0) /* override layout symbol */ snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); - for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); } void -motionnotify(XEvent *e) { +motionnotify(XEvent *e) +{ static Monitor *mon = NULL; Monitor *m; XMotionEvent *ev = &e->xmotion; - if(ev->window != root) + if (ev->window != root) return; - if((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { - unfocus(selmon->sel, True); + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { + unfocus(selmon->sel, 1); selmon = m; focus(NULL); } @@ -1359,23 +1147,25 @@ motionnotify(XEvent *e) { } void -movemouse(const Arg *arg) { +movemouse(const Arg *arg) +{ int x, y, ocx, ocy, nx, ny; Client *c; Monitor *m; XEvent ev; + Time lasttime = 0; - if(!(c = selmon->sel)) + if (!(c = selmon->sel)) return; - if(c->isfullscreen) /* no support moving fullscreen windows by mouse */ + if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ return; restack(selmon); ocx = c->x; ocy = c->y; - if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) return; - if(!getrootptr(&x, &y)) + if (!getrootptr(&x, &y)) return; do { XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); @@ -1386,29 +1176,33 @@ movemouse(const Arg *arg) { handler[ev.type](&ev); break; case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + nx = ocx + (ev.xmotion.x - x); ny = ocy + (ev.xmotion.y - y); - if(nx >= selmon->wx && nx <= selmon->wx + selmon->ww + if (nx >= selmon->wx && nx <= selmon->wx + selmon->ww && ny >= selmon->wy && ny <= selmon->wy + selmon->wh) { - if(abs(selmon->wx - nx) < snap) + if (abs(selmon->wx - nx) < snap) nx = selmon->wx; - else if(abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) + else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) nx = selmon->wx + selmon->ww - WIDTH(c); - if(abs(selmon->wy - ny) < snap) + if (abs(selmon->wy - ny) < snap) ny = selmon->wy; - else if(abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) + else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) ny = selmon->wy + selmon->wh - HEIGHT(c); - if(!c->isfloating && selmon->lt[selmon->sellt]->arrange + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) togglefloating(NULL); } - if(!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, nx, ny, c->w, c->h, True); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, nx, ny, c->w, c->h, 1); break; } - } while(ev.type != ButtonRelease); + } while (ev.type != ButtonRelease); XUngrabPointer(dpy, CurrentTime); - if((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { sendmon(c, m); selmon = m; focus(NULL); @@ -1416,13 +1210,15 @@ movemouse(const Arg *arg) { } Client * -nexttiled(Client *c) { - for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); +nexttiled(Client *c) +{ + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); return c; } void -pop(Client *c) { +pop(Client *c) +{ detach(c); attach(c); focus(c); @@ -1430,33 +1226,21 @@ pop(Client *c) { } void -propertynotify(XEvent *e) { +propertynotify(XEvent *e) +{ Client *c; Window trans; XPropertyEvent *ev = &e->xproperty; -#ifdef CONFIG_DWM_SYSTEMTRAY - if((c = wintosystrayicon(ev->window))) { - if(ev->atom == XA_WM_NORMAL_HINTS) { - updatesizehints(c); - updatesystrayicongeom(c, c->w, c->h); - } - else - updatesystrayiconstate(c, ev); - resizebarwin(selmon); - updatesystray(); - } -#endif - - if((ev->window == root) && (ev->atom == XA_WM_NAME)) + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); - else if(ev->state == PropertyDelete) + else if (ev->state == PropertyDelete) return; /* ignore */ - else if((c = wintoclient(ev->window))) { + else if ((c = wintoclient(ev->window))) { switch(ev->atom) { 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); break; @@ -1468,28 +1252,30 @@ propertynotify(XEvent *e) { drawbars(); break; } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { updatetitle(c); - if(c == c->mon->sel) + if (c == c->mon->sel) drawbar(c->mon); } - if(ev->atom == netatom[NetWMWindowType]) + if (ev->atom == netatom[NetWMWindowType]) updatewindowtype(c); } } void -quit(const Arg *arg) { - running = False; +quit(const Arg *arg) +{ + running = 0; } Monitor * -recttomon(int x, int y, int w, int h) { +recttomon(int x, int y, int w, int h) +{ Monitor *m, *r = selmon; int a, area = 0; - for(m = mons; m; m = m->next) - if((a = INTERSECT(x, y, w, h, m)) > area) { + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) { area = a; r = m; } @@ -1497,13 +1283,15 @@ recttomon(int x, int y, int w, int h) { } void -resize(Client *c, int x, int y, int w, int h, Bool interact) { - if(applysizehints(c, &x, &y, &w, &h, interact)) +resize(Client *c, int x, int y, int w, int h, int interact) +{ + if (applysizehints(c, &x, &y, &w, &h, interact)) resizeclient(c, x, y, w, h); } void -resizeclient(Client *c, int x, int y, int w, int h) { +resizeclient(Client *c, int x, int y, int w, int h) +{ XWindowChanges wc; c->oldx = c->x; c->x = wc.x = x; @@ -1517,21 +1305,22 @@ resizeclient(Client *c, int x, int y, int w, int h) { } void -resizemouse(const Arg *arg) { - int ocx, ocy; - int nw, nh; +resizemouse(const Arg *arg) +{ + int ocx, ocy, nw, nh; Client *c; Monitor *m; XEvent ev; + Time lasttime = 0; - if(!(c = selmon->sel)) + if (!(c = selmon->sel)) return; - if(c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ return; restack(selmon); ocx = c->x; ocy = c->y; - if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) return; XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); @@ -1544,24 +1333,28 @@ resizemouse(const Arg *arg) { handler[ev.type](&ev); break; case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); - if(c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww + if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) { - if(!c->isfloating && selmon->lt[selmon->sellt]->arrange + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) togglefloating(NULL); } - if(!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, c->x, c->y, nw, nh, True); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, c->x, c->y, nw, nh, 1); break; } - } while(ev.type != ButtonRelease); + } while (ev.type != ButtonRelease); XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); XUngrabPointer(dpy, CurrentTime); - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - if((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { sendmon(c, m); selmon = m; focus(NULL); @@ -1569,70 +1362,74 @@ resizemouse(const Arg *arg) { } void -restack(Monitor *m) { +restack(Monitor *m) +{ Client *c; XEvent ev; XWindowChanges wc; drawbar(m); - if(!m->sel) + if (!m->sel) return; - if(m->sel->isfloating || !m->lt[m->sellt]->arrange) + if (m->sel->isfloating || !m->lt[m->sellt]->arrange) XRaiseWindow(dpy, m->sel->win); - if(m->lt[m->sellt]->arrange) { + if (m->lt[m->sellt]->arrange) { wc.stack_mode = Below; wc.sibling = m->barwin; - for(c = m->stack; c; c = c->snext) - if(!c->isfloating && ISVISIBLE(c)) { + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) { XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); wc.sibling = c->win; } } XSync(dpy, False); - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } void -run(void) { +run(void) +{ XEvent ev; /* main event loop */ XSync(dpy, False); - while(running && !XNextEvent(dpy, &ev)) - if(handler[ev.type]) + while (running && !XNextEvent(dpy, &ev)) + if (handler[ev.type]) handler[ev.type](&ev); /* call handler */ } void -scan(void) { +scan(void) +{ unsigned int i, num; Window d1, d2, *wins = NULL; XWindowAttributes wa; - if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for(i = 0; i < num; i++) { - if(!XGetWindowAttributes(dpy, wins[i], &wa) + if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + for (i = 0; i < num; i++) { + if (!XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; - if(wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) manage(wins[i], &wa); } - for(i = 0; i < num; i++) { /* now the transients */ - if(!XGetWindowAttributes(dpy, wins[i], &wa)) + for (i = 0; i < num; i++) { /* now the transients */ + if (!XGetWindowAttributes(dpy, wins[i], &wa)) continue; - if(XGetTransientForHint(dpy, wins[i], &d1) + if (XGetTransientForHint(dpy, wins[i], &d1) && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) manage(wins[i], &wa); } - if(wins) + if (wins) XFree(wins); } } void -sendmon(Client *c, Monitor *m) { - if(c->mon == m) +sendmon(Client *c, Monitor *m) +{ + if (c->mon == m) return; - unfocus(c, True); + unfocus(c, 1); detach(c); detachstack(c); c->mon = m; @@ -1644,105 +1441,68 @@ sendmon(Client *c, Monitor *m) { } void -setclientstate(Client *c, long state) { +setclientstate(Client *c, long state) +{ long data[] = { state, None }; XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, PropModeReplace, (unsigned char *)data, 2); } -Bool -#ifdef CONFIG_DWM_SYSTEMTRAY -sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) { -#else -sendevent(Client *c, Atom proto) { -#endif +int +sendevent(Client *c, Atom proto) +{ int n; Atom *protocols; -#ifdef CONFIG_DWM_SYSTEMTRAY - Atom mt; -#endif - Bool exists = False; + int exists = 0; XEvent ev; -#ifdef CONFIG_DWM_SYSTEMTRAY - if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { - mt = wmatom[WMProtocols]; - if(XGetWMProtocols(dpy, w, &protocols, &n)) { - while(!exists && n--) - exists = protocols[n] == proto; - XFree(protocols); - } - } - else { - exists = True; - mt = proto; - } -#else - if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { - while(!exists && n--) + if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { + while (!exists && n--) exists = protocols[n] == proto; XFree(protocols); } -#endif - if(exists) { + if (exists) { ev.type = ClientMessage; - #ifdef CONFIG_DWM_SYSTEMTRAY - ev.xclient.window = w; - ev.xclient.message_type = mt; - #else ev.xclient.window = c->win; ev.xclient.message_type = wmatom[WMProtocols]; - #endif ev.xclient.format = 32; - #ifdef CONFIG_DWM_SYSTEMTRAY - ev.xclient.data.l[0] = d0; - ev.xclient.data.l[1] = d1; - ev.xclient.data.l[2] = d2; - ev.xclient.data.l[3] = d3; - ev.xclient.data.l[4] = d4; - XSendEvent(dpy, w, False, mask, &ev); - #else ev.xclient.data.l[0] = proto; ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, c->win, False, NoEventMask, &ev); - #endif } return exists; } void -setfocus(Client *c) { - if(!c->neverfocus) { +setfocus(Client *c) +{ + if (!c->neverfocus) { XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XChangeProperty(dpy, root, netatom[NetActiveWindow], - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); } -#ifdef CONFIG_DWM_SYSTEMTRAY - sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); -#else sendevent(c, wmatom[WMTakeFocus]); -#endif } void -setfullscreen(Client *c, Bool fullscreen) { - if(fullscreen) { +setfullscreen(Client *c, int fullscreen) +{ + if (fullscreen && !c->isfullscreen) { XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = True; + c->isfullscreen = 1; c->oldstate = c->isfloating; c->oldbw = c->bw; c->bw = 0; - c->isfloating = True; + c->isfloating = 1; resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); XRaiseWindow(dpy, c->win); - } - else { + } else if (!fullscreen && c->isfullscreen){ XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = False; + c->isfullscreen = 0; c->isfloating = c->oldstate; c->bw = c->oldbw; c->x = c->oldx; @@ -1755,27 +1515,14 @@ setfullscreen(Client *c, Bool fullscreen) { } void -setlayout(const Arg *arg) { - if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]){ - #ifdef CONFIG_DWM_PERTAG - selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - #else +setlayout(const Arg *arg) +{ + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) selmon->sellt ^= 1; - #endif - } - if(arg && arg->v) - #ifdef CONFIG_DWM_PERTAG - selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; - #else + if (arg && arg->v) selmon->lt[selmon->sellt] = (Layout *)arg->v; - #endif - - #ifdef CONFIG_DWM_PERTAG - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - #endif strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if(selmon->sel) + if (selmon->sel) arrange(selmon); else drawbar(selmon); @@ -1783,24 +1530,22 @@ setlayout(const Arg *arg) { /* arg > 1.0 will set mfact absolutly */ void -setmfact(const Arg *arg) { +setmfact(const Arg *arg) +{ float f; - if(!arg || !selmon->lt[selmon->sellt]->arrange) + 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.1 || f > 0.9) return; -#ifdef CONFIG_DWM_PERTAG - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; -#else selmon->mfact = f; -#endif arrange(selmon); } void -setup(void) { +setup(void) +{ XSetWindowAttributes wa; /* clean up any zombies immediately */ @@ -1808,13 +1553,14 @@ setup(void) { /* init screen */ screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - fnt = drw_font_create(dpy, font); sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); - bh = fnt->h + 2; + root = RootWindow(dpy, screen); drw = drw_create(dpy, screen, root, sw, sh); - drw_setfont(drw, fnt); + drw_load_fonts(drw, fonts, LENGTH(fonts)); + if (!drw->fontcount) + die("no fonts could be loaded.\n"); + bh = drw->fonts[0]->h + 2; updategeom(); /* init atoms */ wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); @@ -1825,46 +1571,21 @@ setup(void) { netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); -#ifdef CONFIG_DWM_OPACITY - netatom[NetWMWindowsOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False); -#endif netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); -#ifdef CONFIG_DWM_SYSTEMTRAY - netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); - netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); - netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); - xatom[Manager] = XInternAtom(dpy, "MANAGER", False); - xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); - xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); -#endif /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ -#ifdef CONFIG_DWM_PANGO - scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor, 0); - scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor, 0); - scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor, 0); - scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor, 0); - scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor, 0); - scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor, 0); -#else scheme[SchemeNorm].border = drw_clr_create(drw, normbordercolor); scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor); scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor); scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor); scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); - -#endif -#ifdef CONFIG_DWM_SYSTEMTRAY - /* init system tray */ - updatesystray(); -#endif /* init bars */ updatebars(); updatestatus(); @@ -1883,34 +1604,38 @@ setup(void) { } void -showhide(Client *c) { - if(!c) +showhide(Client *c) +{ + if (!c) return; - if(ISVISIBLE(c)) { /* show clients top down */ + if (ISVISIBLE(c)) { + /* show clients top down */ XMoveWindow(dpy, c->win, c->x, c->y); - if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, False); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); showhide(c->snext); - } - else { /* hide clients bottom up */ + } else { + /* hide clients bottom up */ showhide(c->snext); XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); } } void -sigchld(int unused) { - if(signal(SIGCHLD, sigchld) == SIG_ERR) - die("Can't install SIGCHLD handler"); - while(0 < waitpid(-1, NULL, WNOHANG)); +sigchld(int unused) +{ + if (signal(SIGCHLD, sigchld) == SIG_ERR) + die("can't install SIGCHLD handler:"); + while (0 < waitpid(-1, NULL, WNOHANG)); } void -spawn(const Arg *arg) { - if(arg->v == dmenucmd) +spawn(const Arg *arg) +{ + if (arg->v == dmenucmd) dmenumon[0] = '0' + selmon->num; - if(fork() == 0) { - if(dpy) + if (fork() == 0) { + if (dpy) close(ConnectionNumber(dpy)); setsid(); execvp(((char **)arg->v)[0], (char **)arg->v); @@ -1921,8 +1646,9 @@ spawn(const Arg *arg) { } void -tag(const Arg *arg) { - if(selmon->sel && arg->ui & TAGMASK) { +tag(const Arg *arg) +{ + if (selmon->sel && arg->ui & TAGMASK) { selmon->sel->tags = arg->ui & TAGMASK; focus(NULL); arrange(selmon); @@ -1930,86 +1656,71 @@ tag(const Arg *arg) { } void -tagmon(const Arg *arg) { - if(!selmon->sel || !mons->next) +tagmon(const Arg *arg) +{ + if (!selmon->sel || !mons->next) return; sendmon(selmon->sel, dirtomon(arg->i)); } void -tile(Monitor *m) { +tile(Monitor *m) +{ unsigned int i, n, h, mw, my, ty; Client *c; - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if(n == 0) + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) return; - if(n > m->nmaster) + if (n > m->nmaster) mw = m->nmaster ? m->ww * m->mfact : 0; else mw = m->ww; - for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if(i < m->nmaster) { + 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); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); my += HEIGHT(c); - } - else { + } else { h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); ty += HEIGHT(c); } } void -togglebar(const Arg *arg) { -#ifdef CONFIG_DWM_PERTAG - selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; -#else +togglebar(const Arg *arg) +{ selmon->showbar = !selmon->showbar; -#endif updatebarpos(selmon); -#ifdef CONFIG_DWM_SYSTEMTRAY - resizebarwin(selmon); - if(showsystray) { - XWindowChanges wc; - if(!selmon->showbar) - wc.y = -bh; - else if(selmon->showbar) { - wc.y = 0; - if(!selmon->topbar) - wc.y = selmon->mh - bh; - } - XConfigureWindow(dpy, systray->win, CWY, &wc); - } -#else XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -#endif arrange(selmon); } void -togglefloating(const Arg *arg) { - if(!selmon->sel) +togglefloating(const Arg *arg) +{ + if (!selmon->sel) return; - if(selmon->sel->isfullscreen) /* no support for fullscreen windows */ + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ return; selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if(selmon->sel->isfloating) + if (selmon->sel->isfloating) resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, False); + selmon->sel->w, selmon->sel->h, 0); arrange(selmon); } void -toggletag(const Arg *arg) { +toggletag(const Arg *arg) +{ unsigned int newtags; - if(!selmon->sel) + if (!selmon->sel) return; newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if(newtags) { + if (newtags) { selmon->sel->tags = newtags; focus(NULL); arrange(selmon); @@ -2017,65 +1728,40 @@ toggletag(const Arg *arg) { } void -toggleview(const Arg *arg) { +toggleview(const Arg *arg) +{ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); -#ifdef CONFIG_DWM_PERTAG - int i; -#endif - - if(newtagset) { - #ifdef CONFIG_DWM_PERTAG - if(newtagset == ~0) { - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = 0; - } - /* test if the user did not select the same tag */ - if(!(newtagset & 1 << (selmon->pertag->curtag - 1))) { - selmon->pertag->prevtag = selmon->pertag->curtag; - for (i=0; !(newtagset & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - #endif + if (newtagset) { selmon->tagset[selmon->seltags] = newtagset; - - #ifdef CONFIG_DWM_PERTAG - /* apply settings for this view */ - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) - togglebar(NULL); - #endif - focus(NULL); arrange(selmon); } } void -unfocus(Client *c, Bool setfocus) { - if(!c) +unfocus(Client *c, int setfocus) +{ + if (!c) return; - grabbuttons(c, False); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->rgb); - if(setfocus) { + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->pix); + if (setfocus) { XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); XDeleteProperty(dpy, root, netatom[NetActiveWindow]); } } void -unmanage(Client *c, Bool destroyed) { +unmanage(Client *c, int destroyed) +{ Monitor *m = c->mon; XWindowChanges wc; /* The server grab construct avoids race conditions. */ detach(c); detachstack(c); - if(!destroyed) { + if (!destroyed) { wc.border_width = c->oldbw; XGrabServer(dpy); XSetErrorHandler(xerrordummy); @@ -2093,119 +1779,101 @@ unmanage(Client *c, Bool destroyed) { } void -unmapnotify(XEvent *e) { +unmapnotify(XEvent *e) +{ Client *c; XUnmapEvent *ev = &e->xunmap; - if((c = wintoclient(ev->window))) { - if(ev->send_event) + if ((c = wintoclient(ev->window))) { + if (ev->send_event) setclientstate(c, WithdrawnState); else - unmanage(c, False); - } -#ifdef CONFIG_DWM_SYSTEMTRAY - else if((c = wintosystrayicon(ev->window))) { - removesystrayicon(c); - resizebarwin(selmon); - updatesystray(); + unmanage(c, 0); } -#endif } void -updatebars(void) { +updatebars(void) +{ Monitor *m; -#ifdef CONFIG_DWM_SYSTEMTRAY - unsigned int w; -#endif XSetWindowAttributes wa = { .override_redirect = True, .background_pixmap = ParentRelative, .event_mask = ButtonPressMask|ExposureMask }; - for(m = mons; m; m = m->next) { + for (m = mons; m; m = m->next) { if (m->barwin) continue; - #ifdef CONFIG_DWM_SYSTEMTRAY - w = m->ww; - if(showsystray && m == systraytomon(m)) - w -= getsystraywidth(); - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), - #else m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), - #endif CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - #ifdef CONFIG_DWM_SYSTEMTRAY - if(showsystray && m == systraytomon(m)) - XMapRaised(dpy, systray->win); - #endif XMapRaised(dpy, m->barwin); } } void -updatebarpos(Monitor *m) { +updatebarpos(Monitor *m) +{ m->wy = m->my; m->wh = m->mh; - if(m->showbar) { + if (m->showbar) { m->wh -= bh; m->by = m->topbar ? m->wy : m->wy + m->wh; m->wy = m->topbar ? m->wy + bh : m->wy; - } - else + } else m->by = -bh; } void -updateclientlist() { +updateclientlist() +{ Client *c; Monitor *m; XDeleteProperty(dpy, root, netatom[NetClientList]); - for(m = mons; m; m = m->next) - for(c = m->clients; c; c = c->next) + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *) &(c->win), 1); } -Bool -updategeom(void) { - Bool dirty = False; +int +updategeom(void) +{ + int dirty = 0; #ifdef XINERAMA - if(XineramaIsActive(dpy)) { + if (XineramaIsActive(dpy)) { int i, j, n, nn; Client *c; Monitor *m; XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); XineramaScreenInfo *unique = NULL; - for(n = 0, m = mons; m; m = m->next, n++); + for (n = 0, m = mons; m; m = m->next, n++); /* only consider unique geometries as separate screens */ - if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn))) - die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn); - for(i = 0, j = 0; i < nn; i++) - if(isuniquegeom(unique, j, &info[i])) + 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)); XFree(info); nn = j; - if(n <= nn) { - for(i = 0; i < (nn - n); i++) { /* new monitors available */ - for(m = mons; m && m->next; m = m->next); - if(m) + if (n <= nn) { + for (i = 0; i < (nn - n); i++) { /* new monitors available */ + 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 + 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 = True; + dirty = 1; m->num = i; m->mx = m->wx = unique[i].x_org; m->my = m->wy = unique[i].y_org; @@ -2213,12 +1881,12 @@ updategeom(void) { 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(m->clients) { - dirty = True; + } else { + /* less monitors available nn < n */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while (m->clients) { + dirty = 1; c = m->clients; m->clients = c->next; detachstack(c); @@ -2226,27 +1894,26 @@ updategeom(void) { attach(c); attachstack(c); } - if(m == selmon) + if (m == selmon) selmon = mons; cleanupmon(m); } } free(unique); - } - else + } else #endif /* XINERAMA */ /* default monitor setup */ { - if(!mons) + if (!mons) mons = createmon(); - if(mons->mw != sw || mons->mh != sh) { - dirty = True; + if (mons->mw != sw || mons->mh != sh) { + dirty = 1; mons->mw = mons->ww = sw; mons->mh = mons->wh = sh; updatebarpos(mons); } } - if(dirty) { + if (dirty) { selmon = mons; selmon = wintomon(root); } @@ -2254,179 +1921,151 @@ updategeom(void) { } void -updatenumlockmask(void) { +updatenumlockmask(void) +{ unsigned int i, j; XModifierKeymap *modmap; numlockmask = 0; modmap = XGetModifierMapping(dpy); - for(i = 0; i < 8; i++) - for(j = 0; j < modmap->max_keypermod; j++) - if(modmap->modifiermap[i * modmap->max_keypermod + j] + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) numlockmask = (1 << i); XFreeModifiermap(modmap); } void -updatesizehints(Client *c) { +updatesizehints(Client *c) +{ long msize; XSizeHints size; - if(!XGetWMNormalHints(dpy, c->win, &size, &msize)) + if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) /* size is uninitialized, ensure that size.flags aren't used */ size.flags = PSize; - if(size.flags & PBaseSize) { + if (size.flags & PBaseSize) { c->basew = size.base_width; c->baseh = size.base_height; - } - else if(size.flags & PMinSize) { + } else if (size.flags & PMinSize) { c->basew = size.min_width; c->baseh = size.min_height; - } - else + } else c->basew = c->baseh = 0; - if(size.flags & PResizeInc) { + if (size.flags & PResizeInc) { c->incw = size.width_inc; c->inch = size.height_inc; - } - else + } else c->incw = c->inch = 0; - if(size.flags & PMaxSize) { + if (size.flags & PMaxSize) { c->maxw = size.max_width; c->maxh = size.max_height; - } - else + } else c->maxw = c->maxh = 0; - if(size.flags & PMinSize) { + if (size.flags & PMinSize) { c->minw = size.min_width; c->minh = size.min_height; - } - else if(size.flags & PBaseSize) { + } else if (size.flags & PBaseSize) { c->minw = size.base_width; c->minh = size.base_height; - } - else + } else c->minw = c->minh = 0; - if(size.flags & PAspect) { + if (size.flags & PAspect) { c->mina = (float)size.min_aspect.y / size.min_aspect.x; c->maxa = (float)size.max_aspect.x / size.max_aspect.y; - } - else + } else c->maxa = c->mina = 0.0; c->isfixed = (c->maxw && c->minw && c->maxh && c->minh && c->maxw == c->minw && c->maxh == c->minh); } void -updatetitle(Client *c) { - if(!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) +updatetitle(Client *c) +{ + if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); - if(c->name[0] == '\0') /* hack to mark broken clients */ + if (c->name[0] == '\0') /* hack to mark broken clients */ strcpy(c->name, broken); } void -updatestatus(void) { - if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) +updatestatus(void) +{ + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) strcpy(stext, "dwm-"VERSION); drawbar(selmon); } void -updatewindowtype(Client *c) { +updatewindowtype(Client *c) +{ Atom state = getatomprop(c, netatom[NetWMState]); Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - if(state == netatom[NetWMFullscreen]) - setfullscreen(c, True); - if(wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = True; + if (state == netatom[NetWMFullscreen]) + setfullscreen(c, 1); + if (wtype == netatom[NetWMWindowTypeDialog]) + c->isfloating = 1; } void -updatewmhints(Client *c) { +updatewmhints(Client *c) +{ XWMHints *wmh; - if((wmh = XGetWMHints(dpy, c->win))) { - if(c == selmon->sel && wmh->flags & XUrgencyHint) { + if ((wmh = XGetWMHints(dpy, c->win))) { + if (c == selmon->sel && wmh->flags & XUrgencyHint) { wmh->flags &= ~XUrgencyHint; XSetWMHints(dpy, c->win, wmh); - } - else - c->isurgent = (wmh->flags & XUrgencyHint) ? True : False; - if(wmh->flags & InputHint) + } else + c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; + if (wmh->flags & InputHint) c->neverfocus = !wmh->input; else - c->neverfocus = False; + c->neverfocus = 0; XFree(wmh); } } void -view(const Arg *arg) { - -#ifdef CONFIG_DWM_PERTAG - int i; - unsigned int tmptag; -#endif - - if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) +view(const Arg *arg) +{ + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; selmon->seltags ^= 1; /* toggle sel tagset */ - if(arg->ui & TAGMASK) - #ifdef CONFIG_DWM_PERTAG - {selmon->pertag->prevtag = selmon->pertag->curtag; - #endif + if (arg->ui & TAGMASK) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - #ifdef CONFIG_DWM_PERTAG - if(arg->ui == ~0) - selmon->pertag->curtag = 0; - else { - for (i=0; !(arg->ui & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) - togglebar(NULL); - #endif focus(NULL); arrange(selmon); } Client * -wintoclient(Window w) { +wintoclient(Window w) +{ Client *c; Monitor *m; - for(m = mons; m; m = m->next) - for(c = m->clients; c; c = c->next) - if(c->win == w) + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + if (c->win == w) return c; return NULL; } Monitor * -wintomon(Window w) { +wintomon(Window w) +{ int x, y; Client *c; Monitor *m; - if(w == root && getrootptr(&x, &y)) + if (w == root && getrootptr(&x, &y)) return recttomon(x, y, 1, 1); - for(m = mons; m; m = m->next) - if(w == m->barwin) + for (m = mons; m; m = m->next) + if (w == m->barwin) return m; - if((c = wintoclient(w))) + if ((c = wintoclient(w))) return c->mon; return selmon; } @@ -2435,8 +2074,9 @@ wintomon(Window w) { * ignored (especially on UnmapNotify's). Other types of errors call Xlibs * default error handler, which may call exit. */ int -xerror(Display *dpy, XErrorEvent *ee) { - if(ee->error_code == BadWindow +xerror(Display *dpy, XErrorEvent *ee) +{ + if (ee->error_code == BadWindow || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) @@ -2452,40 +2092,44 @@ xerror(Display *dpy, XErrorEvent *ee) { } int -xerrordummy(Display *dpy, XErrorEvent *ee) { +xerrordummy(Display *dpy, XErrorEvent *ee) +{ return 0; } /* Startup Error handler to check if another window manager * is already running. */ int -xerrorstart(Display *dpy, XErrorEvent *ee) { +xerrorstart(Display *dpy, XErrorEvent *ee) +{ die("dwm: another window manager is already running\n"); return -1; } void -zoom(const Arg *arg) { +zoom(const Arg *arg) +{ Client *c = selmon->sel; - if(!selmon->lt[selmon->sellt]->arrange + if (!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)) return; - if(c == nexttiled(selmon->clients)) - if(!c || !(c = nexttiled(c->next))) + if (c == nexttiled(selmon->clients)) + if (!c || !(c = nexttiled(c->next))) return; pop(c); } int -main(int argc, char *argv[]) { - if(argc == 2 && !strcmp("-v", argv[1])) - die("dwm-"VERSION", © 2006-2014 dwm engineers, see LICENSE for details\n"); - else if(argc != 1) +main(int argc, char *argv[]) +{ + if (argc == 2 && !strcmp("-v", argv[1])) + die("dwm-"VERSION "\n"); + else if (argc != 1) die("usage: dwm [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); - if(!(dpy = XOpenDisplay(NULL))) + if (!(dpy = XOpenDisplay(NULL))) die("dwm: cannot open display\n"); checkotherwm(); setup(); @@ -2495,197 +2139,3 @@ main(int argc, char *argv[]) { XCloseDisplay(dpy); return EXIT_SUCCESS; } - -#ifdef CONFIG_DWM_OPACITY -void -opacity(Client *c, double opacity) -{ - if(opacity >= 0 && opacity <= 1) { - unsigned long real_opacity[] = { opacity * 0xffffffff }; - XChangeProperty(dpy, c->win, netatom[NetWMWindowsOpacity], XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)real_opacity, - 1); - } else - XDeleteProperty(dpy, c->win, netatom[NetWMWindowsOpacity]); -} -#endif - -#ifdef CONFIG_DWM_SYSTEMTRAY -unsigned int -getsystraywidth() { - unsigned int w = 0; - Client *i; - if(showsystray) - for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; - return w ? w + systrayspacing : 1; -} - - void -removesystrayicon(Client *i) { - Client **ii; - - if(!showsystray || !i) - return; - for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); - if(ii) - *ii = i->next; - free(i); -} - - void -resizebarwin(Monitor *m) { - unsigned int w = m->ww; - if(showsystray && m == systraytomon(m)) - w -= getsystraywidth(); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -} - - void -resizerequest(XEvent *e) { - XResizeRequestEvent *ev = &e->xresizerequest; - Client *i; - - if((i = wintosystrayicon(ev->window))) { - updatesystrayicongeom(i, ev->width, ev->height); - resizebarwin(selmon); - updatesystray(); - } -} - -Monitor * -systraytomon(Monitor *m) { - Monitor *t; - int i, n; - if(!systraypinning) { - if(!m) - return selmon; - return m == selmon ? m : NULL; - } - for(n = 1, t = mons; t && t->next; n++, t = t->next) ; - for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; - if(systraypinningfailfirst && n < systraypinning) - return mons; - return t; -} - - void -updatesystrayicongeom(Client *i, int w, int h) { - if(i) { - i->h = bh; - if(w == h) - i->w = bh; - else if(h == bh) - i->w = w; - 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 */ - if(i->h > bh) { - if(i->w == i->h) - i->w = bh; - else - i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); - i->h = bh; - } - } -} - -void -updatesystrayiconstate(Client *i, XPropertyEvent *ev) { - long flags; - int code = 0; - - if(!showsystray || !i || ev->atom != xatom[XembedInfo] || - !(flags = getatomprop(i, xatom[XembedInfo]))) - return; - - if(flags & XEMBED_MAPPED && !i->tags) { - i->tags = 1; - code = XEMBED_WINDOW_ACTIVATE; - XMapRaised(dpy, i->win); - setclientstate(i, NormalState); - } - else if(!(flags & XEMBED_MAPPED) && i->tags) { - i->tags = 0; - code = XEMBED_WINDOW_DEACTIVATE; - XUnmapWindow(dpy, i->win); - setclientstate(i, WithdrawnState); - } - else - return; - sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, - systray->win, XEMBED_EMBEDDED_VERSION); -} - -void -updatesystray(void) { - XSetWindowAttributes wa; - XWindowChanges wc; - Client *i; - Monitor *m = systraytomon(NULL); - unsigned int x = m->mx + m->mw; - unsigned int w = 1; - - if(!showsystray) - return; - if(!systray) { - /* init systray */ - if(!(systray = (Systray *)calloc(1, sizeof(Systray)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); - systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel].bg->rgb); - wa.event_mask = ButtonPressMask | ExposureMask; - wa.override_redirect = True; - wa.background_pixel = scheme[SchemeNorm].bg->rgb; - XSelectInput(dpy, systray->win, SubstructureNotifyMask); - XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&systrayorientation, 1); - XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); - XMapRaised(dpy, systray->win); - XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); - if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { - sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); - XSync(dpy, False); - } - else { - fprintf(stderr, "dwm: unable to obtain system tray.\n"); - free(systray); - systray = NULL; - return; - } - } - for(w = 0, i = systray->icons; i; i = i->next) { - /* make sure the background color stays the same */ - wa.background_pixel = scheme[SchemeNorm].bg->rgb; - XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); - XMapRaised(dpy, i->win); - w += systrayspacing; - i->x = w; - XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); - w += i->w; - if(i->mon != m) - i->mon = m; - } - w = w ? w + systrayspacing : 1; - x -= w; - XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); - wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; - wc.stack_mode = Above; wc.sibling = m->barwin; - XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); - XMapWindow(dpy, systray->win); - XMapSubwindows(dpy, systray->win); - /* redraw background */ - XSetForeground(dpy, drw->gc, scheme[SchemeNorm].bg->rgb); - XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); - XSync(dpy, False); -} - -Client * -wintosystrayicon(Window w) { - Client *i = NULL; - - if(!showsystray || !w) - return i; - for(i = systray->icons; i && i->win != w; i = i->next) ; - return i; -} -#endif @@ -2,16 +2,32 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "util.h" +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + perror(NULL); + return p; +} + void -die(const char *errstr, ...) { +die(const char *fmt, ...) { va_list ap; - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); va_end(ap); - exit(EXIT_FAILURE); -} + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } + + exit(1); +} @@ -1,11 +1,8 @@ /* See LICENSE file for copyright and license details. */ -#ifndef MAX #define MAX(A, B) ((A) > (B) ? (A) : (B)) -#endif - -#ifndef MIN #define MIN(A, B) ((A) < (B) ? (A) : (B)) -#endif +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) void die(const char *errstr, ...); +void *ecalloc(size_t, size_t); |