| tchanged default colors - dwm - [fork] customized build of dwm, the dynamic win… | |
| git clone git://src.adamsgaard.dk/dwm | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 9e8b3258a06de01c53e60243ffe3419b47d016dd | |
| parent 44f2e8b952264311887c3b51dc6a987af226062a | |
| Author: Anselm R. Garbe <[email protected]> | |
| Date: Thu, 13 Jul 2006 11:43:05 +0200 | |
| changed default colors | |
| Diffstat: | |
| M Makefile | 4 ++-- | |
| M client.c | 15 ++++++++------- | |
| M dev.c | 2 +- | |
| M draw.c | 89 +++++++++++++----------------… | |
| A dwm.h | 136 +++++++++++++++++++++++++++++… | |
| M event.c | 2 +- | |
| A main.c | 274 +++++++++++++++++++++++++++++… | |
| M util.c | 2 +- | |
| D wm.c | 272 -----------------------------… | |
| D wm.h | 137 -----------------------------… | |
| 10 files changed, 461 insertions(+), 472 deletions(-) | |
| --- | |
| diff --git a/Makefile b/Makefile | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -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); | |
| t@@ -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; | |
| t@@ -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); | |
| t@@ -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 | EnterWindow… | |
| XGetTransientForHint(dpy, c->win, &c->trans); | |
| t@@ -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, | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -8,7 +8,7 @@ | |
| #include <X11/Xlocale.h> | |
| -#include "wm.h" | |
| +#include "dwm.h" | |
| static void | |
| drawborder(void) | |
| t@@ -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) | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -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, w… | |
| + 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, scree… | |
| + 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 | |
| t@@ -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 | |
| t@@ -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, w… | |
| - 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, scree… | |
| - 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 | |
| t@@ -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); |