2wm

dual window manager prototype (minimalist dwm with no tags, just one view)
git clone git://git.suckless.org/2wm
Log | Files | Refs | README | LICENSE

commit f650386dfe7bc89ffb4fa5af37de463733b66a84
parent 8b0680e70836aa4a2cba7877cc40d46c1f7f8a47
Author: Anselm R. Garbe <arg@suckless.org>
Date:   Mon, 12 Feb 2007 12:10:21 +0100

removed statusbar
Diffstat:
2wm.h | 11+----------
Makefile | 2+-
client.c | 1-
config.mk | 4++--
draw.c | 175-------------------------------------------------------------------------------
event.c | 72+++---------------------------------------------------------------------
main.c | 88+++++++++++++++++++++++--------------------------------------------------------
util.c | 2+-
view.c | 5-----
9 files changed, 33 insertions(+), 327 deletions(-)

diff --git a/2wm.h b/2wm.h @@ -53,8 +53,6 @@ struct Client { }; extern const char *tags[]; /* all tags */ -extern char stext[256]; /* status text */ -extern int bh, bmw; /* bar height, bar mode label width */ extern int screen, sx, sy, sw, sh; /* screen geometry */ extern int wax, way, wah, waw; /* windowarea geometry */ extern unsigned int master, nmaster; /* master percent, number of master clients */ @@ -67,7 +65,7 @@ extern Client *clients, *sel, *stack; /* global client list and stack */ extern Cursor cursor[CurLast]; extern DC dc; /* global draw context */ extern Display *dpy; -extern Window root, barwin; +extern Window root; /* client.c */ extern void configure(Client *c); /* send synthetic configure event */ @@ -81,15 +79,8 @@ extern void updatesizehints(Client *c); /* update the size hint variables of c extern void updatetitle(Client *c); /* update the name of c */ extern void unmanage(Client *c); /* destroy c */ -/* draw.c */ -extern void drawstatus(void); /* draw the bar */ -extern unsigned long getcolor(const char *colstr); /* return color of colstr */ -extern void setfont(const char *fontstr); /* set the font for DC */ -extern unsigned int textw(const char *text); /* return the width of text in px*/ - /* event.c */ extern void grabkeys(void); /* grab all keys defined in config.h */ -extern void procevent(void); /* process pending X events */ /* main.c */ extern void quit(Arg *arg); /* quit 2wm nicely */ diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = client.c draw.c event.c main.c tag.c util.c view.c +SRC = client.c event.c main.c tag.c util.c view.c OBJ = ${SRC:.c=.o} all: options 2wm diff --git a/client.c b/client.c @@ -99,7 +99,6 @@ focus(Client *c) { grabbuttons(c, True); } sel = c; - drawstatus(); if(!selscreen) return; if(c) { diff --git a/config.mk b/config.mk @@ -17,8 +17,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" LDFLAGS = ${LIBS} -#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = -g ${LIBS} +CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" +LDFLAGS = -g ${LIBS} # Solaris #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" diff --git a/draw.c b/draw.c @@ -1,175 +0,0 @@ -/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ -#include "2wm.h" -#include <stdio.h> -#include <string.h> - -/* static */ - -static Bool -isoccupied(unsigned int t) -{ - Client *c; - for(c = clients; c; c = c->next) - if(c->tags[t]) - return True; - return False; -} - -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); - } -} - -/* 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 = bmw; - drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, 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); -} - -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; -} - -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; -} - -unsigned int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; -} diff --git a/event.c b/event.c @@ -35,14 +35,13 @@ movemouse(Client *c) { c->ismax = False; XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); for(;;) { - XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + XMaskEvent(dpy, MOUSEMASK | SubstructureRedirectMask, &ev); switch (ev.type) { case ButtonRelease: resize(c, True); XUngrabPointer(dpy, CurrentTime); return; case ConfigureRequest: - case Expose: case MapRequest: handler[ev.type](&ev); break; @@ -78,7 +77,7 @@ resizemouse(Client *c) { c->ismax = False; XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); for(;;) { - XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev); + XMaskEvent(dpy, MOUSEMASK | SubstructureRedirectMask , &ev); switch(ev.type) { case ButtonRelease: resize(c, True); @@ -88,7 +87,6 @@ resizemouse(Client *c) { while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); return; case ConfigureRequest: - case Expose: case MapRequest: handler[ev.type](&ev); break; @@ -106,47 +104,10 @@ resizemouse(Client *c) { static void buttonpress(XEvent *e) { - int x; - Arg a; Client *c; XButtonPressedEvent *ev = &e->xbutton; - if(barwin == ev->window) { - x = 0; - for(a.i = 0; a.i < ntags; a.i++) { - x += textw(tags[a.i]); - if(ev->x < x) { - if(ev->button == Button1) { - if(ev->state & MODKEY) - tag(&a); - else - view(&a); - } - else if(ev->button == Button3) { - if(ev->state & MODKEY) - toggletag(&a); - else - toggleview(&a); - } - return; - } - } - if(ev->x < x + bmw) - switch(ev->button) { - case Button1: - togglemode(NULL); - break; - case Button4: - a.i = 1; - incnmaster(&a); - break; - case Button5: - a.i = -1; - incnmaster(&a); - break; - } - } - else if((c = getclient(ev->window))) { + if((c = getclient(ev->window))) { focus(c); if(CLEANMASK(ev->state) != MODKEY) return; @@ -240,16 +201,6 @@ enternotify(XEvent *e) { } static void -expose(XEvent *e) { - XExposeEvent *ev = &e->xexpose; - - if(ev->count == 0) { - if(barwin == ev->window) - drawstatus(); - } -} - -static void keypress(XEvent *e) { static unsigned int len = sizeof key / sizeof key[0]; unsigned int i; @@ -322,11 +273,6 @@ propertynotify(XEvent *e) { updatesizehints(c); break; } - if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if(c == sel) - drawstatus(); - } } } @@ -347,7 +293,6 @@ void (*handler[LASTEvent]) (XEvent *) = { [DestroyNotify] = destroynotify, [EnterNotify] = enternotify, [LeaveNotify] = leavenotify, - [Expose] = expose, [KeyPress] = keypress, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, @@ -374,14 +319,3 @@ grabkeys(void) { GrabModeAsync, GrabModeAsync); } } - -void -procevent(void) { - XEvent ev; - - while(XPending(dpy)) { - XNextEvent(dpy, &ev); - if(handler[ev.type]) - (handler[ev.type])(&ev); /* call handler */ - } -} diff --git a/main.c b/main.c @@ -17,7 +17,6 @@ /* extern */ -char stext[256]; int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah; unsigned int master, nmaster, ntags, numlockmask; Atom wmatom[WMLast], netatom[NetLast]; @@ -35,7 +34,17 @@ Window root, barwin; /* static */ static int (*xerrorxlib)(Display *, XErrorEvent *); -static Bool otherwm, readin; +static Bool otherwm; + +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 void cleanup(void) { @@ -128,29 +137,16 @@ setup(void) { dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); dc.sel[ColBG] = getcolor(SELBGCOLOR); dc.sel[ColFG] = getcolor(SELFGCOLOR); - setfont(FONT); /* geometry */ sx = sy = 0; sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); master = MASTER; nmaster = NMASTER; - bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL); - /* bar */ - dc.h = bh = dc.font.height + 2; - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; - wa.event_mask = ButtonPressMask | ExposureMask; - barwin = XCreateWindow(dpy, root, sx, sy + (TOPBAR ? 0 : sh - bh), sw, bh, 0, - DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - XDefineCursor(dpy, barwin, cursor[CurNormal]); - XMapRaised(dpy, barwin); - strcpy(stext, "dwm-"VERSION); /* windowarea */ wax = sx; - way = sy + (TOPBAR ? bh : 0); - wah = sh - bh; + way = sy; + wah = sh; waw = sw; /* pixmap for everything */ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); @@ -188,7 +184,7 @@ sendevent(Window w, Atom a, long value) { void quit(Arg *arg) { - readin = running = False; + running = False; } /* There's no way to check accesses to destroyed windows, thus those cases are @@ -206,28 +202,23 @@ xerror(Display *dpy, XErrorEvent *ee) { || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", + fprintf(stderr, "2wm: fatal error: request code=%d, error code=%d\n", ee->request_code, ee->error_code); return xerrorxlib(dpy, ee); /* may call exit */ } int 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); - exit(EXIT_SUCCESS); - } + if(argc == 2 && !strncmp("-v", argv[1], 3)) + eprint("2wm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n"); else if(argc != 1) - eprint("usage: dwm [-v]\n"); + eprint("usage: 2wm [-v]\n"); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) - eprint("dwm: cannot open display\n"); - xfd = ConnectionNumber(dpy); + eprint("2wm: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); otherwm = False; @@ -236,51 +227,22 @@ main(int argc, char *argv[]) { XSelectInput(dpy, root, SubstructureRedirectMask); XSync(dpy, False); if(otherwm) - eprint("dwm: another window manager is already running\n"); + eprint("2wm: another window manager is already running\n"); XSync(dpy, False); XSetErrorHandler(NULL); xerrorxlib = XSetErrorHandler(xerror); XSync(dpy, False); setup(); - drawstatus(); scan(); /* main event loop, also reads status text from stdin */ XSync(dpy, False); - procevent(); - readin = True; + while(running) { - FD_ZERO(&rd); - if(readin) - FD_SET(STDIN_FILENO, &rd); - FD_SET(xfd, &rd); - if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) { - if(errno == EINTR) - continue; - eprint("select failed\n"); - } - if(FD_ISSET(STDIN_FILENO, &rd)) { - switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) { - case -1: - strncpy(stext, strerror(errno), sizeof stext - 1); - stext[sizeof stext - 1] = '\0'; - readin = False; - break; - case 0: - strncpy(stext, "EOF", 4); - readin = False; - break; - default: - for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0'); - for(; p >= stext && *p != '\n'; --p); - if(p > stext) - strncpy(stext, p + 1, sizeof stext); - } - drawstatus(); - } - if(FD_ISSET(xfd, &rd)) - procevent(); + XNextEvent(dpy, &ev); + if(handler[ev.type]) + (handler[ev.type])(&ev); /* call handler */ } cleanup(); XCloseDisplay(dpy); diff --git a/util.c b/util.c @@ -45,7 +45,7 @@ spawn(Arg *arg) { close(ConnectionNumber(dpy)); setsid(); execl(shell, shell, "-c", arg->cmd, (char *)NULL); - fprintf(stderr, "dwm: execl '%s -c %s'", shell, arg->cmd); + fprintf(stderr, "2wm: execl '%s -c %s'", shell, arg->cmd); perror(" failed"); } exit(0); diff --git a/view.c b/view.c @@ -155,8 +155,6 @@ incnmaster(Arg *arg) { nmaster += arg->i; if(sel) arrange(); - else - drawstatus(); } Bool @@ -187,7 +185,6 @@ restack(void) { Client *c; XEvent ev; - drawstatus(); if(!sel) return; if(sel->isfloat || arrange == dofloat) @@ -218,8 +215,6 @@ togglemode(Arg *arg) { arrange = (arrange == dofloat) ? dotile : dofloat; if(sel) arrange(); - else - drawstatus(); } void