aewl
changeset 75:f08271b7cb20
rearranged several stuff
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Sat, 15 Jul 2006 16:30:50 +0200 |
parents | 5370ef170cc9 |
children | 4bd49f404f10 |
files | Makefile client.c draw.c dwm.h event.c main.c tag.c util.c |
diffstat | 10 files changed, 442 insertions(+), 444 deletions(-) [+] |
line diff
1.1 --- a/Makefile Fri Jul 14 22:54:09 2006 +0200 1.2 +++ b/Makefile Sat Jul 15 16:30:50 2006 +0200 1.3 @@ -3,7 +3,7 @@ 1.4 1.5 include config.mk 1.6 1.7 -SRC = client.c draw.c event.c key.c main.c screen.c util.c 1.8 +SRC = client.c draw.c event.c main.c tag.c util.c 1.9 OBJ = ${SRC:.c=.o} 1.10 MAN1 = dwm.1 1.11 BIN = dwm
2.1 --- a/client.c Fri Jul 14 22:54:09 2006 +0200 2.2 +++ b/client.c Sat Jul 15 16:30:50 2006 +0200 2.3 @@ -11,18 +11,6 @@ 2.4 2.5 #include "dwm.h" 2.6 2.7 -static Rule rule[] = { 2.8 - /* class instance tags floating */ 2.9 - { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, 2.10 -}; 2.11 - 2.12 -Client * 2.13 -getnext(Client *c) 2.14 -{ 2.15 - for(; c && !c->tags[tsel]; c = c->next); 2.16 - return c; 2.17 -} 2.18 - 2.19 void 2.20 ban(Client *c) 2.21 { 2.22 @@ -31,7 +19,7 @@ 2.23 } 2.24 2.25 static void 2.26 -resize_title(Client *c) 2.27 +resizetitle(Client *c) 2.28 { 2.29 int i; 2.30 2.31 @@ -72,7 +60,7 @@ 2.32 } 2.33 } 2.34 XFree(name.value); 2.35 - resize_title(c); 2.36 + resizetitle(c); 2.37 } 2.38 2.39 void 2.40 @@ -143,42 +131,6 @@ 2.41 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 2.42 } 2.43 2.44 -static void 2.45 -init_tags(Client *c) 2.46 -{ 2.47 - XClassHint ch; 2.48 - static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; 2.49 - unsigned int i, j; 2.50 - Bool matched = False; 2.51 - 2.52 - if(!len) { 2.53 - c->tags[tsel] = tags[tsel]; 2.54 - return; 2.55 - } 2.56 - 2.57 - if(XGetClassHint(dpy, c->win, &ch)) { 2.58 - if(ch.res_class && ch.res_name) { 2.59 - for(i = 0; i < len; i++) 2.60 - if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) 2.61 - && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) 2.62 - { 2.63 - for(j = 0; j < TLast; j++) 2.64 - c->tags[j] = rule[i].tags[j]; 2.65 - c->floating = rule[i].floating; 2.66 - matched = True; 2.67 - break; 2.68 - } 2.69 - } 2.70 - if(ch.res_class) 2.71 - XFree(ch.res_class); 2.72 - if(ch.res_name) 2.73 - XFree(ch.res_name); 2.74 - } 2.75 - 2.76 - if(!matched) 2.77 - c->tags[tsel] = tags[tsel]; 2.78 -} 2.79 - 2.80 void 2.81 manage(Window w, XWindowAttributes *wa) 2.82 { 2.83 @@ -196,7 +148,7 @@ 2.84 c->h = wa->height; 2.85 c->th = bh; 2.86 c->border = 1; 2.87 - c->proto = proto(c->win); 2.88 + c->proto = getproto(c->win); 2.89 setsize(c); 2.90 XSelectInput(dpy, c->win, 2.91 StructureNotifyMask | PropertyChangeMask | EnterWindowMask); 2.92 @@ -211,7 +163,7 @@ 2.93 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); 2.94 2.95 settitle(c); 2.96 - init_tags(c); 2.97 + settags(c); 2.98 2.99 for(l = &clients; *l; l = &(*l)->next); 2.100 c->next = *l; /* *l == nil */ 2.101 @@ -224,8 +176,8 @@ 2.102 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, 2.103 GrabModeAsync, GrabModeSync, None, None); 2.104 2.105 - if(!c->floating) 2.106 - c->floating = trans 2.107 + if(!c->dofloat) 2.108 + c->dofloat = trans 2.109 || ((c->maxw == c->minw) && (c->maxh == c->minh)); 2.110 2.111 arrange(NULL); 2.112 @@ -321,7 +273,7 @@ 2.113 c->w = c->maxw; 2.114 if(c->maxh && c->h > c->maxh) 2.115 c->h = c->maxh; 2.116 - resize_title(c); 2.117 + resizetitle(c); 2.118 XSetWindowBorderWidth(dpy, c->win, 1); 2.119 XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); 2.120 e.type = ConfigureNotify; 2.121 @@ -339,7 +291,7 @@ 2.122 } 2.123 2.124 static int 2.125 -dummy_xerror(Display *dsply, XErrorEvent *err) 2.126 +xerrordummy(Display *dsply, XErrorEvent *ee) 2.127 { 2.128 return 0; 2.129 } 2.130 @@ -350,7 +302,7 @@ 2.131 Client **l; 2.132 2.133 XGrabServer(dpy); 2.134 - XSetErrorHandler(dummy_xerror); 2.135 + XSetErrorHandler(xerrordummy); 2.136 2.137 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 2.138 XDestroyWindow(dpy, c->title); 2.139 @@ -374,7 +326,7 @@ 2.140 } 2.141 2.142 Client * 2.143 -gettitle(Window w) 2.144 +getctitle(Window w) 2.145 { 2.146 Client *c; 2.147 for(c = clients; c; c = c->next) 2.148 @@ -392,3 +344,80 @@ 2.149 return c; 2.150 return NULL; 2.151 } 2.152 + 2.153 +void 2.154 +zoom(Arg *arg) 2.155 +{ 2.156 + Client **l, *c; 2.157 + 2.158 + if(!sel) 2.159 + return; 2.160 + 2.161 + if(sel == getnext(clients) && sel->next) { 2.162 + if((c = getnext(sel->next))) 2.163 + sel = c; 2.164 + } 2.165 + 2.166 + for(l = &clients; *l && *l != sel; l = &(*l)->next); 2.167 + *l = sel->next; 2.168 + 2.169 + sel->next = clients; /* pop */ 2.170 + clients = sel; 2.171 + arrange(NULL); 2.172 + focus(sel); 2.173 +} 2.174 + 2.175 +void 2.176 +maximize(Arg *arg) 2.177 +{ 2.178 + if(!sel) 2.179 + return; 2.180 + sel->x = sx; 2.181 + sel->y = sy + bh; 2.182 + sel->w = sw - 2 * sel->border; 2.183 + sel->h = sh - 2 * sel->border - bh; 2.184 + higher(sel); 2.185 + resize(sel, False); 2.186 +} 2.187 + 2.188 +void 2.189 +focusprev(Arg *arg) 2.190 +{ 2.191 + Client *c; 2.192 + 2.193 + if(!sel) 2.194 + return; 2.195 + 2.196 + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { 2.197 + higher(c); 2.198 + focus(c); 2.199 + } 2.200 +} 2.201 + 2.202 +void 2.203 +focusnext(Arg *arg) 2.204 +{ 2.205 + Client *c; 2.206 + 2.207 + if(!sel) 2.208 + return; 2.209 + 2.210 + if(!(c = getnext(sel->next))) 2.211 + c = getnext(clients); 2.212 + if(c) { 2.213 + higher(c); 2.214 + c->revert = sel; 2.215 + focus(c); 2.216 + } 2.217 +} 2.218 + 2.219 +void 2.220 +killclient(Arg *arg) 2.221 +{ 2.222 + if(!sel) 2.223 + return; 2.224 + if(sel->proto & WM_PROTOCOL_DELWIN) 2.225 + sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 2.226 + else 2.227 + XKillClient(dpy, sel->win); 2.228 +}
3.1 --- a/draw.c Fri Jul 14 22:54:09 2006 +0200 3.2 +++ b/draw.c Sat Jul 15 16:30:50 2006 +0200 3.3 @@ -11,33 +11,42 @@ 3.4 #include "dwm.h" 3.5 3.6 void 3.7 +drawall() 3.8 +{ 3.9 + Client *c; 3.10 + 3.11 + for(c = clients; c; c = getnext(c->next)) 3.12 + drawtitle(c); 3.13 + drawstatus(); 3.14 +} 3.15 + 3.16 +void 3.17 drawstatus() 3.18 { 3.19 int i; 3.20 + Bool istile = arrange == dotile; 3.21 3.22 dc.x = dc.y = 0; 3.23 dc.w = bw; 3.24 - drawtext(NULL, False, False); 3.25 + drawtext(NULL, !istile, False); 3.26 3.27 - if(arrange == floating) { 3.28 - dc.w = textw("~"); 3.29 - drawtext("~", False, False); 3.30 - } 3.31 - else 3.32 - dc.w = 0; 3.33 + dc.w = 0; 3.34 for(i = 0; i < TLast; i++) { 3.35 dc.x += dc.w; 3.36 dc.w = textw(tags[i]); 3.37 - drawtext(tags[i], i == tsel, True); 3.38 + if(istile) 3.39 + drawtext(tags[i], (i == tsel), True); 3.40 + else 3.41 + drawtext(tags[i], (i != tsel), True); 3.42 } 3.43 if(sel) { 3.44 dc.x += dc.w; 3.45 dc.w = textw(sel->name); 3.46 - drawtext(sel->name, True, True); 3.47 + drawtext(sel->name, istile, True); 3.48 } 3.49 dc.w = textw(stext); 3.50 dc.x = bx + bw - dc.w; 3.51 - drawtext(stext, False, False); 3.52 + drawtext(stext, !istile, False); 3.53 3.54 XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); 3.55 XFlush(dpy); 3.56 @@ -47,6 +56,8 @@ 3.57 drawtitle(Client *c) 3.58 { 3.59 int i; 3.60 + Bool istile = arrange == dotile; 3.61 + 3.62 if(c == sel) { 3.63 drawstatus(); 3.64 XUnmapWindow(dpy, c->title); 3.65 @@ -64,12 +75,12 @@ 3.66 if(c->tags[i]) { 3.67 dc.x += dc.w; 3.68 dc.w = textw(c->tags[i]); 3.69 - drawtext(c->tags[i], False, True); 3.70 + drawtext(c->tags[i], !istile, True); 3.71 } 3.72 } 3.73 dc.x += dc.w; 3.74 dc.w = textw(c->name); 3.75 - drawtext(c->name, False, True); 3.76 + drawtext(c->name, !istile, True); 3.77 XCopyArea(dpy, dc.drawable, c->title, dc.gc, 3.78 0, 0, c->tw, c->th, 0, 0); 3.79 XFlush(dpy); 3.80 @@ -215,7 +226,7 @@ 3.81 if (!dc.font.xfont) 3.82 dc.font.xfont = XLoadQueryFont(dpy, "fixed"); 3.83 if (!dc.font.xfont) 3.84 - error("error, cannot init 'fixed' font\n"); 3.85 + eprint("error, cannot init 'fixed' font\n"); 3.86 dc.font.ascent = dc.font.xfont->ascent; 3.87 dc.font.descent = dc.font.xfont->descent; 3.88 }
4.1 --- a/dwm.h Fri Jul 14 22:54:09 2006 +0200 4.2 +++ b/dwm.h Sat Jul 15 16:30:50 2006 +0200 4.3 @@ -66,7 +66,7 @@ 4.4 int grav; 4.5 unsigned int border; 4.6 long flags; 4.7 - Bool floating; 4.8 + Bool dofloat; 4.9 Window win; 4.10 Window title; 4.11 Client *next; 4.12 @@ -77,7 +77,7 @@ 4.13 const char *class; 4.14 const char *instance; 4.15 char *tags[TLast]; 4.16 - Bool floating; 4.17 + Bool dofloat; 4.18 }; 4.19 4.20 struct Key { 4.21 @@ -103,6 +103,7 @@ 4.22 extern Client *clients, *sel; 4.23 4.24 /* client.c */ 4.25 +extern void ban(Client *c); 4.26 extern void manage(Window w, XWindowAttributes *wa); 4.27 extern void unmanage(Client *c); 4.28 extern Client *getclient(Window w); 4.29 @@ -110,14 +111,18 @@ 4.30 extern void settitle(Client *c); 4.31 extern void resize(Client *c, Bool inc); 4.32 extern void setsize(Client *c); 4.33 -extern Client *gettitle(Window w); 4.34 +extern Client *getctitle(Window w); 4.35 extern void higher(Client *c); 4.36 extern void lower(Client *c); 4.37 extern void gravitate(Client *c, Bool invert); 4.38 -extern void ban(Client *c); 4.39 -extern Client *getnext(Client *c); 4.40 +extern void zoom(Arg *arg); 4.41 +extern void maximize(Arg *arg); 4.42 +extern void focusprev(Arg *arg); 4.43 +extern void focusnext(Arg *arg); 4.44 +extern void killclient(Arg *arg); 4.45 4.46 /* draw.c */ 4.47 +extern void drawall(); 4.48 extern void drawstatus(); 4.49 extern void drawtitle(Client *c); 4.50 extern void drawtext(const char *text, Bool invert, Bool border); 4.51 @@ -127,22 +132,25 @@ 4.52 extern unsigned int textw(char *text); 4.53 extern unsigned int texth(void); 4.54 4.55 -/* key.c */ 4.56 +/* event.c */ 4.57 extern void grabkeys(); 4.58 -extern void keypress(XEvent *e); 4.59 4.60 /* main.c */ 4.61 -extern int xerror(Display *dsply, XErrorEvent *e); 4.62 +extern void quit(Arg *arg); 4.63 +extern int xerror(Display *dsply, XErrorEvent *ee); 4.64 extern void sendevent(Window w, Atom a, long value); 4.65 -extern int proto(Window w); 4.66 -extern void quit(Arg *arg); 4.67 +extern int getproto(Window w); 4.68 4.69 -/* screen.c */ 4.70 -extern void floating(Arg *arg); 4.71 -extern void tiling(Arg *arg); 4.72 +/* tag.c */ 4.73 +extern Client *getnext(Client *c); 4.74 +extern void settags(Client *c); 4.75 +extern void dofloat(Arg *arg); 4.76 +extern void dotile(Arg *arg); 4.77 extern void view(Arg *arg); 4.78 +extern void appendtag(Arg *arg); 4.79 +extern void replacetag(Arg *arg); 4.80 4.81 /* util.c */ 4.82 -extern void error(const char *errstr, ...); 4.83 +extern void eprint(const char *errstr, ...); 4.84 extern void *emallocz(unsigned int size); 4.85 extern void spawn(Arg *arg);
5.1 --- a/event.c Fri Jul 14 22:54:09 2006 +0200 5.2 +++ b/event.c Sat Jul 15 16:30:50 2006 +0200 5.3 @@ -16,6 +16,44 @@ 5.4 #define ButtonMask (ButtonPressMask | ButtonReleaseMask) 5.5 #define MouseMask (ButtonMask | PointerMotionMask) 5.6 5.7 +/********** CUSTOMIZE **********/ 5.8 + 5.9 +const char *term[] = { 5.10 + "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", 5.11 + "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL 5.12 +}; 5.13 +const char *browse[] = { "firefox", NULL }; 5.14 +const char *xlock[] = { "xlock", NULL }; 5.15 + 5.16 +Key key[] = { 5.17 + /* modifier key function arguments */ 5.18 + { Mod1Mask, XK_Return, zoom, { 0 } }, 5.19 + { Mod1Mask, XK_k, focusprev, { 0 } }, 5.20 + { Mod1Mask, XK_j, focusnext, { 0 } }, 5.21 + { Mod1Mask, XK_m, maximize, { 0 } }, 5.22 + { Mod1Mask, XK_0, view, { .i = Tscratch } }, 5.23 + { Mod1Mask, XK_1, view, { .i = Tdev } }, 5.24 + { Mod1Mask, XK_2, view, { .i = Twww } }, 5.25 + { Mod1Mask, XK_3, view, { .i = Twork } }, 5.26 + { Mod1Mask, XK_space, dotile, { 0 } }, 5.27 + { Mod1Mask|ShiftMask, XK_space, dofloat, { 0 } }, 5.28 + { Mod1Mask|ShiftMask, XK_0, replacetag, { .i = Tscratch } }, 5.29 + { Mod1Mask|ShiftMask, XK_1, replacetag, { .i = Tdev } }, 5.30 + { Mod1Mask|ShiftMask, XK_2, replacetag, { .i = Twww } }, 5.31 + { Mod1Mask|ShiftMask, XK_3, replacetag, { .i = Twork } }, 5.32 + { Mod1Mask|ShiftMask, XK_c, killclient, { 0 } }, 5.33 + { Mod1Mask|ShiftMask, XK_q, quit, { 0 } }, 5.34 + { Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } }, 5.35 + { Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } }, 5.36 + { Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } }, 5.37 + { ControlMask, XK_0, appendtag, { .i = Tscratch } }, 5.38 + { ControlMask, XK_1, appendtag, { .i = Tdev } }, 5.39 + { ControlMask, XK_2, appendtag, { .i = Twww } }, 5.40 + { ControlMask, XK_3, appendtag, { .i = Twork } }, 5.41 +}; 5.42 + 5.43 +/********** CUSTOMIZE **********/ 5.44 + 5.45 /* local functions */ 5.46 static void buttonpress(XEvent *e); 5.47 static void configurerequest(XEvent *e); 5.48 @@ -23,6 +61,7 @@ 5.49 static void enternotify(XEvent *e); 5.50 static void leavenotify(XEvent *e); 5.51 static void expose(XEvent *e); 5.52 +static void keypress(XEvent *e); 5.53 static void maprequest(XEvent *e); 5.54 static void propertynotify(XEvent *e); 5.55 static void unmapnotify(XEvent *e); 5.56 @@ -40,8 +79,40 @@ 5.57 [UnmapNotify] = unmapnotify 5.58 }; 5.59 5.60 +void 5.61 +grabkeys() 5.62 +{ 5.63 + static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 5.64 + unsigned int i; 5.65 + KeyCode code; 5.66 + 5.67 + for(i = 0; i < len; i++) { 5.68 + code = XKeysymToKeycode(dpy, key[i].keysym); 5.69 + XUngrabKey(dpy, code, key[i].mod, root); 5.70 + XGrabKey(dpy, code, key[i].mod, root, True, 5.71 + GrabModeAsync, GrabModeAsync); 5.72 + } 5.73 +} 5.74 + 5.75 static void 5.76 -mresize(Client *c) 5.77 +keypress(XEvent *e) 5.78 +{ 5.79 + XKeyEvent *ev = &e->xkey; 5.80 + static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 5.81 + unsigned int i; 5.82 + KeySym keysym; 5.83 + 5.84 + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 5.85 + for(i = 0; i < len; i++) 5.86 + if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { 5.87 + if(key[i].func) 5.88 + key[i].func(&key[i].arg); 5.89 + return; 5.90 + } 5.91 +} 5.92 + 5.93 +static void 5.94 +resizemouse(Client *c) 5.95 { 5.96 XEvent ev; 5.97 int ocx, ocy; 5.98 @@ -75,7 +146,7 @@ 5.99 } 5.100 5.101 static void 5.102 -mmove(Client *c) 5.103 +movemouse(Client *c) 5.104 { 5.105 XEvent ev; 5.106 int x1, y1, ocx, ocy, di; 5.107 @@ -117,7 +188,7 @@ 5.108 Client *c; 5.109 5.110 if(barwin == ev->window) { 5.111 - x = (arrange == floating) ? textw("~") : 0; 5.112 + x = (arrange == dofloat) ? textw("~") : 0; 5.113 for(a.i = 0; a.i < TLast; a.i++) { 5.114 x += textw(tags[a.i]); 5.115 if(ev->x < x) { 5.116 @@ -127,20 +198,20 @@ 5.117 } 5.118 } 5.119 else if((c = getclient(ev->window))) { 5.120 - if(arrange == tiling && !c->floating) 5.121 + if(arrange == dotile && !c->dofloat) 5.122 return; 5.123 higher(c); 5.124 switch(ev->button) { 5.125 default: 5.126 break; 5.127 case Button1: 5.128 - mmove(c); 5.129 + movemouse(c); 5.130 break; 5.131 case Button2: 5.132 lower(c); 5.133 break; 5.134 case Button3: 5.135 - mresize(c); 5.136 + resizemouse(c); 5.137 break; 5.138 } 5.139 } 5.140 @@ -226,7 +297,7 @@ 5.141 if(ev->count == 0) { 5.142 if(barwin == ev->window) 5.143 drawstatus(); 5.144 - else if((c = gettitle(ev->window))) 5.145 + else if((c = getctitle(ev->window))) 5.146 drawtitle(c); 5.147 } 5.148 } 5.149 @@ -262,14 +333,14 @@ 5.150 5.151 if((c = getclient(ev->window))) { 5.152 if(ev->atom == wm_atom[WMProtocols]) { 5.153 - c->proto = proto(c->win); 5.154 + c->proto = getproto(c->win); 5.155 return; 5.156 } 5.157 switch (ev->atom) { 5.158 default: break; 5.159 case XA_WM_TRANSIENT_FOR: 5.160 XGetTransientForHint(dpy, c->win, &trans); 5.161 - if(!c->floating && (c->floating = (trans != 0))) 5.162 + if(!c->dofloat && (c->dofloat = (trans != 0))) 5.163 arrange(NULL); 5.164 break; 5.165 case XA_WM_NORMAL_HINTS:
6.1 --- a/key.c Fri Jul 14 22:54:09 2006 +0200 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,192 +0,0 @@ 6.4 -/* 6.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 6.6 - * See LICENSE file for license details. 6.7 - */ 6.8 - 6.9 -#include <fcntl.h> 6.10 -#include <stdio.h> 6.11 -#include <stdlib.h> 6.12 -#include <string.h> 6.13 -#include <unistd.h> 6.14 -#include <X11/keysym.h> 6.15 -#include <X11/Xatom.h> 6.16 - 6.17 -#include "dwm.h" 6.18 - 6.19 -static void ckill(Arg *arg); 6.20 -static void nextc(Arg *arg); 6.21 -static void prevc(Arg *arg); 6.22 -static void max(Arg *arg); 6.23 -static void ttrunc(Arg *arg); 6.24 -static void tappend(Arg *arg); 6.25 -static void zoom(Arg *arg); 6.26 - 6.27 -/********** CUSTOMIZE **********/ 6.28 - 6.29 -const char *term[] = { 6.30 - "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", 6.31 - "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL 6.32 -}; 6.33 -const char *browse[] = { "firefox", NULL }; 6.34 -const char *xlock[] = { "xlock", NULL }; 6.35 - 6.36 -Key key[] = { 6.37 - /* modifier key function arguments */ 6.38 - { Mod1Mask, XK_Return, zoom, { 0 } }, 6.39 - { Mod1Mask, XK_k, prevc, { 0 } }, 6.40 - { Mod1Mask, XK_j, nextc, { 0 } }, 6.41 - { Mod1Mask, XK_m, max, { 0 } }, 6.42 - { Mod1Mask, XK_0, view, { .i = Tscratch } }, 6.43 - { Mod1Mask, XK_1, view, { .i = Tdev } }, 6.44 - { Mod1Mask, XK_2, view, { .i = Twww } }, 6.45 - { Mod1Mask, XK_3, view, { .i = Twork } }, 6.46 - { Mod1Mask, XK_space, tiling, { 0 } }, 6.47 - { Mod1Mask|ShiftMask, XK_space, floating, { 0 } }, 6.48 - { Mod1Mask|ShiftMask, XK_0, ttrunc, { .i = Tscratch } }, 6.49 - { Mod1Mask|ShiftMask, XK_1, ttrunc, { .i = Tdev } }, 6.50 - { Mod1Mask|ShiftMask, XK_2, ttrunc, { .i = Twww } }, 6.51 - { Mod1Mask|ShiftMask, XK_3, ttrunc, { .i = Twork } }, 6.52 - { Mod1Mask|ShiftMask, XK_c, ckill, { 0 } }, 6.53 - { Mod1Mask|ShiftMask, XK_q, quit, { 0 } }, 6.54 - { Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } }, 6.55 - { Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } }, 6.56 - { Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } }, 6.57 - { ControlMask, XK_0, tappend, { .i = Tscratch } }, 6.58 - { ControlMask, XK_1, tappend, { .i = Tdev } }, 6.59 - { ControlMask, XK_2, tappend, { .i = Twww } }, 6.60 - { ControlMask, XK_3, tappend, { .i = Twork } }, 6.61 -}; 6.62 - 6.63 -/********** CUSTOMIZE **********/ 6.64 - 6.65 -void 6.66 -grabkeys() 6.67 -{ 6.68 - static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 6.69 - unsigned int i; 6.70 - KeyCode code; 6.71 - 6.72 - for(i = 0; i < len; i++) { 6.73 - code = XKeysymToKeycode(dpy, key[i].keysym); 6.74 - XUngrabKey(dpy, code, key[i].mod, root); 6.75 - XGrabKey(dpy, code, key[i].mod, root, True, 6.76 - GrabModeAsync, GrabModeAsync); 6.77 - } 6.78 -} 6.79 - 6.80 -void 6.81 -keypress(XEvent *e) 6.82 -{ 6.83 - XKeyEvent *ev = &e->xkey; 6.84 - static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 6.85 - unsigned int i; 6.86 - KeySym keysym; 6.87 - 6.88 - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 6.89 - for(i = 0; i < len; i++) 6.90 - if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { 6.91 - if(key[i].func) 6.92 - key[i].func(&key[i].arg); 6.93 - return; 6.94 - } 6.95 -} 6.96 - 6.97 -static void 6.98 -zoom(Arg *arg) 6.99 -{ 6.100 - Client **l, *c; 6.101 - 6.102 - if(!sel) 6.103 - return; 6.104 - 6.105 - if(sel == getnext(clients) && sel->next) { 6.106 - if((c = getnext(sel->next))) 6.107 - sel = c; 6.108 - } 6.109 - 6.110 - for(l = &clients; *l && *l != sel; l = &(*l)->next); 6.111 - *l = sel->next; 6.112 - 6.113 - sel->next = clients; /* pop */ 6.114 - clients = sel; 6.115 - arrange(NULL); 6.116 - focus(sel); 6.117 -} 6.118 - 6.119 -static void 6.120 -max(Arg *arg) 6.121 -{ 6.122 - if(!sel) 6.123 - return; 6.124 - sel->x = sx; 6.125 - sel->y = sy + bh; 6.126 - sel->w = sw - 2 * sel->border; 6.127 - sel->h = sh - 2 * sel->border - bh; 6.128 - higher(sel); 6.129 - resize(sel, False); 6.130 -} 6.131 - 6.132 -static void 6.133 -tappend(Arg *arg) 6.134 -{ 6.135 - if(!sel) 6.136 - return; 6.137 - 6.138 - sel->tags[arg->i] = tags[arg->i]; 6.139 - arrange(NULL); 6.140 -} 6.141 - 6.142 -static void 6.143 -ttrunc(Arg *arg) 6.144 -{ 6.145 - int i; 6.146 - if(!sel) 6.147 - return; 6.148 - 6.149 - for(i = 0; i < TLast; i++) 6.150 - sel->tags[i] = NULL; 6.151 - tappend(arg); 6.152 -} 6.153 - 6.154 -static void 6.155 -prevc(Arg *arg) 6.156 -{ 6.157 - Client *c; 6.158 - 6.159 - if(!sel) 6.160 - return; 6.161 - 6.162 - if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { 6.163 - higher(c); 6.164 - focus(c); 6.165 - } 6.166 -} 6.167 - 6.168 -static void 6.169 -nextc(Arg *arg) 6.170 -{ 6.171 - Client *c; 6.172 - 6.173 - if(!sel) 6.174 - return; 6.175 - 6.176 - if(!(c = getnext(sel->next))) 6.177 - c = getnext(clients); 6.178 - if(c) { 6.179 - higher(c); 6.180 - c->revert = sel; 6.181 - focus(c); 6.182 - } 6.183 -} 6.184 - 6.185 -static void 6.186 -ckill(Arg *arg) 6.187 -{ 6.188 - if(!sel) 6.189 - return; 6.190 - if(sel->proto & WM_PROTOCOL_DELWIN) 6.191 - sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 6.192 - else 6.193 - XKillClient(dpy, sel->win); 6.194 -} 6.195 -
7.1 --- a/main.c Fri Jul 14 22:54:09 2006 +0200 7.2 +++ b/main.c Sat Jul 15 16:30:50 2006 +0200 7.3 @@ -43,16 +43,16 @@ 7.4 Client *clients = NULL; 7.5 Client *sel = NULL; 7.6 7.7 -static Bool other_wm_running; 7.8 +static Bool otherwm; 7.9 static const char version[] = 7.10 "dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; 7.11 -static int (*x_xerror) (Display *, XErrorEvent *); 7.12 +static int (*xerrorxlib)(Display *, XErrorEvent *); 7.13 7.14 static void 7.15 -usage() { error("usage: dwm [-v]\n"); } 7.16 +usage() { eprint("usage: dwm [-v]\n"); } 7.17 7.18 static void 7.19 -scan_wins() 7.20 +scan() 7.21 { 7.22 unsigned int i, num; 7.23 Window *wins; 7.24 @@ -73,6 +73,22 @@ 7.25 XFree(wins); 7.26 } 7.27 7.28 +static void 7.29 +cleanup() 7.30 +{ 7.31 + while(sel) { 7.32 + resize(sel, True); 7.33 + unmanage(sel); 7.34 + } 7.35 + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 7.36 +} 7.37 + 7.38 +void 7.39 +quit(Arg *arg) 7.40 +{ 7.41 + running = False; 7.42 +} 7.43 + 7.44 static int 7.45 win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) 7.46 { 7.47 @@ -94,7 +110,7 @@ 7.48 } 7.49 7.50 int 7.51 -proto(Window w) 7.52 +getproto(Window w) 7.53 { 7.54 unsigned char *protocols; 7.55 long res; 7.56 @@ -129,58 +145,42 @@ 7.57 } 7.58 7.59 /* 7.60 + * Startup Error handler to check if another window manager 7.61 + * is already running. 7.62 + */ 7.63 +static int 7.64 +xerrorstart(Display *dsply, XErrorEvent *ee) 7.65 +{ 7.66 + otherwm = True; 7.67 + return -1; 7.68 +} 7.69 + 7.70 +/* 7.71 * There's no way to check accesses to destroyed windows, thus 7.72 * those cases are ignored (especially on UnmapNotify's). 7.73 * Other types of errors call Xlib's default error handler, which 7.74 * calls exit(). 7.75 */ 7.76 int 7.77 -xerror(Display *dpy, XErrorEvent *error) 7.78 +xerror(Display *dpy, XErrorEvent *ee) 7.79 { 7.80 - if(error->error_code == BadWindow 7.81 - || (error->request_code == X_SetInputFocus 7.82 - && error->error_code == BadMatch) 7.83 - || (error->request_code == X_PolyText8 7.84 - && error->error_code == BadDrawable) 7.85 - || (error->request_code == X_PolyFillRectangle 7.86 - && error->error_code == BadDrawable) 7.87 - || (error->request_code == X_PolySegment 7.88 - && error->error_code == BadDrawable) 7.89 - || (error->request_code == X_ConfigureWindow 7.90 - && error->error_code == BadMatch) 7.91 - || (error->request_code == X_GrabKey 7.92 - && error->error_code == BadAccess)) 7.93 + if(ee->error_code == BadWindow 7.94 + || (ee->request_code == X_SetInputFocus 7.95 + && ee->error_code == BadMatch) 7.96 + || (ee->request_code == X_PolyText8 7.97 + && ee->error_code == BadDrawable) 7.98 + || (ee->request_code == X_PolyFillRectangle 7.99 + && ee->error_code == BadDrawable) 7.100 + || (ee->request_code == X_PolySegment 7.101 + && ee->error_code == BadDrawable) 7.102 + || (ee->request_code == X_ConfigureWindow 7.103 + && ee->error_code == BadMatch) 7.104 + || (ee->request_code == X_GrabKey 7.105 + && ee->error_code == BadAccess)) 7.106 return 0; 7.107 fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", 7.108 - error->request_code, error->error_code); 7.109 - return x_xerror(dpy, error); /* may call exit() */ 7.110 -} 7.111 - 7.112 -/* 7.113 - * Startup Error handler to check if another window manager 7.114 - * is already running. 7.115 - */ 7.116 -static int 7.117 -startup_xerror(Display *dpy, XErrorEvent *error) 7.118 -{ 7.119 - other_wm_running = True; 7.120 - return -1; 7.121 -} 7.122 - 7.123 -static void 7.124 -cleanup() 7.125 -{ 7.126 - while(sel) { 7.127 - resize(sel, True); 7.128 - unmanage(sel); 7.129 - } 7.130 - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 7.131 -} 7.132 - 7.133 -void 7.134 -quit(Arg *arg) 7.135 -{ 7.136 - running = False; 7.137 + ee->request_code, ee->error_code); 7.138 + return xerrorxlib(dpy, ee); /* may call exit() */ 7.139 } 7.140 7.141 int 7.142 @@ -208,23 +208,23 @@ 7.143 7.144 dpy = XOpenDisplay(0); 7.145 if(!dpy) 7.146 - error("dwm: cannot connect X server\n"); 7.147 + eprint("dwm: cannot connect X server\n"); 7.148 7.149 screen = DefaultScreen(dpy); 7.150 root = RootWindow(dpy, screen); 7.151 7.152 /* check if another WM is already running */ 7.153 - other_wm_running = False; 7.154 - XSetErrorHandler(startup_xerror); 7.155 + otherwm = False; 7.156 + XSetErrorHandler(xerrorstart); 7.157 /* this causes an error if some other WM is running */ 7.158 XSelectInput(dpy, root, SubstructureRedirectMask); 7.159 XFlush(dpy); 7.160 7.161 - if(other_wm_running) 7.162 - error("dwm: another window manager is already running\n"); 7.163 + if(otherwm) 7.164 + eprint("dwm: another window manager is already running\n"); 7.165 7.166 XSetErrorHandler(0); 7.167 - x_xerror = XSetErrorHandler(xerror); 7.168 + xerrorxlib = XSetErrorHandler(xerror); 7.169 7.170 /* init atoms */ 7.171 wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); 7.172 @@ -278,7 +278,7 @@ 7.173 XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); 7.174 7.175 strcpy(stext, "dwm-"VERSION); 7.176 - scan_wins(); 7.177 + scan(); 7.178 7.179 /* main event loop, reads status text from stdin as well */ 7.180 Mainloop: 7.181 @@ -292,7 +292,7 @@ 7.182 if(i == -1 && errno == EINTR) 7.183 continue; 7.184 if(i < 0) 7.185 - error("select failed\n"); 7.186 + eprint("select failed\n"); 7.187 else if(i > 0) { 7.188 if(FD_ISSET(ConnectionNumber(dpy), &rd)) { 7.189 while(XPending(dpy)) {
8.1 --- a/screen.c Fri Jul 14 22:54:09 2006 +0200 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,100 +0,0 @@ 8.4 -/* 8.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 8.6 - * See LICENSE file for license details. 8.7 - */ 8.8 - 8.9 -#include "dwm.h" 8.10 - 8.11 -void (*arrange)(Arg *) = tiling; 8.12 - 8.13 -void 8.14 -view(Arg *arg) 8.15 -{ 8.16 - Client *c; 8.17 - 8.18 - tsel = arg->i; 8.19 - arrange(NULL); 8.20 - 8.21 - for(c = clients; c; c = getnext(c->next)) 8.22 - drawtitle(c); 8.23 - drawstatus(); 8.24 -} 8.25 - 8.26 -void 8.27 -floating(Arg *arg) 8.28 -{ 8.29 - Client *c; 8.30 - 8.31 - arrange = floating; 8.32 - for(c = clients; c; c = c->next) { 8.33 - if(c->tags[tsel]) 8.34 - resize(c, True); 8.35 - else 8.36 - ban(c); 8.37 - } 8.38 - if(sel && !sel->tags[tsel]) { 8.39 - if((sel = getnext(clients))) { 8.40 - higher(sel); 8.41 - focus(sel); 8.42 - } 8.43 - } 8.44 - drawstatus(); 8.45 -} 8.46 - 8.47 -void 8.48 -tiling(Arg *arg) 8.49 -{ 8.50 - Client *c; 8.51 - int n, i, w, h; 8.52 - 8.53 - w = sw - mw; 8.54 - arrange = tiling; 8.55 - for(n = 0, c = clients; c; c = c->next) 8.56 - if(c->tags[tsel] && !c->floating) 8.57 - n++; 8.58 - 8.59 - if(n > 1) 8.60 - h = (sh - bh) / (n - 1); 8.61 - else 8.62 - h = sh - bh; 8.63 - 8.64 - for(i = 0, c = clients; c; c = c->next) { 8.65 - if(c->tags[tsel]) { 8.66 - if(c->floating) { 8.67 - higher(c); 8.68 - resize(c, True); 8.69 - continue; 8.70 - } 8.71 - if(n == 1) { 8.72 - c->x = sx; 8.73 - c->y = sy + bh; 8.74 - c->w = sw - 2 * c->border; 8.75 - c->h = sh - 2 * c->border - bh; 8.76 - } 8.77 - else if(i == 0) { 8.78 - c->x = sx; 8.79 - c->y = sy + bh; 8.80 - c->w = mw - 2 * c->border; 8.81 - c->h = sh - 2 * c->border - bh; 8.82 - } 8.83 - else { 8.84 - c->x = sx + mw; 8.85 - c->y = sy + (i - 1) * h + bh; 8.86 - c->w = w - 2 * c->border; 8.87 - c->h = h - 2 * c->border; 8.88 - } 8.89 - resize(c, False); 8.90 - i++; 8.91 - } 8.92 - else 8.93 - ban(c); 8.94 - } 8.95 - if(!sel || (sel && !sel->tags[tsel])) { 8.96 - if((sel = getnext(clients))) { 8.97 - higher(sel); 8.98 - focus(sel); 8.99 - } 8.100 - } 8.101 - drawstatus(); 8.102 -} 8.103 -
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tag.c Sat Jul 15 16:30:50 2006 +0200 9.3 @@ -0,0 +1,171 @@ 9.4 +/* 9.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 9.6 + * See LICENSE file for license details. 9.7 + */ 9.8 + 9.9 +#include <stdlib.h> 9.10 +#include <stdio.h> 9.11 +#include <string.h> 9.12 +#include <X11/Xatom.h> 9.13 +#include <X11/Xutil.h> 9.14 + 9.15 +#include "dwm.h" 9.16 + 9.17 +static Rule rule[] = { 9.18 + /* class instance tags dofloat */ 9.19 + { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, 9.20 +}; 9.21 + 9.22 +void (*arrange)(Arg *) = dotile; 9.23 + 9.24 +Client * 9.25 +getnext(Client *c) 9.26 +{ 9.27 + for(; c && !c->tags[tsel]; c = c->next); 9.28 + return c; 9.29 +} 9.30 + 9.31 +void 9.32 +settags(Client *c) 9.33 +{ 9.34 + XClassHint ch; 9.35 + static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; 9.36 + unsigned int i, j; 9.37 + Bool matched = False; 9.38 + 9.39 + if(!len) { 9.40 + c->tags[tsel] = tags[tsel]; 9.41 + return; 9.42 + } 9.43 + 9.44 + if(XGetClassHint(dpy, c->win, &ch)) { 9.45 + if(ch.res_class && ch.res_name) { 9.46 + for(i = 0; i < len; i++) 9.47 + if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) 9.48 + && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) 9.49 + { 9.50 + for(j = 0; j < TLast; j++) 9.51 + c->tags[j] = rule[i].tags[j]; 9.52 + c->dofloat = rule[i].dofloat; 9.53 + matched = True; 9.54 + break; 9.55 + } 9.56 + } 9.57 + if(ch.res_class) 9.58 + XFree(ch.res_class); 9.59 + if(ch.res_name) 9.60 + XFree(ch.res_name); 9.61 + } 9.62 + 9.63 + if(!matched) 9.64 + c->tags[tsel] = tags[tsel]; 9.65 +} 9.66 + 9.67 +void 9.68 +view(Arg *arg) 9.69 +{ 9.70 + tsel = arg->i; 9.71 + arrange(NULL); 9.72 + drawall(); 9.73 +} 9.74 + 9.75 +void 9.76 +dofloat(Arg *arg) 9.77 +{ 9.78 + Client *c; 9.79 + 9.80 + arrange = dofloat; 9.81 + for(c = clients; c; c = c->next) { 9.82 + if(c->tags[tsel]) 9.83 + resize(c, True); 9.84 + else 9.85 + ban(c); 9.86 + } 9.87 + if(sel && !sel->tags[tsel]) { 9.88 + if((sel = getnext(clients))) { 9.89 + higher(sel); 9.90 + focus(sel); 9.91 + } 9.92 + } 9.93 + drawall(); 9.94 +} 9.95 + 9.96 +void 9.97 +dotile(Arg *arg) 9.98 +{ 9.99 + Client *c; 9.100 + int n, i, w, h; 9.101 + 9.102 + w = sw - mw; 9.103 + arrange = dotile; 9.104 + for(n = 0, c = clients; c; c = c->next) 9.105 + if(c->tags[tsel] && !c->dofloat) 9.106 + n++; 9.107 + 9.108 + if(n > 1) 9.109 + h = (sh - bh) / (n - 1); 9.110 + else 9.111 + h = sh - bh; 9.112 + 9.113 + for(i = 0, c = clients; c; c = c->next) { 9.114 + if(c->tags[tsel]) { 9.115 + if(c->dofloat) { 9.116 + higher(c); 9.117 + resize(c, True); 9.118 + continue; 9.119 + } 9.120 + if(n == 1) { 9.121 + c->x = sx; 9.122 + c->y = sy + bh; 9.123 + c->w = sw - 2 * c->border; 9.124 + c->h = sh - 2 * c->border - bh; 9.125 + } 9.126 + else if(i == 0) { 9.127 + c->x = sx; 9.128 + c->y = sy + bh; 9.129 + c->w = mw - 2 * c->border; 9.130 + c->h = sh - 2 * c->border - bh; 9.131 + } 9.132 + else { 9.133 + c->x = sx + mw; 9.134 + c->y = sy + (i - 1) * h + bh; 9.135 + c->w = w - 2 * c->border; 9.136 + c->h = h - 2 * c->border; 9.137 + } 9.138 + resize(c, False); 9.139 + i++; 9.140 + } 9.141 + else 9.142 + ban(c); 9.143 + } 9.144 + if(!sel || (sel && !sel->tags[tsel])) { 9.145 + if((sel = getnext(clients))) { 9.146 + higher(sel); 9.147 + focus(sel); 9.148 + } 9.149 + } 9.150 + drawall(); 9.151 +} 9.152 + 9.153 +void 9.154 +appendtag(Arg *arg) 9.155 +{ 9.156 + if(!sel) 9.157 + return; 9.158 + 9.159 + sel->tags[arg->i] = tags[arg->i]; 9.160 + arrange(NULL); 9.161 +} 9.162 + 9.163 +void 9.164 +replacetag(Arg *arg) 9.165 +{ 9.166 + int i; 9.167 + if(!sel) 9.168 + return; 9.169 + 9.170 + for(i = 0; i < TLast; i++) 9.171 + sel->tags[i] = NULL; 9.172 + appendtag(arg); 9.173 +} 9.174 +
10.1 --- a/util.c Fri Jul 14 22:54:09 2006 +0200 10.2 +++ b/util.c Sat Jul 15 16:30:50 2006 +0200 10.3 @@ -13,7 +13,7 @@ 10.4 #include "dwm.h" 10.5 10.6 void 10.7 -error(const char *errstr, ...) { 10.8 +eprint(const char *errstr, ...) { 10.9 va_list ap; 10.10 va_start(ap, errstr); 10.11 vfprintf(stderr, errstr, ap);