dwm

Extremely fast, small, and dynamic window manager for X
git clone git://git.janpasierb.com/dwm.git
Log | Files | Refs | README | LICENSE

commit 9e8b3258a06de01c53e60243ffe3419b47d016dd
parent 44f2e8b952264311887c3b51dc6a987af226062a
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Thu, 13 Jul 2006 11:43:05 +0200

changed default colors

Diffstat:
MMakefile | 4++--
Mclient.c | 15++++++++-------
Mdev.c | 2+-
Mdraw.c | 89++++++++++++++++++++++++++++++++++---------------------------------------------
Adwm.h | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mevent.c | 2+-
Amain.c | 274+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mutil.c | 2+-
Dwm.c | 272-------------------------------------------------------------------------------
Dwm.h | 137-------------------------------------------------------------------------------
10 files changed, 461 insertions(+), 472 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = client.c dev.c draw.c event.c util.c wm.c +SRC = client.c dev.c draw.c event.c main.c util.c OBJ = ${SRC:.c=.o} MAN1 = dwm.1 BIN = dwm @@ -22,7 +22,7 @@ config: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: wm.h +${OBJ}: dwm.h dwm: ${OBJ} @echo LD $@ diff --git a/client.c b/client.c @@ -9,7 +9,7 @@ #include <X11/Xatom.h> #include <X11/Xutil.h> -#include "wm.h" +#include "dwm.h" static void floating(void); static void tiling(void); @@ -125,8 +125,8 @@ resize_title(Client *c) c->tw = 0; for(i = 0; i < TLast; i++) if(c->tags[i]) - c->tw += textw(&dc.font, c->tags[i]) + dc.font.height; - c->tw += textw(&dc.font, c->name) + dc.font.height; + c->tw += textw(c->tags[i]) + dc.font.height; + c->tw += textw(c->name) + dc.font.height; if(c->tw > c->w) c->tw = c->w + 2; c->tx = c->x + c->w - c->tw + 2; @@ -226,10 +226,12 @@ focus(Client *c) c->snext = stack; stack = c; if(old && old != c) { + XSetWindowBorder(dpy, old->win, dc.bg); XMapWindow(dpy, old->title); draw_client(old); } XUnmapWindow(dpy, c->title); + XSetWindowBorder(dpy, c->win, dc.fg); draw_client(c); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XFlush(dpy); @@ -250,8 +252,6 @@ manage(Window w, XWindowAttributes *wa) c->th = th; c->border = 1; update_size(c); - XSetWindowBorderWidth(dpy, c->win, 1); - XSetWindowBorder(dpy, c->win, dc.border); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); XGetTransientForHint(dpy, c->win, &c->trans); @@ -269,6 +269,7 @@ manage(Window w, XWindowAttributes *wa) for(l=&clients; *l; l=&(*l)->next); c->next = *l; /* *l == nil */ *l = c; + XSetWindowBorderWidth(dpy, c->win, 1); XMapRaised(dpy, c->win); XMapRaised(dpy, c->title); XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask, @@ -435,12 +436,12 @@ draw_client(Client *c) for(i = 0; i < TLast; i++) { if(c->tags[i]) { dc.x += dc.w; - dc.w = textw(&dc.font, c->tags[i]) + dc.font.height; + dc.w = textw(c->tags[i]) + dc.font.height; draw(True, c->tags[i]); } } dc.x += dc.w; - dc.w = textw(&dc.font, c->name) + dc.font.height; + dc.w = textw(c->name) + dc.font.height; draw(True, c->name); XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 0); diff --git a/dev.c b/dev.c @@ -3,7 +3,7 @@ * See LICENSE file for license details. */ -#include "wm.h" +#include "dwm.h" #include <stdlib.h> #include <string.h> diff --git a/draw.c b/draw.c @@ -8,7 +8,7 @@ #include <X11/Xlocale.h> -#include "wm.h" +#include "dwm.h" static void drawborder(void) @@ -59,7 +59,7 @@ draw(Bool border, const char *text) x = dc.x + (h / 2); /* shorten text if necessary */ - while(len && (w = textnw(&dc.font, buf, len)) > dc.w - h) + while(len && (w = textnw(buf, len)) > dc.w - h) buf[--len] = 0; if(w > dc.w) @@ -79,93 +79,80 @@ draw(Bool border, const char *text) } } -static unsigned long -xinitcolors(Colormap cmap, const char *colstr) +unsigned long +initcolor(const char *colstr) { XColor color; + Colormap cmap = DefaultColormap(dpy, screen); + XAllocNamedColor(dpy, cmap, colstr, &color, &color); return color.pixel; } -void -initcolors(const char *bg, const char *fg, const char *border) -{ - Colormap cmap = DefaultColormap(dpy, screen); - dc.bg = xinitcolors(cmap, bg); - dc.fg = xinitcolors(cmap, fg); - dc.border = xinitcolors(cmap, border); -} - unsigned int -textnw(Fnt *font, char *text, unsigned int len) +textnw(char *text, unsigned int len) { XRectangle r; - if(font->set) { - XmbTextExtents(font->set, text, len, NULL, &r); + if(dc.font.set) { + XmbTextExtents(dc.font.set, text, len, NULL, &r); return r.width; } - return XTextWidth(font->xfont, text, len); -} - -unsigned int -textw(Fnt *font, char *text) -{ - return textnw(font, text, strlen(text)); + return XTextWidth(dc.font.xfont, text, len); } unsigned int -texth(Fnt *font) +textw(char *text) { - return font->height + 4; + return textnw(text, strlen(text)); } void -initfont(Fnt *font, const char *fontstr) +initfont(const char *fontstr) { char **missing, *def; int i, n; missing = NULL; setlocale(LC_ALL, ""); - if(font->set) - XFreeFontSet(dpy, font->set); - font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + 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(font->set) { - XFreeFontSet(dpy, font->set); - font->set = NULL; + if(dc.font.set) { + XFreeFontSet(dpy, dc.font.set); + dc.font.set = NULL; } } - if(font->set) { + if(dc.font.set) { XFontSetExtents *font_extents; XFontStruct **xfonts; char **font_names; - font->ascent = font->descent = 0; - font_extents = XExtentsOfFontSet(font->set); - n = XFontsOfFontSet(font->set, &xfonts, &font_names); - for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) { - if(font->ascent < (*xfonts)->ascent) - font->ascent = (*xfonts)->ascent; - if(font->descent < (*xfonts)->descent) - font->descent = (*xfonts)->descent; + 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(font->xfont) - XFreeFont(dpy, font->xfont); - font->xfont = NULL; - font->xfont = XLoadQueryFont(dpy, fontstr); - if (!font->xfont) - font->xfont = XLoadQueryFont(dpy, "fixed"); - if (!font->xfont) + if(dc.font.xfont) + XFreeFont(dpy, dc.font.xfont); + dc.font.xfont = NULL; + dc.font.xfont = XLoadQueryFont(dpy, fontstr); + if (!dc.font.xfont) + dc.font.xfont = XLoadQueryFont(dpy, "fixed"); + if (!dc.font.xfont) error("error, cannot init 'fixed' font\n"); - font->ascent = font->xfont->ascent; - font->descent = font->xfont->descent; + dc.font.ascent = dc.font.xfont->ascent; + dc.font.descent = dc.font.xfont->descent; } - font->height = font->ascent + font->descent; + dc.font.height = dc.font.ascent + dc.font.descent; } diff --git a/dwm.h b/dwm.h @@ -0,0 +1,136 @@ +/* + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <X11/Xlib.h> + +/********** CUSTOMIZE **********/ + +#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" +#define BGCOLOR "DarkSlateGrey" +#define FGCOLOR "LightSteelBlue" +#define BORDERCOLOR "SlateGray" +#define WM_PROTOCOL_DELWIN 1 + +/* tags */ +enum { Tscratch, Tdev, Tirc, Twww, Twork, TLast }; + +/********** CUSTOMIZE **********/ + +typedef struct DC DC; +typedef struct Client Client; +typedef struct Fnt Fnt; +typedef struct Key Key; + +/* atoms */ +enum { WMProtocols, WMDelete, WMLast }; +enum { NetSupported, NetWMName, NetLast }; + +/* cursor */ +enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; + +struct Fnt { + XFontStruct *xfont; + XFontSet set; + int ascent; + int descent; + int height; +}; + +struct DC { /* draw context */ + GC gc; + Drawable drawable; + int x, y, w, h; + Fnt font; + unsigned long bg; + unsigned long fg; + unsigned long border; +}; + +struct Client { + char name[256]; + char *tags[TLast]; + int proto; + int x, y, w, h; + int tx, ty, tw, th; + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int grav; + unsigned int border; + long flags; + Window win; + Window trans; + Window title; + Client *next; + Client *snext; +}; + +struct Key { + unsigned long mod; + KeySym keysym; + void (*func)(void *aux); + void *aux; +}; + +extern Display *dpy; +extern Window root; +extern Atom wm_atom[WMLast], net_atom[NetLast]; +extern Cursor cursor[CurLast]; +extern Bool running, issel; +extern void (*handler[LASTEvent]) (XEvent *); + +extern int tsel, screen, sx, sy, sw, sh, th; +extern char stext[1024], *tags[TLast]; + +extern DC dc; +extern Client *clients, *stack; + +/* client.c */ +extern void manage(Window w, XWindowAttributes *wa); +extern void unmanage(Client *c); +extern Client *getclient(Window w); +extern void focus(Client *c); +extern void update_name(Client *c); +extern void draw_client(Client *c); +extern void resize(Client *c); +extern void update_size(Client *c); +extern Client *gettitle(Window w); +extern void craise(Client *c); +extern void lower(Client *c); +extern void ckill(void *aux); +extern void sel(void *aux); +extern void max(void *aux); +extern void toggle(void *aux); +extern void gravitate(Client *c, Bool invert); + +/* draw.c */ +extern void draw(Bool border, const char *text); +extern unsigned long initcolor(const char *colstr); +extern void initfont(const char *fontstr); +extern unsigned int textnw(char *text, unsigned int len); +extern unsigned int textw(char *text); +extern unsigned int texth(void); + +/* event.c */ +extern void discard_events(long even_mask); + +/* dev.c */ +extern void update_keys(void); +extern void keypress(XEvent *e); +extern void mresize(Client *c); +extern void mmove(Client *c); + +/* main.c */ +extern int error_handler(Display *dsply, XErrorEvent *e); +extern void send_message(Window w, Atom a, long value); +extern int win_proto(Window w); +extern void quit(void *aux); + +/* util.c */ +extern void error(const char *errstr, ...); +extern void *emallocz(unsigned int size); +extern void *emalloc(unsigned int size); +extern void *erealloc(void *ptr, unsigned int size); +extern char *estrdup(const char *str); +extern void spawn(char *argv[]); +extern void swap(void **p1, void **p2); diff --git a/event.c b/event.c @@ -9,7 +9,7 @@ #include <X11/keysym.h> #include <X11/Xatom.h> -#include "wm.h" +#include "dwm.h" /* local functions */ static void buttonpress(XEvent *e); diff --git a/main.c b/main.c @@ -0,0 +1,274 @@ +/* + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include <X11/cursorfont.h> +#include <X11/Xatom.h> +#include <X11/Xproto.h> + +#include "dwm.h" + +/********** CUSTOMIZE **********/ + +char *tags[TLast] = { + [Tscratch] = "scratch", + [Tdev] = "dev", + [Tirc] = "irc", + [Twww] = "www", + [Twork] = "work", +}; + +/********** CUSTOMIZE **********/ + +/* X structs */ +Display *dpy; +Window root, barwin; +Atom wm_atom[WMLast], net_atom[NetLast]; +Cursor cursor[CurLast]; +Bool running = True; +Bool issel; + +char stext[1024]; +int tsel = Tdev; /* default tag */ +int screen, sx, sy, sw, sh, th; + +DC dc = {0}; +Client *clients = NULL; +Client *stack = NULL; + +static Bool other_wm_running; +static const char version[] = + "dwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; +static int (*x_error_handler) (Display *, XErrorEvent *); + +static void +usage() { error("usage: dwm [-v]\n"); } + +static void +scan_wins() +{ + unsigned int i, num; + Window *wins; + XWindowAttributes wa; + Window d1, d2; + + 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)) + continue; + if(wa.map_state == IsViewable) + manage(wins[i], &wa); + } + } + if(wins) + XFree(wins); +} + +static int +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) +{ + Atom real; + int format; + unsigned long res, extra; + int status; + + status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, + &res, &extra, prop); + + if(status != Success || *prop == 0) { + return 0; + } + if(res == 0) { + free((void *) *prop); + } + return res; +} + +int +win_proto(Window w) +{ + unsigned char *protocols; + long res; + int protos = 0; + int i; + + res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, &protocols); + if(res <= 0) { + return protos; + } + for(i = 0; i < res; i++) { + if(protocols[i] == wm_atom[WMDelete]) + protos |= WM_PROTOCOL_DELWIN; + } + free((char *) protocols); + return protos; +} + +void +send_message(Window w, Atom a, long value) +{ + XEvent e; + + e.type = ClientMessage; + e.xclient.window = w; + e.xclient.message_type = a; + e.xclient.format = 32; + e.xclient.data.l[0] = value; + e.xclient.data.l[1] = CurrentTime; + XSendEvent(dpy, w, False, NoEventMask, &e); + XFlush(dpy); +} + +/* + * There's no way to check accesses to destroyed windows, thus + * those cases are ignored (especially on UnmapNotify's). + * Other types of errors call Xlib's default error handler, which + * calls exit(). + */ +int +error_handler(Display *dpy, XErrorEvent *error) +{ + if(error->error_code == BadWindow + || (error->request_code == X_SetInputFocus + && error->error_code == BadMatch) + || (error->request_code == X_PolyText8 + && error->error_code == BadDrawable) + || (error->request_code == X_PolyFillRectangle + && error->error_code == BadDrawable) + || (error->request_code == X_PolySegment + && error->error_code == BadDrawable) + || (error->request_code == X_ConfigureWindow + && error->error_code == BadMatch) + || (error->request_code == X_GrabKey + && error->error_code == BadAccess)) + return 0; + fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", + error->request_code, error->error_code); + return x_error_handler(dpy, error); /* may call exit() */ +} + +/* + * Startup Error handler to check if another window manager + * is already running. + */ +static int +startup_error_handler(Display *dpy, XErrorEvent *error) +{ + other_wm_running = True; + return -1; +} + +static void +cleanup() +{ + while(clients) + unmanage(clients); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); +} + +void +quit(void *aux) +{ + running = False; +} + +int +main(int argc, char *argv[]) +{ + int i; + XSetWindowAttributes wa; + unsigned int mask; + Window w; + XEvent ev; + + /* command line args */ + for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { + switch (argv[i][1]) { + case 'v': + fprintf(stdout, "%s", version); + exit(0); + break; + default: + usage(); + break; + } + } + + dpy = XOpenDisplay(0); + if(!dpy) + error("dwm: cannot connect X server\n"); + + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + + /* check if another WM is already running */ + other_wm_running = False; + XSetErrorHandler(startup_error_handler); + /* this causes an error if some other WM is running */ + XSelectInput(dpy, root, SubstructureRedirectMask); + XFlush(dpy); + + if(other_wm_running) + error("dwm: another window manager is already running\n"); + + sx = sy = 0; + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); + + XSetErrorHandler(0); + x_error_handler = XSetErrorHandler(error_handler); + + /* init atoms */ + wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + + XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, + PropModeReplace, (unsigned char *) net_atom, NetLast); + + + /* init cursors */ + cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); + cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); + cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); + + update_keys(); + + /* style */ + dc.bg = initcolor(BGCOLOR); + dc.fg = initcolor(FGCOLOR); + dc.border = initcolor(BORDERCOLOR); + initfont(FONT); + + th = dc.font.height + 4; + + dc.drawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, root, 0, 0); + + wa.event_mask = SubstructureRedirectMask | EnterWindowMask \ + | LeaveWindowMask; + wa.cursor = cursor[CurNormal]; + XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + + scan_wins(); + + while(running) { + XNextEvent(dpy, &ev); + if(handler[ev.type]) + (handler[ev.type])(&ev); /* call handler */ + } + + cleanup(); + XCloseDisplay(dpy); + + return 0; +} diff --git a/util.c b/util.c @@ -11,7 +11,7 @@ #include <sys/wait.h> #include <unistd.h> -#include "wm.h" +#include "dwm.h" void error(const char *errstr, ...) { diff --git a/wm.c b/wm.c @@ -1,272 +0,0 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include <X11/cursorfont.h> -#include <X11/Xatom.h> -#include <X11/Xproto.h> - -#include "wm.h" - -/********** CUSTOMIZE **********/ - -char *tags[TLast] = { - [Tscratch] = "scratch", - [Tdev] = "dev", - [Tirc] = "irc", - [Twww] = "www", - [Twork] = "work", -}; - -/********** CUSTOMIZE **********/ - -/* X structs */ -Display *dpy; -Window root, barwin; -Atom wm_atom[WMLast], net_atom[NetLast]; -Cursor cursor[CurLast]; -Bool running = True; -Bool issel; - -char stext[1024]; -int tsel = Tdev; /* default tag */ -int screen, sx, sy, sw, sh, th; - -DC dc = {0}; -Client *clients = NULL; -Client *stack = NULL; - -static Bool other_wm_running; -static const char version[] = - "dwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; -static int (*x_error_handler) (Display *, XErrorEvent *); - -static void -usage() { error("usage: dwm [-v]\n"); } - -static void -scan_wins() -{ - unsigned int i, num; - Window *wins; - XWindowAttributes wa; - Window d1, d2; - - 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)) - continue; - if(wa.map_state == IsViewable) - manage(wins[i], &wa); - } - } - if(wins) - XFree(wins); -} - -static int -win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) -{ - Atom real; - int format; - unsigned long res, extra; - int status; - - status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, - &res, &extra, prop); - - if(status != Success || *prop == 0) { - return 0; - } - if(res == 0) { - free((void *) *prop); - } - return res; -} - -int -win_proto(Window w) -{ - unsigned char *protocols; - long res; - int protos = 0; - int i; - - res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, &protocols); - if(res <= 0) { - return protos; - } - for(i = 0; i < res; i++) { - if(protocols[i] == wm_atom[WMDelete]) - protos |= WM_PROTOCOL_DELWIN; - } - free((char *) protocols); - return protos; -} - -void -send_message(Window w, Atom a, long value) -{ - XEvent e; - - e.type = ClientMessage; - e.xclient.window = w; - e.xclient.message_type = a; - e.xclient.format = 32; - e.xclient.data.l[0] = value; - e.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, w, False, NoEventMask, &e); - XFlush(dpy); -} - -/* - * There's no way to check accesses to destroyed windows, thus - * those cases are ignored (especially on UnmapNotify's). - * Other types of errors call Xlib's default error handler, which - * calls exit(). - */ -int -error_handler(Display *dpy, XErrorEvent *error) -{ - if(error->error_code == BadWindow - || (error->request_code == X_SetInputFocus - && error->error_code == BadMatch) - || (error->request_code == X_PolyText8 - && error->error_code == BadDrawable) - || (error->request_code == X_PolyFillRectangle - && error->error_code == BadDrawable) - || (error->request_code == X_PolySegment - && error->error_code == BadDrawable) - || (error->request_code == X_ConfigureWindow - && error->error_code == BadMatch) - || (error->request_code == X_GrabKey - && error->error_code == BadAccess)) - return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", - error->request_code, error->error_code); - return x_error_handler(dpy, error); /* may call exit() */ -} - -/* - * Startup Error handler to check if another window manager - * is already running. - */ -static int -startup_error_handler(Display *dpy, XErrorEvent *error) -{ - other_wm_running = True; - return -1; -} - -static void -cleanup() -{ - while(clients) - unmanage(clients); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); -} - -void -quit(void *aux) -{ - running = False; -} - -int -main(int argc, char *argv[]) -{ - int i; - XSetWindowAttributes wa; - unsigned int mask; - Window w; - XEvent ev; - - /* command line args */ - for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { - switch (argv[i][1]) { - case 'v': - fprintf(stdout, "%s", version); - exit(0); - break; - default: - usage(); - break; - } - } - - dpy = XOpenDisplay(0); - if(!dpy) - error("dwm: cannot connect X server\n"); - - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - - /* check if another WM is already running */ - other_wm_running = False; - XSetErrorHandler(startup_error_handler); - /* this causes an error if some other WM is running */ - XSelectInput(dpy, root, SubstructureRedirectMask); - XFlush(dpy); - - if(other_wm_running) - error("dwm: another window manager is already running\n"); - - sx = sy = 0; - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); - - XSetErrorHandler(0); - x_error_handler = XSetErrorHandler(error_handler); - - /* init atoms */ - wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - - XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) net_atom, NetLast); - - - /* init cursors */ - cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); - cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); - cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); - - update_keys(); - - /* style */ - initcolors(BGCOLOR, FGCOLOR, BORDERCOLOR); - initfont(&dc.font, FONT); - - th = texth(&dc.font); - - dc.drawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, 0); - - wa.event_mask = SubstructureRedirectMask | EnterWindowMask \ - | LeaveWindowMask; - wa.cursor = cursor[CurNormal]; - XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); - - scan_wins(); - - while(running) { - XNextEvent(dpy, &ev); - if(handler[ev.type]) - (handler[ev.type])(&ev); /* call handler */ - } - - cleanup(); - XCloseDisplay(dpy); - - return 0; -} diff --git a/wm.h b/wm.h @@ -1,137 +0,0 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <X11/Xlib.h> - -/********** CUSTOMIZE **********/ - -#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#666699" -#define FGCOLOR "#ffffff" -#define BORDERCOLOR "#9999CC" -#define STATUSDELAY 10 /* seconds */ -#define WM_PROTOCOL_DELWIN 1 - -/* tags */ -enum { Tscratch, Tdev, Tirc, Twww, Twork, TLast }; - -/********** CUSTOMIZE **********/ - -typedef struct DC DC; -typedef struct Client Client; -typedef struct Fnt Fnt; -typedef struct Key Key; - -/* atoms */ -enum { WMProtocols, WMDelete, WMLast }; -enum { NetSupported, NetWMName, NetLast }; - -/* cursor */ -enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; - -struct Fnt { - XFontStruct *xfont; - XFontSet set; - int ascent; - int descent; - int height; -}; - -struct DC { /* draw context */ - GC gc; - Drawable drawable; - int x, y, w, h; - Fnt font; - unsigned long bg; - unsigned long fg; - unsigned long border; -}; - -struct Client { - char name[256]; - char *tags[TLast]; - int proto; - int x, y, w, h; - int tx, ty, tw, th; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int grav; - unsigned int border; - long flags; - Window win; - Window trans; - Window title; - Client *next; - Client *snext; -}; - -struct Key { - unsigned long mod; - KeySym keysym; - void (*func)(void *aux); - void *aux; -}; - -extern Display *dpy; -extern Window root; -extern Atom wm_atom[WMLast], net_atom[NetLast]; -extern Cursor cursor[CurLast]; -extern Bool running, issel; -extern void (*handler[LASTEvent]) (XEvent *); - -extern int tsel, screen, sx, sy, sw, sh, th; -extern char stext[1024], *tags[TLast]; - -extern DC dc; -extern Client *clients, *stack; - -/* client.c */ -extern void manage(Window w, XWindowAttributes *wa); -extern void unmanage(Client *c); -extern Client *getclient(Window w); -extern void focus(Client *c); -extern void update_name(Client *c); -extern void draw_client(Client *c); -extern void resize(Client *c); -extern void update_size(Client *c); -extern Client *gettitle(Window w); -extern void craise(Client *c); -extern void lower(Client *c); -extern void ckill(void *aux); -extern void sel(void *aux); -extern void max(void *aux); -extern void toggle(void *aux); -extern void gravitate(Client *c, Bool invert); - -/* draw.c */ -extern void draw(Bool border, const char *text); -extern void initcolors(const char *bg, const char *fg, const char *bo); -extern void initfont(Fnt *font, const char *fontstr); -extern unsigned int textnw(Fnt *font, char *text, unsigned int len); -extern unsigned int textw(Fnt *font, char *text); -extern unsigned int texth(Fnt *font); - -/* event.c */ -extern void discard_events(long even_mask); - -/* dev.c */ -extern void update_keys(void); -extern void keypress(XEvent *e); -extern void mresize(Client *c); -extern void mmove(Client *c); - -/* util.c */ -extern void error(const char *errstr, ...); -extern void *emallocz(unsigned int size); -extern void *emalloc(unsigned int size); -extern void *erealloc(void *ptr, unsigned int size); -extern char *estrdup(const char *str); -extern void spawn(char *argv[]); -extern void swap(void **p1, void **p2); - -/* wm.c */ -extern int error_handler(Display *dsply, XErrorEvent *e); -extern void send_message(Window w, Atom a, long value); -extern int win_proto(Window w); -extern void quit(void *aux);