trearranged several stuff - dwm - [fork] customized build of dwm, the dynamic w… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit dba23062bad40afb1a90f60b6897cf9e1ca5035b | |
parent c0705eeb65733e8c5091e47d5bdc701a0779a949 | |
Author: Anselm R. Garbe <[email protected]> | |
Date: Sat, 15 Jul 2006 16:30:50 +0200 | |
rearranged several stuff | |
Diffstat: | |
M Makefile | 2 +- | |
M client.c | 145 +++++++++++++++++++----------… | |
M draw.c | 37 ++++++++++++++++++++---------… | |
M dwm.h | 36 +++++++++++++++++++----------… | |
M event.c | 89 +++++++++++++++++++++++++++--… | |
D key.c | 192 -----------------------------… | |
M main.c | 112 ++++++++++++++++-------------… | |
D screen.c | 100 -----------------------------… | |
A tag.c | 171 +++++++++++++++++++++++++++++… | |
M util.c | 2 +- | |
10 files changed, 442 insertions(+), 444 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
t@@ -3,7 +3,7 @@ | |
include config.mk | |
-SRC = client.c draw.c event.c key.c main.c screen.c util.c | |
+SRC = client.c draw.c event.c main.c tag.c util.c | |
OBJ = ${SRC:.c=.o} | |
MAN1 = dwm.1 | |
BIN = dwm | |
diff --git a/client.c b/client.c | |
t@@ -11,18 +11,6 @@ | |
#include "dwm.h" | |
-static Rule rule[] = { | |
- /* class instance tags … | |
- { "Firefox-bin", "Gecko", { [Twww] = "www" }, … | |
-}; | |
- | |
-Client * | |
-getnext(Client *c) | |
-{ | |
- for(; c && !c->tags[tsel]; c = c->next); | |
- return c; | |
-} | |
- | |
void | |
ban(Client *c) | |
{ | |
t@@ -31,7 +19,7 @@ ban(Client *c) | |
} | |
static void | |
-resize_title(Client *c) | |
+resizetitle(Client *c) | |
{ | |
int i; | |
t@@ -72,7 +60,7 @@ settitle(Client *c) | |
} | |
} | |
XFree(name.value); | |
- resize_title(c); | |
+ resizetitle(c); | |
} | |
void | |
t@@ -143,42 +131,6 @@ focus(Client *c) | |
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | |
} | |
-static void | |
-init_tags(Client *c) | |
-{ | |
- XClassHint ch; | |
- static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; | |
- unsigned int i, j; | |
- Bool matched = False; | |
- | |
- if(!len) { | |
- c->tags[tsel] = tags[tsel]; | |
- return; | |
- } | |
- | |
- if(XGetClassHint(dpy, c->win, &ch)) { | |
- if(ch.res_class && ch.res_name) { | |
- for(i = 0; i < len; i++) | |
- if(!strncmp(rule[i].class, ch.res_class, sizeo… | |
- && !strncmp(rule[i].instance, ch.res_n… | |
- { | |
- for(j = 0; j < TLast; j++) | |
- c->tags[j] = rule[i].tags[j]; | |
- c->floating = rule[i].floating; | |
- matched = True; | |
- break; | |
- } | |
- } | |
- if(ch.res_class) | |
- XFree(ch.res_class); | |
- if(ch.res_name) | |
- XFree(ch.res_name); | |
- } | |
- | |
- if(!matched) | |
- c->tags[tsel] = tags[tsel]; | |
-} | |
- | |
void | |
manage(Window w, XWindowAttributes *wa) | |
{ | |
t@@ -196,7 +148,7 @@ manage(Window w, XWindowAttributes *wa) | |
c->h = wa->height; | |
c->th = bh; | |
c->border = 1; | |
- c->proto = proto(c->win); | |
+ c->proto = getproto(c->win); | |
setsize(c); | |
XSelectInput(dpy, c->win, | |
StructureNotifyMask | PropertyChangeMask | EnterWindow… | |
t@@ -211,7 +163,7 @@ manage(Window w, XWindowAttributes *wa) | |
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | |
settitle(c); | |
- init_tags(c); | |
+ settags(c); | |
for(l = &clients; *l; l = &(*l)->next); | |
c->next = *l; /* *l == nil */ | |
t@@ -224,8 +176,8 @@ manage(Window w, XWindowAttributes *wa) | |
XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | |
GrabModeAsync, GrabModeSync, None, None); | |
- if(!c->floating) | |
- c->floating = trans | |
+ if(!c->dofloat) | |
+ c->dofloat = trans | |
|| ((c->maxw == c->minw) && (c->maxh == c->minh)); | |
arrange(NULL); | |
t@@ -321,7 +273,7 @@ resize(Client *c, Bool inc) | |
c->w = c->maxw; | |
if(c->maxh && c->h > c->maxh) | |
c->h = c->maxh; | |
- resize_title(c); | |
+ resizetitle(c); | |
XSetWindowBorderWidth(dpy, c->win, 1); | |
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | |
e.type = ConfigureNotify; | |
t@@ -339,7 +291,7 @@ resize(Client *c, Bool inc) | |
} | |
static int | |
-dummy_xerror(Display *dsply, XErrorEvent *err) | |
+xerrordummy(Display *dsply, XErrorEvent *ee) | |
{ | |
return 0; | |
} | |
t@@ -350,7 +302,7 @@ unmanage(Client *c) | |
Client **l; | |
XGrabServer(dpy); | |
- XSetErrorHandler(dummy_xerror); | |
+ XSetErrorHandler(xerrordummy); | |
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | |
XDestroyWindow(dpy, c->title); | |
t@@ -374,7 +326,7 @@ unmanage(Client *c) | |
} | |
Client * | |
-gettitle(Window w) | |
+getctitle(Window w) | |
{ | |
Client *c; | |
for(c = clients; c; c = c->next) | |
t@@ -392,3 +344,80 @@ getclient(Window w) | |
return c; | |
return NULL; | |
} | |
+ | |
+void | |
+zoom(Arg *arg) | |
+{ | |
+ Client **l, *c; | |
+ | |
+ if(!sel) | |
+ return; | |
+ | |
+ if(sel == getnext(clients) && sel->next) { | |
+ if((c = getnext(sel->next))) | |
+ sel = c; | |
+ } | |
+ | |
+ for(l = &clients; *l && *l != sel; l = &(*l)->next); | |
+ *l = sel->next; | |
+ | |
+ sel->next = clients; /* pop */ | |
+ clients = sel; | |
+ arrange(NULL); | |
+ focus(sel); | |
+} | |
+ | |
+void | |
+maximize(Arg *arg) | |
+{ | |
+ if(!sel) | |
+ return; | |
+ sel->x = sx; | |
+ sel->y = sy + bh; | |
+ sel->w = sw - 2 * sel->border; | |
+ sel->h = sh - 2 * sel->border - bh; | |
+ higher(sel); | |
+ resize(sel, False); | |
+} | |
+ | |
+void | |
+focusprev(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ if(!sel) | |
+ return; | |
+ | |
+ if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
+ higher(c); | |
+ focus(c); | |
+ } | |
+} | |
+ | |
+void | |
+focusnext(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ if(!sel) | |
+ return; | |
+ | |
+ if(!(c = getnext(sel->next))) | |
+ c = getnext(clients); | |
+ if(c) { | |
+ higher(c); | |
+ c->revert = sel; | |
+ focus(c); | |
+ } | |
+} | |
+ | |
+void | |
+killclient(Arg *arg) | |
+{ | |
+ if(!sel) | |
+ return; | |
+ if(sel->proto & WM_PROTOCOL_DELWIN) | |
+ sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
+ else | |
+ XKillClient(dpy, sel->win); | |
+} | |
diff --git a/draw.c b/draw.c | |
t@@ -11,33 +11,42 @@ | |
#include "dwm.h" | |
void | |
+drawall() | |
+{ | |
+ Client *c; | |
+ | |
+ for(c = clients; c; c = getnext(c->next)) | |
+ drawtitle(c); | |
+ drawstatus(); | |
+} | |
+ | |
+void | |
drawstatus() | |
{ | |
int i; | |
+ Bool istile = arrange == dotile; | |
dc.x = dc.y = 0; | |
dc.w = bw; | |
- drawtext(NULL, False, False); | |
+ drawtext(NULL, !istile, False); | |
- if(arrange == floating) { | |
- dc.w = textw("~"); | |
- drawtext("~", False, False); | |
- } | |
- else | |
- dc.w = 0; | |
+ dc.w = 0; | |
for(i = 0; i < TLast; i++) { | |
dc.x += dc.w; | |
dc.w = textw(tags[i]); | |
- drawtext(tags[i], i == tsel, True); | |
+ if(istile) | |
+ drawtext(tags[i], (i == tsel), True); | |
+ else | |
+ drawtext(tags[i], (i != tsel), True); | |
} | |
if(sel) { | |
dc.x += dc.w; | |
dc.w = textw(sel->name); | |
- drawtext(sel->name, True, True); | |
+ drawtext(sel->name, istile, True); | |
} | |
dc.w = textw(stext); | |
dc.x = bx + bw - dc.w; | |
- drawtext(stext, False, False); | |
+ drawtext(stext, !istile, False); | |
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); | |
XFlush(dpy); | |
t@@ -47,6 +56,8 @@ void | |
drawtitle(Client *c) | |
{ | |
int i; | |
+ Bool istile = arrange == dotile; | |
+ | |
if(c == sel) { | |
drawstatus(); | |
XUnmapWindow(dpy, c->title); | |
t@@ -64,12 +75,12 @@ drawtitle(Client *c) | |
if(c->tags[i]) { | |
dc.x += dc.w; | |
dc.w = textw(c->tags[i]); | |
- drawtext(c->tags[i], False, True); | |
+ drawtext(c->tags[i], !istile, True); | |
} | |
} | |
dc.x += dc.w; | |
dc.w = textw(c->name); | |
- drawtext(c->name, False, True); | |
+ drawtext(c->name, !istile, True); | |
XCopyArea(dpy, dc.drawable, c->title, dc.gc, | |
0, 0, c->tw, c->th, 0, 0); | |
XFlush(dpy); | |
t@@ -215,7 +226,7 @@ setfont(const char *fontstr) | |
if (!dc.font.xfont) | |
dc.font.xfont = XLoadQueryFont(dpy, "fixed"); | |
if (!dc.font.xfont) | |
- error("error, cannot init 'fixed' font\n"); | |
+ eprint("error, cannot init 'fixed' font\n"); | |
dc.font.ascent = dc.font.xfont->ascent; | |
dc.font.descent = dc.font.xfont->descent; | |
} | |
diff --git a/dwm.h b/dwm.h | |
t@@ -66,7 +66,7 @@ struct Client { | |
int grav; | |
unsigned int border; | |
long flags; | |
- Bool floating; | |
+ Bool dofloat; | |
Window win; | |
Window title; | |
Client *next; | |
t@@ -77,7 +77,7 @@ struct Rule { | |
const char *class; | |
const char *instance; | |
char *tags[TLast]; | |
- Bool floating; | |
+ Bool dofloat; | |
}; | |
struct Key { | |
t@@ -103,6 +103,7 @@ extern DC dc; | |
extern Client *clients, *sel; | |
/* client.c */ | |
+extern void ban(Client *c); | |
extern void manage(Window w, XWindowAttributes *wa); | |
extern void unmanage(Client *c); | |
extern Client *getclient(Window w); | |
t@@ -110,14 +111,18 @@ extern void focus(Client *c); | |
extern void settitle(Client *c); | |
extern void resize(Client *c, Bool inc); | |
extern void setsize(Client *c); | |
-extern Client *gettitle(Window w); | |
+extern Client *getctitle(Window w); | |
extern void higher(Client *c); | |
extern void lower(Client *c); | |
extern void gravitate(Client *c, Bool invert); | |
-extern void ban(Client *c); | |
-extern Client *getnext(Client *c); | |
+extern void zoom(Arg *arg); | |
+extern void maximize(Arg *arg); | |
+extern void focusprev(Arg *arg); | |
+extern void focusnext(Arg *arg); | |
+extern void killclient(Arg *arg); | |
/* draw.c */ | |
+extern void drawall(); | |
extern void drawstatus(); | |
extern void drawtitle(Client *c); | |
extern void drawtext(const char *text, Bool invert, Bool border); | |
t@@ -127,22 +132,25 @@ extern unsigned int textnw(char *text, unsigned int len); | |
extern unsigned int textw(char *text); | |
extern unsigned int texth(void); | |
-/* key.c */ | |
+/* event.c */ | |
extern void grabkeys(); | |
-extern void keypress(XEvent *e); | |
/* main.c */ | |
-extern int xerror(Display *dsply, XErrorEvent *e); | |
-extern void sendevent(Window w, Atom a, long value); | |
-extern int proto(Window w); | |
extern void quit(Arg *arg); | |
+extern int xerror(Display *dsply, XErrorEvent *ee); | |
+extern void sendevent(Window w, Atom a, long value); | |
+extern int getproto(Window w); | |
-/* screen.c */ | |
-extern void floating(Arg *arg); | |
-extern void tiling(Arg *arg); | |
+/* tag.c */ | |
+extern Client *getnext(Client *c); | |
+extern void settags(Client *c); | |
+extern void dofloat(Arg *arg); | |
+extern void dotile(Arg *arg); | |
extern void view(Arg *arg); | |
+extern void appendtag(Arg *arg); | |
+extern void replacetag(Arg *arg); | |
/* util.c */ | |
-extern void error(const char *errstr, ...); | |
+extern void eprint(const char *errstr, ...); | |
extern void *emallocz(unsigned int size); | |
extern void spawn(Arg *arg); | |
diff --git a/event.c b/event.c | |
t@@ -16,6 +16,44 @@ | |
#define ButtonMask (ButtonPressMask | ButtonReleaseMask) | |
#define MouseMask (ButtonMask | PointerMotionMask) | |
+/********** CUSTOMIZE **********/ | |
+ | |
+const char *term[] = { | |
+ "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", | |
+ "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL | |
+}; | |
+const char *browse[] = { "firefox", NULL }; | |
+const char *xlock[] = { "xlock", NULL }; | |
+ | |
+Key key[] = { | |
+ /* modifier key … | |
+ { Mod1Mask, XK_Return, zoom, … | |
+ { Mod1Mask, XK_k, focusp… | |
+ { Mod1Mask, XK_j, focusn… | |
+ { Mod1Mask, XK_m, maximi… | |
+ { Mod1Mask, XK_0, view, … | |
+ { Mod1Mask, XK_1, view, … | |
+ { Mod1Mask, XK_2, view, … | |
+ { Mod1Mask, XK_3, view, … | |
+ { Mod1Mask, XK_space, dotile, … | |
+ { Mod1Mask|ShiftMask, XK_space, dofloat, { 0 } }, | |
+ { Mod1Mask|ShiftMask, XK_0, replacetag, … | |
+ { Mod1Mask|ShiftMask, XK_1, replacetag, … | |
+ { Mod1Mask|ShiftMask, XK_2, replacetag, … | |
+ { Mod1Mask|ShiftMask, XK_3, replacetag, … | |
+ { Mod1Mask|ShiftMask, XK_c, killclient, … | |
+ { Mod1Mask|ShiftMask, XK_q, quit, … | |
+ { Mod1Mask|ShiftMask, XK_Return, spawn, {… | |
+ { Mod1Mask|ShiftMask, XK_w, spawn, … | |
+ { Mod1Mask|ShiftMask, XK_l, spawn, … | |
+ { ControlMask, XK_0, appendtag, … | |
+ { ControlMask, XK_1, appendtag, … | |
+ { ControlMask, XK_2, appendtag, … | |
+ { ControlMask, XK_3, appendtag, … | |
+}; | |
+ | |
+/********** CUSTOMIZE **********/ | |
+ | |
/* local functions */ | |
static void buttonpress(XEvent *e); | |
static void configurerequest(XEvent *e); | |
t@@ -23,6 +61,7 @@ static void destroynotify(XEvent *e); | |
static void enternotify(XEvent *e); | |
static void leavenotify(XEvent *e); | |
static void expose(XEvent *e); | |
+static void keypress(XEvent *e); | |
static void maprequest(XEvent *e); | |
static void propertynotify(XEvent *e); | |
static void unmapnotify(XEvent *e); | |
t@@ -40,8 +79,40 @@ void (*handler[LASTEvent]) (XEvent *) = { | |
[UnmapNotify] = unmapnotify | |
}; | |
+void | |
+grabkeys() | |
+{ | |
+ static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
+ unsigned int i; | |
+ KeyCode code; | |
+ | |
+ for(i = 0; i < len; i++) { | |
+ code = XKeysymToKeycode(dpy, key[i].keysym); | |
+ XUngrabKey(dpy, code, key[i].mod, root); | |
+ XGrabKey(dpy, code, key[i].mod, root, True, | |
+ GrabModeAsync, GrabModeAsync); | |
+ } | |
+} | |
+ | |
+static void | |
+keypress(XEvent *e) | |
+{ | |
+ XKeyEvent *ev = &e->xkey; | |
+ static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
+ unsigned int i; | |
+ KeySym keysym; | |
+ | |
+ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | |
+ for(i = 0; i < len; i++) | |
+ if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | |
+ if(key[i].func) | |
+ key[i].func(&key[i].arg); | |
+ return; | |
+ } | |
+} | |
+ | |
static void | |
-mresize(Client *c) | |
+resizemouse(Client *c) | |
{ | |
XEvent ev; | |
int ocx, ocy; | |
t@@ -75,7 +146,7 @@ mresize(Client *c) | |
} | |
static void | |
-mmove(Client *c) | |
+movemouse(Client *c) | |
{ | |
XEvent ev; | |
int x1, y1, ocx, ocy, di; | |
t@@ -117,7 +188,7 @@ buttonpress(XEvent *e) | |
Client *c; | |
if(barwin == ev->window) { | |
- x = (arrange == floating) ? textw("~") : 0; | |
+ x = (arrange == dofloat) ? textw("~") : 0; | |
for(a.i = 0; a.i < TLast; a.i++) { | |
x += textw(tags[a.i]); | |
if(ev->x < x) { | |
t@@ -127,20 +198,20 @@ buttonpress(XEvent *e) | |
} | |
} | |
else if((c = getclient(ev->window))) { | |
- if(arrange == tiling && !c->floating) | |
+ if(arrange == dotile && !c->dofloat) | |
return; | |
higher(c); | |
switch(ev->button) { | |
default: | |
break; | |
case Button1: | |
- mmove(c); | |
+ movemouse(c); | |
break; | |
case Button2: | |
lower(c); | |
break; | |
case Button3: | |
- mresize(c); | |
+ resizemouse(c); | |
break; | |
} | |
} | |
t@@ -226,7 +297,7 @@ expose(XEvent *e) | |
if(ev->count == 0) { | |
if(barwin == ev->window) | |
drawstatus(); | |
- else if((c = gettitle(ev->window))) | |
+ else if((c = getctitle(ev->window))) | |
drawtitle(c); | |
} | |
} | |
t@@ -262,14 +333,14 @@ propertynotify(XEvent *e) | |
if((c = getclient(ev->window))) { | |
if(ev->atom == wm_atom[WMProtocols]) { | |
- c->proto = proto(c->win); | |
+ c->proto = getproto(c->win); | |
return; | |
} | |
switch (ev->atom) { | |
default: break; | |
case XA_WM_TRANSIENT_FOR: | |
XGetTransientForHint(dpy, c->win, &trans); | |
- if(!c->floating && (c->floating = (trans != 0)… | |
+ if(!c->dofloat && (c->dofloat = (trans != 0))) | |
arrange(NULL); | |
break; | |
case XA_WM_NORMAL_HINTS: | |
diff --git a/key.c b/key.c | |
t@@ -1,192 +0,0 @@ | |
-/* | |
- * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
- * See LICENSE file for license details. | |
- */ | |
- | |
-#include <fcntl.h> | |
-#include <stdio.h> | |
-#include <stdlib.h> | |
-#include <string.h> | |
-#include <unistd.h> | |
-#include <X11/keysym.h> | |
-#include <X11/Xatom.h> | |
- | |
-#include "dwm.h" | |
- | |
-static void ckill(Arg *arg); | |
-static void nextc(Arg *arg); | |
-static void prevc(Arg *arg); | |
-static void max(Arg *arg); | |
-static void ttrunc(Arg *arg); | |
-static void tappend(Arg *arg); | |
-static void zoom(Arg *arg); | |
- | |
-/********** CUSTOMIZE **********/ | |
- | |
-const char *term[] = { | |
- "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", | |
- "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL | |
-}; | |
-const char *browse[] = { "firefox", NULL }; | |
-const char *xlock[] = { "xlock", NULL }; | |
- | |
-Key key[] = { | |
- /* modifier key … | |
- { Mod1Mask, XK_Return, zoom, … | |
- { Mod1Mask, XK_k, prevc,… | |
- { Mod1Mask, XK_j, nextc,… | |
- { Mod1Mask, XK_m, max, … | |
- { Mod1Mask, XK_0, view, … | |
- { Mod1Mask, XK_1, view, … | |
- { Mod1Mask, XK_2, view, … | |
- { Mod1Mask, XK_3, view, … | |
- { Mod1Mask, XK_space, tiling, … | |
- { Mod1Mask|ShiftMask, XK_space, floating, { 0 } }… | |
- { Mod1Mask|ShiftMask, XK_0, ttrunc, … | |
- { Mod1Mask|ShiftMask, XK_1, ttrunc, … | |
- { Mod1Mask|ShiftMask, XK_2, ttrunc, … | |
- { Mod1Mask|ShiftMask, XK_3, ttrunc, … | |
- { Mod1Mask|ShiftMask, XK_c, ckill, … | |
- { Mod1Mask|ShiftMask, XK_q, quit, … | |
- { Mod1Mask|ShiftMask, XK_Return, spawn, {… | |
- { Mod1Mask|ShiftMask, XK_w, spawn, … | |
- { Mod1Mask|ShiftMask, XK_l, spawn, … | |
- { ControlMask, XK_0, tappend, … | |
- { ControlMask, XK_1, tappend, … | |
- { ControlMask, XK_2, tappend, … | |
- { ControlMask, XK_3, tappend, … | |
-}; | |
- | |
-/********** CUSTOMIZE **********/ | |
- | |
-void | |
-grabkeys() | |
-{ | |
- static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
- unsigned int i; | |
- KeyCode code; | |
- | |
- for(i = 0; i < len; i++) { | |
- code = XKeysymToKeycode(dpy, key[i].keysym); | |
- XUngrabKey(dpy, code, key[i].mod, root); | |
- XGrabKey(dpy, code, key[i].mod, root, True, | |
- GrabModeAsync, GrabModeAsync); | |
- } | |
-} | |
- | |
-void | |
-keypress(XEvent *e) | |
-{ | |
- XKeyEvent *ev = &e->xkey; | |
- static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | |
- unsigned int i; | |
- KeySym keysym; | |
- | |
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | |
- for(i = 0; i < len; i++) | |
- if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | |
- if(key[i].func) | |
- key[i].func(&key[i].arg); | |
- return; | |
- } | |
-} | |
- | |
-static void | |
-zoom(Arg *arg) | |
-{ | |
- Client **l, *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if(sel == getnext(clients) && sel->next) { | |
- if((c = getnext(sel->next))) | |
- sel = c; | |
- } | |
- | |
- for(l = &clients; *l && *l != sel; l = &(*l)->next); | |
- *l = sel->next; | |
- | |
- sel->next = clients; /* pop */ | |
- clients = sel; | |
- arrange(NULL); | |
- focus(sel); | |
-} | |
- | |
-static void | |
-max(Arg *arg) | |
-{ | |
- if(!sel) | |
- return; | |
- sel->x = sx; | |
- sel->y = sy + bh; | |
- sel->w = sw - 2 * sel->border; | |
- sel->h = sh - 2 * sel->border - bh; | |
- higher(sel); | |
- resize(sel, False); | |
-} | |
- | |
-static void | |
-tappend(Arg *arg) | |
-{ | |
- if(!sel) | |
- return; | |
- | |
- sel->tags[arg->i] = tags[arg->i]; | |
- arrange(NULL); | |
-} | |
- | |
-static void | |
-ttrunc(Arg *arg) | |
-{ | |
- int i; | |
- if(!sel) | |
- return; | |
- | |
- for(i = 0; i < TLast; i++) | |
- sel->tags[i] = NULL; | |
- tappend(arg); | |
-} | |
- | |
-static void | |
-prevc(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
- higher(c); | |
- focus(c); | |
- } | |
-} | |
- | |
-static void | |
-nextc(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if(!(c = getnext(sel->next))) | |
- c = getnext(clients); | |
- if(c) { | |
- higher(c); | |
- c->revert = sel; | |
- focus(c); | |
- } | |
-} | |
- | |
-static void | |
-ckill(Arg *arg) | |
-{ | |
- if(!sel) | |
- return; | |
- if(sel->proto & WM_PROTOCOL_DELWIN) | |
- sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
- else | |
- XKillClient(dpy, sel->win); | |
-} | |
- | |
diff --git a/main.c b/main.c | |
t@@ -43,16 +43,16 @@ DC dc = {0}; | |
Client *clients = NULL; | |
Client *sel = NULL; | |
-static Bool other_wm_running; | |
+static Bool otherwm; | |
static const char version[] = | |
"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | |
-static int (*x_xerror) (Display *, XErrorEvent *); | |
+static int (*xerrorxlib)(Display *, XErrorEvent *); | |
static void | |
-usage() { error("usage: dwm [-v]\n"); } | |
+usage() { eprint("usage: dwm [-v]\n"); } | |
static void | |
-scan_wins() | |
+scan() | |
{ | |
unsigned int i, num; | |
Window *wins; | |
t@@ -73,6 +73,22 @@ scan_wins() | |
XFree(wins); | |
} | |
+static void | |
+cleanup() | |
+{ | |
+ while(sel) { | |
+ resize(sel, True); | |
+ unmanage(sel); | |
+ } | |
+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | |
+} | |
+ | |
+void | |
+quit(Arg *arg) | |
+{ | |
+ running = False; | |
+} | |
+ | |
static int | |
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) | |
{ | |
t@@ -94,7 +110,7 @@ win_property(Window w, Atom a, Atom t, long l, unsigned cha… | |
} | |
int | |
-proto(Window w) | |
+getproto(Window w) | |
{ | |
unsigned char *protocols; | |
long res; | |
t@@ -129,58 +145,42 @@ sendevent(Window w, Atom a, long value) | |
} | |
/* | |
- * 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 | |
-xerror(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_xerror(dpy, error); /* may call exit() */ | |
-} | |
- | |
-/* | |
* Startup Error handler to check if another window manager | |
* is already running. | |
*/ | |
static int | |
-startup_xerror(Display *dpy, XErrorEvent *error) | |
+xerrorstart(Display *dsply, XErrorEvent *ee) | |
{ | |
- other_wm_running = True; | |
+ otherwm = True; | |
return -1; | |
} | |
-static void | |
-cleanup() | |
-{ | |
- while(sel) { | |
- resize(sel, True); | |
- unmanage(sel); | |
- } | |
- XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | |
-} | |
- | |
-void | |
-quit(Arg *arg) | |
+/* | |
+ * 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 | |
+xerror(Display *dpy, XErrorEvent *ee) | |
{ | |
- running = False; | |
+ if(ee->error_code == BadWindow | |
+ || (ee->request_code == X_SetInputFocus | |
+ && ee->error_code == BadMatch) | |
+ || (ee->request_code == X_PolyText8 | |
+ && ee->error_code == BadDrawable) | |
+ || (ee->request_code == X_PolyFillRectangle | |
+ && ee->error_code == BadDrawable) | |
+ || (ee->request_code == X_PolySegment | |
+ && ee->error_code == BadDrawable) | |
+ || (ee->request_code == X_ConfigureWindow | |
+ && ee->error_code == BadMatch) | |
+ || (ee->request_code == X_GrabKey | |
+ && ee->error_code == BadAccess)) | |
+ return 0; | |
+ fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", | |
+ ee->request_code, ee->error_code); | |
+ return xerrorxlib(dpy, ee); /* may call exit() */ | |
} | |
int | |
t@@ -208,23 +208,23 @@ main(int argc, char *argv[]) | |
dpy = XOpenDisplay(0); | |
if(!dpy) | |
- error("dwm: cannot connect X server\n"); | |
+ eprint("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_xerror); | |
+ otherwm = False; | |
+ XSetErrorHandler(xerrorstart); | |
/* 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"); | |
+ if(otherwm) | |
+ eprint("dwm: another window manager is already running\n"); | |
XSetErrorHandler(0); | |
- x_xerror = XSetErrorHandler(xerror); | |
+ xerrorxlib = XSetErrorHandler(xerror); | |
/* init atoms */ | |
wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | |
t@@ -278,7 +278,7 @@ main(int argc, char *argv[]) | |
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); | |
strcpy(stext, "dwm-"VERSION); | |
- scan_wins(); | |
+ scan(); | |
/* main event loop, reads status text from stdin as well */ | |
Mainloop: | |
t@@ -292,7 +292,7 @@ Mainloop: | |
if(i == -1 && errno == EINTR) | |
continue; | |
if(i < 0) | |
- error("select failed\n"); | |
+ eprint("select failed\n"); | |
else if(i > 0) { | |
if(FD_ISSET(ConnectionNumber(dpy), &rd)) { | |
while(XPending(dpy)) { | |
diff --git a/screen.c b/screen.c | |
t@@ -1,100 +0,0 @@ | |
-/* | |
- * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
- * See LICENSE file for license details. | |
- */ | |
- | |
-#include "dwm.h" | |
- | |
-void (*arrange)(Arg *) = tiling; | |
- | |
-void | |
-view(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- tsel = arg->i; | |
- arrange(NULL); | |
- | |
- for(c = clients; c; c = getnext(c->next)) | |
- drawtitle(c); | |
- drawstatus(); | |
-} | |
- | |
-void | |
-floating(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- arrange = floating; | |
- for(c = clients; c; c = c->next) { | |
- if(c->tags[tsel]) | |
- resize(c, True); | |
- else | |
- ban(c); | |
- } | |
- if(sel && !sel->tags[tsel]) { | |
- if((sel = getnext(clients))) { | |
- higher(sel); | |
- focus(sel); | |
- } | |
- } | |
- drawstatus(); | |
-} | |
- | |
-void | |
-tiling(Arg *arg) | |
-{ | |
- Client *c; | |
- int n, i, w, h; | |
- | |
- w = sw - mw; | |
- arrange = tiling; | |
- for(n = 0, c = clients; c; c = c->next) | |
- if(c->tags[tsel] && !c->floating) | |
- n++; | |
- | |
- if(n > 1) | |
- h = (sh - bh) / (n - 1); | |
- else | |
- h = sh - bh; | |
- | |
- for(i = 0, c = clients; c; c = c->next) { | |
- if(c->tags[tsel]) { | |
- if(c->floating) { | |
- higher(c); | |
- resize(c, True); | |
- continue; | |
- } | |
- if(n == 1) { | |
- c->x = sx; | |
- c->y = sy + bh; | |
- c->w = sw - 2 * c->border; | |
- c->h = sh - 2 * c->border - bh; | |
- } | |
- else if(i == 0) { | |
- c->x = sx; | |
- c->y = sy + bh; | |
- c->w = mw - 2 * c->border; | |
- c->h = sh - 2 * c->border - bh; | |
- } | |
- else { | |
- c->x = sx + mw; | |
- c->y = sy + (i - 1) * h + bh; | |
- c->w = w - 2 * c->border; | |
- c->h = h - 2 * c->border; | |
- } | |
- resize(c, False); | |
- i++; | |
- } | |
- else | |
- ban(c); | |
- } | |
- if(!sel || (sel && !sel->tags[tsel])) { | |
- if((sel = getnext(clients))) { | |
- higher(sel); | |
- focus(sel); | |
- } | |
- } | |
- drawstatus(); | |
-} | |
- | |
diff --git a/tag.c b/tag.c | |
t@@ -0,0 +1,171 @@ | |
+/* | |
+ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
+ * See LICENSE file for license details. | |
+ */ | |
+ | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#include <string.h> | |
+#include <X11/Xatom.h> | |
+#include <X11/Xutil.h> | |
+ | |
+#include "dwm.h" | |
+ | |
+static Rule rule[] = { | |
+ /* class instance tags … | |
+ { "Firefox-bin", "Gecko", { [Twww] = "www" }, … | |
+}; | |
+ | |
+void (*arrange)(Arg *) = dotile; | |
+ | |
+Client * | |
+getnext(Client *c) | |
+{ | |
+ for(; c && !c->tags[tsel]; c = c->next); | |
+ return c; | |
+} | |
+ | |
+void | |
+settags(Client *c) | |
+{ | |
+ XClassHint ch; | |
+ static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; | |
+ unsigned int i, j; | |
+ Bool matched = False; | |
+ | |
+ if(!len) { | |
+ c->tags[tsel] = tags[tsel]; | |
+ return; | |
+ } | |
+ | |
+ if(XGetClassHint(dpy, c->win, &ch)) { | |
+ if(ch.res_class && ch.res_name) { | |
+ for(i = 0; i < len; i++) | |
+ if(!strncmp(rule[i].class, ch.res_class, sizeo… | |
+ && !strncmp(rule[i].instance, ch.res_n… | |
+ { | |
+ for(j = 0; j < TLast; j++) | |
+ c->tags[j] = rule[i].tags[j]; | |
+ c->dofloat = rule[i].dofloat; | |
+ matched = True; | |
+ break; | |
+ } | |
+ } | |
+ if(ch.res_class) | |
+ XFree(ch.res_class); | |
+ if(ch.res_name) | |
+ XFree(ch.res_name); | |
+ } | |
+ | |
+ if(!matched) | |
+ c->tags[tsel] = tags[tsel]; | |
+} | |
+ | |
+void | |
+view(Arg *arg) | |
+{ | |
+ tsel = arg->i; | |
+ arrange(NULL); | |
+ drawall(); | |
+} | |
+ | |
+void | |
+dofloat(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ arrange = dofloat; | |
+ for(c = clients; c; c = c->next) { | |
+ if(c->tags[tsel]) | |
+ resize(c, True); | |
+ else | |
+ ban(c); | |
+ } | |
+ if(sel && !sel->tags[tsel]) { | |
+ if((sel = getnext(clients))) { | |
+ higher(sel); | |
+ focus(sel); | |
+ } | |
+ } | |
+ drawall(); | |
+} | |
+ | |
+void | |
+dotile(Arg *arg) | |
+{ | |
+ Client *c; | |
+ int n, i, w, h; | |
+ | |
+ w = sw - mw; | |
+ arrange = dotile; | |
+ for(n = 0, c = clients; c; c = c->next) | |
+ if(c->tags[tsel] && !c->dofloat) | |
+ n++; | |
+ | |
+ if(n > 1) | |
+ h = (sh - bh) / (n - 1); | |
+ else | |
+ h = sh - bh; | |
+ | |
+ for(i = 0, c = clients; c; c = c->next) { | |
+ if(c->tags[tsel]) { | |
+ if(c->dofloat) { | |
+ higher(c); | |
+ resize(c, True); | |
+ continue; | |
+ } | |
+ if(n == 1) { | |
+ c->x = sx; | |
+ c->y = sy + bh; | |
+ c->w = sw - 2 * c->border; | |
+ c->h = sh - 2 * c->border - bh; | |
+ } | |
+ else if(i == 0) { | |
+ c->x = sx; | |
+ c->y = sy + bh; | |
+ c->w = mw - 2 * c->border; | |
+ c->h = sh - 2 * c->border - bh; | |
+ } | |
+ else { | |
+ c->x = sx + mw; | |
+ c->y = sy + (i - 1) * h + bh; | |
+ c->w = w - 2 * c->border; | |
+ c->h = h - 2 * c->border; | |
+ } | |
+ resize(c, False); | |
+ i++; | |
+ } | |
+ else | |
+ ban(c); | |
+ } | |
+ if(!sel || (sel && !sel->tags[tsel])) { | |
+ if((sel = getnext(clients))) { | |
+ higher(sel); | |
+ focus(sel); | |
+ } | |
+ } | |
+ drawall(); | |
+} | |
+ | |
+void | |
+appendtag(Arg *arg) | |
+{ | |
+ if(!sel) | |
+ return; | |
+ | |
+ sel->tags[arg->i] = tags[arg->i]; | |
+ arrange(NULL); | |
+} | |
+ | |
+void | |
+replacetag(Arg *arg) | |
+{ | |
+ int i; | |
+ if(!sel) | |
+ return; | |
+ | |
+ for(i = 0; i < TLast; i++) | |
+ sel->tags[i] = NULL; | |
+ appendtag(arg); | |
+} | |
+ | |
diff --git a/util.c b/util.c | |
t@@ -13,7 +13,7 @@ | |
#include "dwm.h" | |
void | |
-error(const char *errstr, ...) { | |
+eprint(const char *errstr, ...) { | |
va_list ap; | |
va_start(ap, errstr); | |
vfprintf(stderr, errstr, ap); |