X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=main.c;h=8ecf9fac8ee2b8bc34348b46f5d69aff07d89638;hb=cdbc84b9a87c427b3d0a202475b0f5aae315fb90;hp=02475e0f102f4880622b2076ac4a17368132e8ab;hpb=fd995dac78e34cc427abd7198af0db957a40664a;p=dwm.git diff --git a/main.c b/main.c index 02475e0..8ecf9fa 100644 --- a/main.c +++ b/main.c @@ -18,8 +18,8 @@ /* extern */ char stext[256]; -int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah; -unsigned int master, nmaster, ntags, numlockmask; +int screen, sx, sy, sw, sh, wax, way, waw, wah; +unsigned int bh, ntags, numlockmask; Atom wmatom[WMLast], netatom[NetLast]; Bool running = True; Bool *seltag; @@ -41,7 +41,8 @@ static void cleanup(void) { close(STDIN_FILENO); while(stack) { - resize(stack, True); + if(stack->isbanned) + XMoveWindow(dpy, stack->win, stack->x, stack->y); unmanage(stack); } if(dc.font.set) @@ -60,6 +61,94 @@ cleanup(void) { free(seltag); } +static unsigned 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); +} + +static void +drawtext(const char *text, unsigned long col[ColLast], Bool filledsquare, Bool emptysquare) { + int x, y, w, h; + static char buf[256]; + unsigned int len, olen; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + 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 */ + while(len && (w = textnw(buf, len)) > dc.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + if(w > dc.w) + return; /* too long */ + gcv.foreground = col[ColFG]; + if(dc.font.set) { + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + } + else { + gcv.font = dc.font.xfont->fid; + XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv); + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); + } + x = (h + 2) / 4; + r.x = dc.x + 1; + r.y = dc.y + 1; + if(filledsquare) { + r.width = r.height = x + 1; + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + } + else if(emptysquare) { + r.width = r.height = x; + XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1); + } +} + +static unsigned long +getcolor(const char *colstr) { + Colormap cmap = DefaultColormap(dpy, screen); + XColor color; + + if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) + eprint("error, cannot allocate color '%s'\n", colstr); + return color.pixel; +} + +static Bool +isoccupied(unsigned int t) { + Client *c; + + for(c = clients; c; c = c->next) + if(c->tags[t]) + return True; + return False; +} + static void scan(void) { unsigned int i, num; @@ -69,9 +158,8 @@ scan(void) { wins = NULL; if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { for(i = 0; i < num; i++) { - if(!XGetWindowAttributes(dpy, wins[i], &wa)) - continue; - if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + if(!XGetWindowAttributes(dpy, wins[i], &wa) + || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; if(wa.map_state == IsViewable) manage(wins[i], &wa); @@ -82,6 +170,47 @@ scan(void) { } static void +setfont(const char *fontstr) { + char *def, **missing; + int i, n; + + missing = NULL; + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + if(missing) { + while(n--) + fprintf(stderr, "missing fontset: %s\n", missing[n]); + XFreeStringList(missing); + } + if(dc.font.set) { + XFontSetExtents *font_extents; + XFontStruct **xfonts; + char **font_names; + dc.font.ascent = dc.font.descent = 0; + font_extents = XExtentsOfFontSet(dc.font.set); + n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); + for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) { + if(dc.font.ascent < (*xfonts)->ascent) + dc.font.ascent = (*xfonts)->ascent; + if(dc.font.descent < (*xfonts)->descent) + dc.font.descent = (*xfonts)->descent; + xfonts++; + } + } + else { + if(dc.font.xfont) + XFreeFont(dpy, dc.font.xfont); + dc.font.xfont = NULL; + if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))) + eprint("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; +} + +static void setup(void) { int i, j; unsigned int mask; @@ -104,12 +233,12 @@ setup(void) { /* init modifier map */ numlockmask = 0; modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) { + 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)) + if(modmap->modifiermap[i * modmap->max_keypermod + j] + == XKeysymToKeycode(dpy, XK_Num_Lock)) numlockmask = (1 << i); } - } XFreeModifiermap(modmap); /* select for events */ wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask @@ -117,7 +246,7 @@ setup(void) { wa.cursor = cursor[CurNormal]; XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); grabkeys(); - initrregs(); + compileregs(); for(ntags = 0; tags[ntags]; ntags++); seltag = emallocz(sizeof(Bool) * ntags); seltag[0] = True; @@ -133,9 +262,7 @@ setup(void) { sx = sy = 0; sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); - master = MASTER; - nmaster = NMASTER; - bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL); + initlayouts(); /* bar */ dc.h = bh = dc.font.height + 2; wa.override_redirect = 1; @@ -173,6 +300,37 @@ xerrorstart(Display *dsply, XErrorEvent *ee) { /* extern */ void +drawstatus(void) { + int i, x; + + dc.x = dc.y = 0; + for(i = 0; i < ntags; i++) { + dc.w = textw(tags[i]); + if(seltag[i]) + drawtext(tags[i], dc.sel, sel && sel->tags[i], isoccupied(i)); + else + drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i)); + dc.x += dc.w; + } + dc.w = blw; + drawtext(lt->symbol, dc.norm, False, False); + x = dc.x + dc.w; + dc.w = textw(stext); + dc.x = sw - dc.w; + if(dc.x < x) { + dc.x = x; + dc.w = sw - x; + } + drawtext(stext, dc.norm, False, False); + if((dc.w = dc.x - x) > bh) { + dc.x = x; + drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm, False, False); + } + XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0); + XSync(dpy, False); +} + +void sendevent(Window w, Atom a, long value) { XEvent e; @@ -186,6 +344,11 @@ sendevent(Window w, Atom a, long value) { XSync(dpy, False); } +unsigned int +textw(const char *text) { + return textnw(text, strlen(text)) + dc.font.height; +} + void quit(Arg *arg) { readin = running = False; @@ -216,6 +379,7 @@ main(int argc, char *argv[]) { char *p; int r, xfd; fd_set rd; + XEvent ev; if(argc == 2 && !strncmp("-v", argv[1], 3)) { fputs("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout); @@ -248,7 +412,6 @@ main(int argc, char *argv[]) { /* main event loop, also reads status text from stdin */ XSync(dpy, False); - procevent(); readin = True; while(running) { FD_ZERO(&rd); @@ -280,7 +443,11 @@ main(int argc, char *argv[]) { drawstatus(); } if(FD_ISSET(xfd, &rd)) - procevent(); + while(XPending(dpy)) { + XNextEvent(dpy, &ev); + if(handler[ev.type]) + (handler[ev.type])(&ev); /* call handler */ + } } cleanup(); XCloseDisplay(dpy);