|  |  | @ -54,7 +54,7 @@ | 
			
		
	
		
			
				
					|  |  |  | #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)                (textnw(X, strlen(X)) + dc.font.height) | 
			
		
	
		
			
				
					|  |  |  | #define TEXTW(X)                (drw_font_getexts_width(drw->font, X, strlen(X)) + drw->font->h) | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | /* enums */ | 
			
		
	
		
			
				
					|  |  |  | enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */ | 
			
		
	
	
		
			
				
					|  |  | @ -98,21 +98,6 @@ struct Client { | 
			
		
	
		
			
				
					|  |  |  | Window win; | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | typedef struct { | 
			
		
	
		
			
				
					|  |  |  | int x, y, w, h; | 
			
		
	
		
			
				
					|  |  |  | unsigned long norm[ColLast]; | 
			
		
	
		
			
				
					|  |  |  | unsigned long sel[ColLast]; | 
			
		
	
		
			
				
					|  |  |  | Drawable drawable; | 
			
		
	
		
			
				
					|  |  |  | GC gc; | 
			
		
	
		
			
				
					|  |  |  | struct { | 
			
		
	
		
			
				
					|  |  |  | int ascent; | 
			
		
	
		
			
				
					|  |  |  | int descent; | 
			
		
	
		
			
				
					|  |  |  | int height; | 
			
		
	
		
			
				
					|  |  |  | XFontSet set; | 
			
		
	
		
			
				
					|  |  |  | XFontStruct *xfont; | 
			
		
	
		
			
				
					|  |  |  | } font; | 
			
		
	
		
			
				
					|  |  |  | } DC; /* draw context */ | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | typedef struct { | 
			
		
	
		
			
				
					|  |  |  | unsigned int mod; | 
			
		
	
		
			
				
					|  |  |  | KeySym keysym; | 
			
		
	
	
		
			
				
					|  |  | @ -178,22 +163,18 @@ static void detachstack(Client *c); | 
			
		
	
		
			
				
					|  |  |  | static Monitor *dirtomon(int dir); | 
			
		
	
		
			
				
					|  |  |  | static void drawbar(Monitor *m); | 
			
		
	
		
			
				
					|  |  |  | static void drawbars(void); | 
			
		
	
		
			
				
					|  |  |  | static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); | 
			
		
	
		
			
				
					|  |  |  | static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); | 
			
		
	
		
			
				
					|  |  |  | static void enternotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void expose(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void focus(Client *c); | 
			
		
	
		
			
				
					|  |  |  | static void focusin(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void focusmon(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void focusstack(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static unsigned long getcolor(const char *colstr); | 
			
		
	
		
			
				
					|  |  |  | static Bool 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 void grabkeys(void); | 
			
		
	
		
			
				
					|  |  |  | static void incnmaster(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void initfont(const char *fontstr); | 
			
		
	
		
			
				
					|  |  |  | static void keypress(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void killclient(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void manage(Window w, XWindowAttributes *wa); | 
			
		
	
	
		
			
				
					|  |  | @ -226,7 +207,6 @@ static void sigchld(int unused); | 
			
		
	
		
			
				
					|  |  |  | static void spawn(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void tag(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void tagmon(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static int textnw(const char *text, unsigned int len); | 
			
		
	
		
			
				
					|  |  |  | static void tile(Monitor *); | 
			
		
	
		
			
				
					|  |  |  | static void togglebar(const Arg *arg); | 
			
		
	
		
			
				
					|  |  |  | static void togglefloating(const Arg *arg); | 
			
		
	
	
		
			
				
					|  |  | @ -279,10 +259,13 @@ static void (*handler[LASTEvent]) (XEvent *) = { | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | static Atom wmatom[WMLast], netatom[NetLast]; | 
			
		
	
		
			
				
					|  |  |  | static Bool running = True; | 
			
		
	
		
			
				
					|  |  |  | static Cursor cursor[CurLast]; | 
			
		
	
		
			
				
					|  |  |  | static Cur *cursor[CurLast]; | 
			
		
	
		
			
				
					|  |  |  | static Theme thmnorm[ColLast]; | 
			
		
	
		
			
				
					|  |  |  | static Theme thmsel[ColLast]; | 
			
		
	
		
			
				
					|  |  |  | static Display *dpy; | 
			
		
	
		
			
				
					|  |  |  | static DC dc; | 
			
		
	
		
			
				
					|  |  |  | static Monitor *mons = NULL, *selmon = NULL; | 
			
		
	
		
			
				
					|  |  |  | static Drw *drw; | 
			
		
	
		
			
				
					|  |  |  | static Fnt *fnt; | 
			
		
	
		
			
				
					|  |  |  | static Monitor *mons, *selmon; | 
			
		
	
		
			
				
					|  |  |  | static Window root; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | /* configuration, allows nested code to access above variables */ | 
			
		
	
	
		
			
				
					|  |  | @ -486,18 +469,20 @@ cleanup(void) { | 
			
		
	
		
			
				
					|  |  |  | for(m = mons; m; m = m->next) | 
			
		
	
		
			
				
					|  |  |  | while(m->stack) | 
			
		
	
		
			
				
					|  |  |  | unmanage(m->stack, False); | 
			
		
	
		
			
				
					|  |  |  | if(dc.font.set) | 
			
		
	
		
			
				
					|  |  |  | XFreeFontSet(dpy, dc.font.set); | 
			
		
	
		
			
				
					|  |  |  | else | 
			
		
	
		
			
				
					|  |  |  | XFreeFont(dpy, dc.font.xfont); | 
			
		
	
		
			
				
					|  |  |  | XUngrabKey(dpy, AnyKey, AnyModifier, root); | 
			
		
	
		
			
				
					|  |  |  | XFreePixmap(dpy, dc.drawable); | 
			
		
	
		
			
				
					|  |  |  | XFreeGC(dpy, dc.gc); | 
			
		
	
		
			
				
					|  |  |  | XFreeCursor(dpy, cursor[CurNormal]); | 
			
		
	
		
			
				
					|  |  |  | XFreeCursor(dpy, cursor[CurResize]); | 
			
		
	
		
			
				
					|  |  |  | XFreeCursor(dpy, cursor[CurMove]); | 
			
		
	
		
			
				
					|  |  |  | while(mons) | 
			
		
	
		
			
				
					|  |  |  | cleanupmon(mons); | 
			
		
	
		
			
				
					|  |  |  | 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(thmnorm->border); | 
			
		
	
		
			
				
					|  |  |  | drw_clr_free(thmnorm->bg); | 
			
		
	
		
			
				
					|  |  |  | drw_clr_free(thmnorm->fg); | 
			
		
	
		
			
				
					|  |  |  | drw_clr_free(thmsel->border); | 
			
		
	
		
			
				
					|  |  |  | drw_clr_free(thmsel->bg); | 
			
		
	
		
			
				
					|  |  |  | drw_clr_free(thmsel->fg); | 
			
		
	
		
			
				
					|  |  |  | drw_free(drw); | 
			
		
	
		
			
				
					|  |  |  | XSync(dpy, False); | 
			
		
	
		
			
				
					|  |  |  | XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); | 
			
		
	
	
		
			
				
					|  |  | @ -581,9 +566,7 @@ configurenotify(XEvent *e) { | 
			
		
	
		
			
				
					|  |  |  | sw = ev->width; | 
			
		
	
		
			
				
					|  |  |  | sh = ev->height; | 
			
		
	
		
			
				
					|  |  |  | if(updategeom() || dirty) { | 
			
		
	
		
			
				
					|  |  |  | if(dc.drawable != 0) | 
			
		
	
		
			
				
					|  |  |  | XFreePixmap(dpy, dc.drawable); | 
			
		
	
		
			
				
					|  |  |  | dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); | 
			
		
	
		
			
				
					|  |  |  | drw_resize(drw, sw, bh); | 
			
		
	
		
			
				
					|  |  |  | updatebars(); | 
			
		
	
		
			
				
					|  |  |  | for(m = mons; m; m = m->next) | 
			
		
	
		
			
				
					|  |  |  | XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); | 
			
		
	
	
		
			
				
					|  |  | @ -710,9 +693,8 @@ dirtomon(int dir) { | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | drawbar(Monitor *m) { | 
			
		
	
		
			
				
					|  |  |  | int x; | 
			
		
	
		
			
				
					|  |  |  | int x, xx, w; | 
			
		
	
		
			
				
					|  |  |  | unsigned int i, occ = 0, urg = 0; | 
			
		
	
		
			
				
					|  |  |  | unsigned long *col; | 
			
		
	
		
			
				
					|  |  |  | Client *c; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | for(c = m->clients; c; c = c->next) { | 
			
		
	
	
		
			
				
					|  |  | @ -720,42 +702,44 @@ drawbar(Monitor *m) { | 
			
		
	
		
			
				
					|  |  |  | if(c->isurgent) | 
			
		
	
		
			
				
					|  |  |  | urg |= c->tags; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | dc.x = 0; | 
			
		
	
		
			
				
					|  |  |  | x = 0; | 
			
		
	
		
			
				
					|  |  |  | for(i = 0; i < LENGTH(tags); i++) { | 
			
		
	
		
			
				
					|  |  |  | dc.w = TEXTW(tags[i]); | 
			
		
	
		
			
				
					|  |  |  | col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; | 
			
		
	
		
			
				
					|  |  |  | drawtext(tags[i], col, urg & 1 << i); | 
			
		
	
		
			
				
					|  |  |  | drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, | 
			
		
	
		
			
				
					|  |  |  | occ & 1 << i, urg & 1 << i, col); | 
			
		
	
		
			
				
					|  |  |  | dc.x += dc.w; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | dc.w = blw = TEXTW(m->ltsymbol); | 
			
		
	
		
			
				
					|  |  |  | drawtext(m->ltsymbol, dc.norm, False); | 
			
		
	
		
			
				
					|  |  |  | dc.x += dc.w; | 
			
		
	
		
			
				
					|  |  |  | x = dc.x; | 
			
		
	
		
			
				
					|  |  |  | w = TEXTW(tags[i]); | 
			
		
	
		
			
				
					|  |  |  | drw_settheme(drw, m->tagset[m->seltags] & 1 << i ? thmsel : thmnorm); | 
			
		
	
		
			
				
					|  |  |  | 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, | 
			
		
	
		
			
				
					|  |  |  | occ & 1 << i, urg & 1 << i); | 
			
		
	
		
			
				
					|  |  |  | x += w; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | w = blw = TEXTW(m->ltsymbol); | 
			
		
	
		
			
				
					|  |  |  | drw_settheme(drw, thmnorm); | 
			
		
	
		
			
				
					|  |  |  | drw_text(drw, x, 0, w, bh, m->ltsymbol, 0); | 
			
		
	
		
			
				
					|  |  |  | x += w; | 
			
		
	
		
			
				
					|  |  |  | xx = x; | 
			
		
	
		
			
				
					|  |  |  | if(m == selmon) { /* status is only drawn on selected monitor */ | 
			
		
	
		
			
				
					|  |  |  | dc.w = TEXTW(stext); | 
			
		
	
		
			
				
					|  |  |  | dc.x = m->ww - dc.w; | 
			
		
	
		
			
				
					|  |  |  | if(dc.x < x) { | 
			
		
	
		
			
				
					|  |  |  | dc.x = x; | 
			
		
	
		
			
				
					|  |  |  | dc.w = m->ww - x; | 
			
		
	
		
			
				
					|  |  |  | w = TEXTW(stext); | 
			
		
	
		
			
				
					|  |  |  | x = m->ww - w; | 
			
		
	
		
			
				
					|  |  |  | if(x < xx) { | 
			
		
	
		
			
				
					|  |  |  | x = xx; | 
			
		
	
		
			
				
					|  |  |  | w = m->ww - xx; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | drawtext(stext, dc.norm, False); | 
			
		
	
		
			
				
					|  |  |  | drw_text(drw, x, 0, w, bh, stext, 0); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | else | 
			
		
	
		
			
				
					|  |  |  | dc.x = m->ww; | 
			
		
	
		
			
				
					|  |  |  | if((dc.w = dc.x - x) > bh) { | 
			
		
	
		
			
				
					|  |  |  | dc.x = x; | 
			
		
	
		
			
				
					|  |  |  | x = m->ww; | 
			
		
	
		
			
				
					|  |  |  | if((w = x - xx) > bh) { | 
			
		
	
		
			
				
					|  |  |  | x = xx; | 
			
		
	
		
			
				
					|  |  |  | if(m->sel) { | 
			
		
	
		
			
				
					|  |  |  | col = m == selmon ? dc.sel : dc.norm; | 
			
		
	
		
			
				
					|  |  |  | drawtext(m->sel->name, col, False); | 
			
		
	
		
			
				
					|  |  |  | drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); | 
			
		
	
		
			
				
					|  |  |  | drw_settheme(drw, m == selmon ? thmsel : thmnorm); | 
			
		
	
		
			
				
					|  |  |  | 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_settheme(drw, thmnorm); | 
			
		
	
		
			
				
					|  |  |  | drw_text(drw, x, 0, w, bh, NULL, 0); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | else | 
			
		
	
		
			
				
					|  |  |  | drawtext(NULL, dc.norm, False); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); | 
			
		
	
		
			
				
					|  |  |  | XSync(dpy, False); | 
			
		
	
		
			
				
					|  |  |  | drw_map(drw, m->barwin, 0, 0, m->ww, bh); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
	
		
			
				
					|  |  | @ -766,45 +750,6 @@ drawbars(void) { | 
			
		
	
		
			
				
					|  |  |  | drawbar(m); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { | 
			
		
	
		
			
				
					|  |  |  | int x; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); | 
			
		
	
		
			
				
					|  |  |  | x = (dc.font.ascent + dc.font.descent + 2) / 4; | 
			
		
	
		
			
				
					|  |  |  | if(filled) | 
			
		
	
		
			
				
					|  |  |  | XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1); | 
			
		
	
		
			
				
					|  |  |  | else if(empty) | 
			
		
	
		
			
				
					|  |  |  | XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | drawtext(const char *text, unsigned long col[ColLast], Bool invert) { | 
			
		
	
		
			
				
					|  |  |  | char buf[256]; | 
			
		
	
		
			
				
					|  |  |  | int i, x, y, h, len, olen; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); | 
			
		
	
		
			
				
					|  |  |  | XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); | 
			
		
	
		
			
				
					|  |  |  | if(!text) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | olen = strlen(text); | 
			
		
	
		
			
				
					|  |  |  | h = dc.font.ascent + dc.font.descent; | 
			
		
	
		
			
				
					|  |  |  | y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; | 
			
		
	
		
			
				
					|  |  |  | x = dc.x + (h / 2); | 
			
		
	
		
			
				
					|  |  |  | /* shorten text if necessary */ | 
			
		
	
		
			
				
					|  |  |  | for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); | 
			
		
	
		
			
				
					|  |  |  | if(!len) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | memcpy(buf, text, len); | 
			
		
	
		
			
				
					|  |  |  | if(len < olen) | 
			
		
	
		
			
				
					|  |  |  | for(i = len; i && i > len - 3; buf[--i] = '.'); | 
			
		
	
		
			
				
					|  |  |  | XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); | 
			
		
	
		
			
				
					|  |  |  | if(dc.font.set) | 
			
		
	
		
			
				
					|  |  |  | XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); | 
			
		
	
		
			
				
					|  |  |  | else | 
			
		
	
		
			
				
					|  |  |  | XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | enternotify(XEvent *e) { | 
			
		
	
		
			
				
					|  |  |  | Client *c; | 
			
		
	
	
		
			
				
					|  |  | @ -848,7 +793,7 @@ focus(Client *c) { | 
			
		
	
		
			
				
					|  |  |  | detachstack(c); | 
			
		
	
		
			
				
					|  |  |  | attachstack(c); | 
			
		
	
		
			
				
					|  |  |  | grabbuttons(c, True); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, c->win, thmsel->border->rgb); | 
			
		
	
		
			
				
					|  |  |  | setfocus(c); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | else { | 
			
		
	
	
		
			
				
					|  |  | @ -922,16 +867,6 @@ getatomprop(Client *c, Atom prop) { | 
			
		
	
		
			
				
					|  |  |  | return atom; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | unsigned long | 
			
		
	
		
			
				
					|  |  |  | getcolor(const char *colstr) { | 
			
		
	
		
			
				
					|  |  |  | Colormap cmap = DefaultColormap(dpy, screen); | 
			
		
	
		
			
				
					|  |  |  | XColor color; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) | 
			
		
	
		
			
				
					|  |  |  | die("error, cannot allocate color '%s'\n", colstr); | 
			
		
	
		
			
				
					|  |  |  | return color.pixel; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | Bool | 
			
		
	
		
			
				
					|  |  |  | getrootptr(int *x, int *y) { | 
			
		
	
		
			
				
					|  |  |  | int di; | 
			
		
	
	
		
			
				
					|  |  | @ -1028,40 +963,6 @@ incnmaster(const Arg *arg) { | 
			
		
	
		
			
				
					|  |  |  | arrange(selmon); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | initfont(const char *fontstr) { | 
			
		
	
		
			
				
					|  |  |  | char *def, **missing; | 
			
		
	
		
			
				
					|  |  |  | int n; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); | 
			
		
	
		
			
				
					|  |  |  | if(missing) { | 
			
		
	
		
			
				
					|  |  |  | while(n--) | 
			
		
	
		
			
				
					|  |  |  | fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]); | 
			
		
	
		
			
				
					|  |  |  | XFreeStringList(missing); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | if(dc.font.set) { | 
			
		
	
		
			
				
					|  |  |  | XFontStruct **xfonts; | 
			
		
	
		
			
				
					|  |  |  | char **font_names; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | dc.font.ascent = dc.font.descent = 0; | 
			
		
	
		
			
				
					|  |  |  | XExtentsOfFontSet(dc.font.set); | 
			
		
	
		
			
				
					|  |  |  | n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); | 
			
		
	
		
			
				
					|  |  |  | while(n--) { | 
			
		
	
		
			
				
					|  |  |  | dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); | 
			
		
	
		
			
				
					|  |  |  | dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent); | 
			
		
	
		
			
				
					|  |  |  | xfonts++; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | else { | 
			
		
	
		
			
				
					|  |  |  | if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) | 
			
		
	
		
			
				
					|  |  |  | && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) | 
			
		
	
		
			
				
					|  |  |  | die("error, cannot load font: '%s'\n", fontstr); | 
			
		
	
		
			
				
					|  |  |  | dc.font.ascent = dc.font.xfont->ascent; | 
			
		
	
		
			
				
					|  |  |  | dc.font.descent = dc.font.xfont->descent; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | dc.font.height = dc.font.ascent + dc.font.descent; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | #ifdef XINERAMA | 
			
		
	
		
			
				
					|  |  |  | static Bool | 
			
		
	
		
			
				
					|  |  |  | isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { | 
			
		
	
	
		
			
				
					|  |  | @ -1140,7 +1041,7 @@ manage(Window w, XWindowAttributes *wa) { | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | wc.border_width = c->bw; | 
			
		
	
		
			
				
					|  |  |  | XConfigureWindow(dpy, w, CWBorderWidth, &wc); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, w, dc.norm[ColBorder]); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, w, thmnorm->border->rgb); | 
			
		
	
		
			
				
					|  |  |  | configure(c); /* propagates border_width, if size doesn't change */ | 
			
		
	
		
			
				
					|  |  |  | updatewindowtype(c); | 
			
		
	
		
			
				
					|  |  |  | updatesizehints(c); | 
			
		
	
	
		
			
				
					|  |  | @ -1232,7 +1133,7 @@ movemouse(const Arg *arg) { | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurMove], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | if(!getrootptr(&x, &y)) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
	
		
			
				
					|  |  | @ -1378,7 +1279,7 @@ resizemouse(const Arg *arg) { | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurResize], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | 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); | 
			
		
	
		
			
				
					|  |  |  | do { | 
			
		
	
	
		
			
				
					|  |  | @ -1597,10 +1498,12 @@ setup(void) { | 
			
		
	
		
			
				
					|  |  |  | /* init screen */ | 
			
		
	
		
			
				
					|  |  |  | screen = DefaultScreen(dpy); | 
			
		
	
		
			
				
					|  |  |  | root = RootWindow(dpy, screen); | 
			
		
	
		
			
				
					|  |  |  | initfont(font); | 
			
		
	
		
			
				
					|  |  |  | fnt = drw_font_create(dpy, font); | 
			
		
	
		
			
				
					|  |  |  | sw = DisplayWidth(dpy, screen); | 
			
		
	
		
			
				
					|  |  |  | sh = DisplayHeight(dpy, screen); | 
			
		
	
		
			
				
					|  |  |  | bh = dc.h = dc.font.height + 2; | 
			
		
	
		
			
				
					|  |  |  | bh = fnt->h + 2; | 
			
		
	
		
			
				
					|  |  |  | drw = drw_create(dpy, screen, root, sw, sh); | 
			
		
	
		
			
				
					|  |  |  | drw_setfont(drw, fnt); | 
			
		
	
		
			
				
					|  |  |  | updategeom(); | 
			
		
	
		
			
				
					|  |  |  | /* init atoms */ | 
			
		
	
		
			
				
					|  |  |  | wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | 
			
		
	
	
		
			
				
					|  |  | @ -1616,21 +1519,16 @@ setup(void) { | 
			
		
	
		
			
				
					|  |  |  | netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); | 
			
		
	
		
			
				
					|  |  |  | netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); | 
			
		
	
		
			
				
					|  |  |  | /* init cursors */ | 
			
		
	
		
			
				
					|  |  |  | cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); | 
			
		
	
		
			
				
					|  |  |  | cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); | 
			
		
	
		
			
				
					|  |  |  | cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); | 
			
		
	
		
			
				
					|  |  |  | 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 */ | 
			
		
	
		
			
				
					|  |  |  | dc.norm[ColBorder] = getcolor(normbordercolor); | 
			
		
	
		
			
				
					|  |  |  | dc.norm[ColBG] = getcolor(normbgcolor); | 
			
		
	
		
			
				
					|  |  |  | dc.norm[ColFG] = getcolor(normfgcolor); | 
			
		
	
		
			
				
					|  |  |  | dc.sel[ColBorder] = getcolor(selbordercolor); | 
			
		
	
		
			
				
					|  |  |  | dc.sel[ColBG] = getcolor(selbgcolor); | 
			
		
	
		
			
				
					|  |  |  | dc.sel[ColFG] = getcolor(selfgcolor); | 
			
		
	
		
			
				
					|  |  |  | dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); | 
			
		
	
		
			
				
					|  |  |  | dc.gc = XCreateGC(dpy, root, 0, NULL); | 
			
		
	
		
			
				
					|  |  |  | XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); | 
			
		
	
		
			
				
					|  |  |  | if(!dc.font.set) | 
			
		
	
		
			
				
					|  |  |  | XSetFont(dpy, dc.gc, dc.font.xfont->fid); | 
			
		
	
		
			
				
					|  |  |  | thmnorm->border = drw_clr_create(drw, normbordercolor); | 
			
		
	
		
			
				
					|  |  |  | thmnorm->bg = drw_clr_create(drw, normbgcolor); | 
			
		
	
		
			
				
					|  |  |  | thmnorm->fg = drw_clr_create(drw, normfgcolor); | 
			
		
	
		
			
				
					|  |  |  | thmsel->border = drw_clr_create(drw, selbordercolor); | 
			
		
	
		
			
				
					|  |  |  | thmsel->bg = drw_clr_create(drw, selbgcolor); | 
			
		
	
		
			
				
					|  |  |  | thmsel->fg = drw_clr_create(drw, selfgcolor); | 
			
		
	
		
			
				
					|  |  |  | /* init bars */ | 
			
		
	
		
			
				
					|  |  |  | updatebars(); | 
			
		
	
		
			
				
					|  |  |  | updatestatus(); | 
			
		
	
	
		
			
				
					|  |  | @ -1639,7 +1537,7 @@ setup(void) { | 
			
		
	
		
			
				
					|  |  |  | PropModeReplace, (unsigned char *) netatom, NetLast); | 
			
		
	
		
			
				
					|  |  |  | XDeleteProperty(dpy, root, netatom[NetClientList]); | 
			
		
	
		
			
				
					|  |  |  | /* select for events */ | 
			
		
	
		
			
				
					|  |  |  | wa.cursor = cursor[CurNormal]; | 
			
		
	
		
			
				
					|  |  |  | wa.cursor = cursor[CurNormal]->cursor; | 
			
		
	
		
			
				
					|  |  |  | wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask | 
			
		
	
		
			
				
					|  |  |  | |EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; | 
			
		
	
		
			
				
					|  |  |  | XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); | 
			
		
	
	
		
			
				
					|  |  | @ -1699,17 +1597,6 @@ tagmon(const Arg *arg) { | 
			
		
	
		
			
				
					|  |  |  | sendmon(selmon->sel, dirtomon(arg->i)); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | int | 
			
		
	
		
			
				
					|  |  |  | textnw(const char *text, unsigned int len) { | 
			
		
	
		
			
				
					|  |  |  | XRectangle r; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if(dc.font.set) { | 
			
		
	
		
			
				
					|  |  |  | XmbTextExtents(dc.font.set, text, len, NULL, &r); | 
			
		
	
		
			
				
					|  |  |  | return r.width; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | return XTextWidth(dc.font.xfont, text, len); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | tile(Monitor *m) { | 
			
		
	
		
			
				
					|  |  |  | unsigned int i, n, h, mw, my, ty; | 
			
		
	
	
		
			
				
					|  |  | @ -1787,7 +1674,7 @@ unfocus(Client *c, Bool setfocus) { | 
			
		
	
		
			
				
					|  |  |  | if(!c) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | grabbuttons(c, False); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); | 
			
		
	
		
			
				
					|  |  |  | XSetWindowBorder(dpy, c->win, thmnorm->border->rgb); | 
			
		
	
		
			
				
					|  |  |  | if(setfocus) { | 
			
		
	
		
			
				
					|  |  |  | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); | 
			
		
	
	
		
			
				
					|  |  | @ -1846,7 +1733,7 @@ updatebars(void) { | 
			
		
	
		
			
				
					|  |  |  | m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), | 
			
		
	
		
			
				
					|  |  |  | CopyFromParent, DefaultVisual(dpy, screen), | 
			
		
	
		
			
				
					|  |  |  | CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); | 
			
		
	
		
			
				
					|  |  |  | XDefineCursor(dpy, m->barwin, cursor[CurNormal]); | 
			
		
	
		
			
				
					|  |  |  | XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); | 
			
		
	
		
			
				
					|  |  |  | XMapRaised(dpy, m->barwin); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
	
		
			
				
					|  |  | 
 |