timplemented tagging a client - dwm - [fork] customized build of dwm, the dynam… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c47da143bdf5b4e3924a411f42648d4b3e86ff00 | |
parent b72588746f3d1548283ca98f90961b4f8c2e2800 | |
Author: Anselm R. Garbe <[email protected]> | |
Date: Thu, 13 Jul 2006 17:09:35 +0200 | |
implemented tagging a client | |
Diffstat: | |
M client.c | 170 ++++++++++++++++++++---------… | |
M dev.c | 27 ++++++++++++++++----------- | |
M dwm.h | 30 +++++++++++++++++++----------- | |
M main.c | 11 ++++++----- | |
M util.c | 3 ++- | |
5 files changed, 156 insertions(+), 85 deletions(-) | |
--- | |
diff --git a/client.c b/client.c | |
t@@ -11,44 +11,76 @@ | |
#include "dwm.h" | |
-static void (*arrange)(void *) = floating; | |
+static void (*arrange)(Arg *) = floating; | |
+ | |
+static Client * | |
+next(Client *c) | |
+{ | |
+ for(c = c->next; c && !c->tags[tsel]; c = c->next); | |
+ return c; | |
+} | |
+ | |
+static Client * | |
+prev(Client *c) | |
+{ | |
+ for(c = c->prev; c && !c->tags[tsel]; c = c->prev); | |
+ return c; | |
+} | |
void | |
-max(void *aux) | |
+max(Arg *arg) | |
{ | |
- if(!stack) | |
+ if(!csel) | |
return; | |
- stack->x = sx; | |
- stack->y = sy; | |
- stack->w = sw - 2 * stack->border; | |
- stack->h = sh - 2 * stack->border; | |
- craise(stack); | |
- resize(stack); | |
+ csel->x = sx; | |
+ csel->y = sy; | |
+ csel->w = sw - 2 * csel->border; | |
+ csel->h = sh - 2 * csel->border; | |
+ craise(csel); | |
+ resize(csel); | |
discard_events(EnterWindowMask); | |
} | |
void | |
-floating(void *aux) | |
+tag(Arg *arg) | |
+{ | |
+ if(!csel) | |
+ return; | |
+ | |
+ if(arg->i == tsel) | |
+ return; | |
+ | |
+ if(csel->tags[arg->i]) | |
+ csel->tags[arg->i] = NULL; /* toggle tag */ | |
+ else | |
+ csel->tags[arg->i] = tags[arg->i]; | |
+ arrange(NULL); | |
+} | |
+ | |
+void | |
+floating(Arg *arg) | |
{ | |
Client *c; | |
arrange = floating; | |
- for(c = stack; c; c = c->snext) | |
+ if(!csel) | |
+ return; | |
+ for(c = csel; c; c = next(c)) | |
resize(c); | |
discard_events(EnterWindowMask); | |
} | |
void | |
-tiling(void *aux) | |
+tiling(Arg *arg) | |
{ | |
Client *c; | |
int n, cols, rows, gw, gh, i, j; | |
float rt, fd; | |
arrange = tiling; | |
- if(!clients) | |
+ if(!csel) | |
return; | |
- for(n = 0, c = clients; c; c = c->next, n++); | |
+ for(n = 0, c = csel; c; c = next(c), n++); | |
rt = sqrt(n); | |
if(modff(rt, &fd) < 0.5) | |
rows = floor(rt); | |
t@@ -62,7 +94,7 @@ tiling(void *aux) | |
gw = (sw - 2) / cols; | |
gh = (sh - 2) / rows; | |
- for(i = j = 0, c = clients; c; c = c->next) { | |
+ for(i = j = 0, c = csel; c; c = next(c)) { | |
c->x = i * gw; | |
c->y = j * gh; | |
c->w = gw; | |
t@@ -77,28 +109,44 @@ tiling(void *aux) | |
} | |
void | |
-sel(void *aux) | |
+prevc(Arg *arg) | |
{ | |
- const char *arg = aux; | |
- Client *c = NULL; | |
+ Client *c; | |
- if(!arg || !stack) | |
+ if(!csel) | |
return; | |
- if(!strncmp(arg, "next", 5)) | |
- c = stack->snext ? stack->snext : stack; | |
- else if(!strncmp(arg, "prev", 5)) | |
- for(c = stack; c && c->snext; c = c->snext); | |
- if(!c) | |
- c = stack; | |
- craise(c); | |
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | |
- focus(c); | |
+ | |
+ if(!(c = prev(csel))) | |
+ c = prev(cend); | |
+ if(c) { | |
+ craise(c); | |
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2… | |
+ focus(c); | |
+ } | |
+} | |
+ | |
+void | |
+nextc(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ if(!csel) | |
+ return; | |
+ | |
+ if(!(c = next(csel))) | |
+ c = next(cstart); | |
+ | |
+ if(c) { | |
+ craise(c); | |
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2… | |
+ focus(c); | |
+ } | |
} | |
void | |
-ckill(void *aux) | |
+ckill(Arg *arg) | |
{ | |
- Client *c = stack; | |
+ Client *c = csel; | |
if(!c) | |
return; | |
t@@ -208,19 +256,12 @@ lower(Client *c) | |
void | |
focus(Client *c) | |
{ | |
- Client **l, *old; | |
- | |
- old = stack; | |
- for(l = &stack; *l && *l != c; l = &(*l)->snext); | |
- if(*l) | |
- *l = c->snext; | |
- c->snext = stack; | |
- stack = c; | |
- if(old && old != c) { | |
- XSetWindowBorder(dpy, old->win, dc.bg); | |
- XMapWindow(dpy, old->title); | |
- draw_client(old); | |
+ if(csel && csel != c) { | |
+ XSetWindowBorder(dpy, csel->win, dc.bg); | |
+ XMapWindow(dpy, csel->title); | |
+ draw_client(csel); | |
} | |
+ csel = c; | |
XUnmapWindow(dpy, c->title); | |
XSetWindowBorder(dpy, c->win, dc.fg); | |
draw_client(c); | |
t@@ -232,7 +273,7 @@ focus(Client *c) | |
void | |
manage(Window w, XWindowAttributes *wa) | |
{ | |
- Client *c, **l; | |
+ Client *c; | |
XSetWindowAttributes twa; | |
c = emallocz(sizeof(Client)); | |
t@@ -258,9 +299,15 @@ manage(Window w, XWindowAttributes *wa) | |
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | |
update_name(c); | |
- for(l=&clients; *l; l=&(*l)->next); | |
- c->next = *l; /* *l == nil */ | |
- *l = c; | |
+ | |
+ if(!cstart) | |
+ cstart = cend = c; | |
+ else { | |
+ cend->next = c; | |
+ c->prev = cend; | |
+ cend = c; | |
+ } | |
+ | |
XSetWindowBorderWidth(dpy, c->win, 1); | |
XMapRaised(dpy, c->win); | |
XMapRaised(dpy, c->title); | |
t@@ -373,33 +420,42 @@ dummy_error_handler(Display *dsply, XErrorEvent *err) | |
void | |
unmanage(Client *c) | |
{ | |
- Client **l; | |
- | |
XGrabServer(dpy); | |
XSetErrorHandler(dummy_error_handler); | |
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | |
XDestroyWindow(dpy, c->title); | |
- for(l=&clients; *l && *l != c; l=&(*l)->next); | |
- *l = c->next; | |
- for(l=&stack; *l && *l != c; l=&(*l)->snext); | |
- *l = c->snext; | |
+ if(c->prev) { | |
+ c->prev->next = c->next; | |
+ if(csel == c) | |
+ csel = c->prev; | |
+ } | |
+ if(c->next) { | |
+ c->next->prev = c->prev; | |
+ if(csel == c) | |
+ csel = c->next; | |
+ } | |
+ if(cstart == c) | |
+ cstart = c->next; | |
+ if(cend == c) | |
+ cend = c->prev; | |
+ | |
free(c); | |
XFlush(dpy); | |
XSetErrorHandler(error_handler); | |
XUngrabServer(dpy); | |
arrange(NULL); | |
- if(stack) | |
- focus(stack); | |
+ if(csel) | |
+ focus(csel); | |
} | |
Client * | |
gettitle(Window w) | |
{ | |
Client *c; | |
- for(c = clients; c; c = c->next) | |
+ for(c = cstart; c; c = c->next) | |
if(c->title == w) | |
return c; | |
return NULL; | |
t@@ -409,7 +465,7 @@ Client * | |
getclient(Window w) | |
{ | |
Client *c; | |
- for(c = clients; c; c = c->next) | |
+ for(c = cstart; c; c = c->next) | |
if(c->win == w) | |
return c; | |
return NULL; | |
t@@ -419,7 +475,7 @@ void | |
draw_client(Client *c) | |
{ | |
int i; | |
- if(c == stack) | |
+ if(c == csel) | |
return; | |
dc.x = dc.y = 0; | |
diff --git a/dev.c b/dev.c | |
t@@ -20,16 +20,21 @@ const char *browse[] = { "firefox", NULL }; | |
const char *xlock[] = { "xlock", NULL }; | |
static Key key[] = { | |
- { Mod1Mask, XK_Return, (void (*)(void *))spawn, term }, | |
- { Mod1Mask, XK_w, (void (*)(void *))spawn, browse }, | |
- { Mod1Mask, XK_l, (void (*)(void *))spawn, xlock }, | |
- { Mod1Mask, XK_k, sel, "prev" }, | |
- { Mod1Mask, XK_j, sel, "next" }, | |
- { Mod1Mask, XK_t, tiling, NULL }, | |
- { Mod1Mask, XK_f, floating, NULL }, | |
- { Mod1Mask, XK_m, max, NULL }, | |
- { Mod1Mask | ShiftMask, XK_c, ckill, NULL }, | |
- { Mod1Mask | ShiftMask, XK_q, quit, NULL }, | |
+ { Mod1Mask, XK_Return, spawn, { .argv = term } }, | |
+ { Mod1Mask, XK_w, spawn, { .argv = browse } }, | |
+ { Mod1Mask, XK_l, spawn, { .argv = xlock } }, | |
+ { Mod1Mask, XK_k, prevc, { 0 } }, | |
+ { Mod1Mask, XK_j, nextc, { 0 } }, | |
+ { Mod1Mask, XK_t, tiling, { 0 } }, | |
+ { Mod1Mask, XK_f, floating, { 0 } }, | |
+ { Mod1Mask, XK_m, max, { 0 } }, | |
+ { Mod1Mask, XK_0, tag, { .i = Tscratch } }, | |
+ { Mod1Mask, XK_1, tag, { .i = Tdev } }, | |
+ { Mod1Mask, XK_2, tag, { .i = Tirc } }, | |
+ { Mod1Mask, XK_3, tag, { .i = Twww } }, | |
+ { Mod1Mask, XK_4, tag, { .i = Twork } }, | |
+ { Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, | |
+ { Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, | |
}; | |
/********** CUSTOMIZE **********/ | |
t@@ -60,7 +65,7 @@ keypress(XEvent *e) | |
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].aux); | |
+ key[i].func(&key[i].arg); | |
return; | |
} | |
} | |
diff --git a/dwm.h b/dwm.h | |
t@@ -22,6 +22,12 @@ typedef struct DC DC; | |
typedef struct Client Client; | |
typedef struct Fnt Fnt; | |
typedef struct Key Key; | |
+typedef union Arg Arg; | |
+ | |
+union Arg { | |
+ const char **argv; | |
+ int i; | |
+}; | |
/* atoms */ | |
enum { WMProtocols, WMDelete, WMLast }; | |
t@@ -62,14 +68,14 @@ struct Client { | |
Window trans; | |
Window title; | |
Client *next; | |
- Client *snext; | |
+ Client *prev; | |
}; | |
struct Key { | |
unsigned long mod; | |
KeySym keysym; | |
- void (*func)(void *aux); | |
- void *aux; | |
+ void (*func)(Arg *arg); | |
+ Arg arg; | |
}; | |
extern Display *dpy; | |
t@@ -83,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th; | |
extern char stext[1024], *tags[TLast]; | |
extern DC dc; | |
-extern Client *clients, *stack; | |
+extern Client *cstart, *cend, *csel; | |
/* client.c */ | |
extern void manage(Window w, XWindowAttributes *wa); | |
t@@ -97,11 +103,13 @@ 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 floating(void *aux); | |
-extern void tiling(void *aux); | |
+extern void ckill(Arg *arg); | |
+extern void nextc(Arg *arg); | |
+extern void prevc(Arg *arg); | |
+extern void max(Arg *arg); | |
+extern void floating(Arg *arg); | |
+extern void tiling(Arg *arg); | |
+void tag(Arg *arg); | |
extern void gravitate(Client *c, Bool invert); | |
/* draw.c */ | |
t@@ -125,7 +133,7 @@ extern void mmove(Client *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); | |
+extern void quit(Arg *arg); | |
/* util.c */ | |
extern void error(const char *errstr, ...); | |
t@@ -133,5 +141,5 @@ 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 spawn(Arg *arg); | |
extern void swap(void **p1, void **p2); | |
diff --git a/main.c b/main.c | |
t@@ -38,8 +38,9 @@ int tsel = Tdev; /* default tag */ | |
int screen, sx, sy, sw, sh, th; | |
DC dc = {0}; | |
-Client *clients = NULL; | |
-Client *stack = NULL; | |
+Client *cstart = NULL; | |
+Client *cend = NULL; | |
+Client *csel = NULL; | |
static Bool other_wm_running; | |
static const char version[] = | |
t@@ -168,13 +169,13 @@ startup_error_handler(Display *dpy, XErrorEvent *error) | |
static void | |
cleanup() | |
{ | |
- while(clients) | |
- unmanage(clients); | |
+ while(csel) | |
+ unmanage(csel); | |
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | |
} | |
void | |
-quit(void *aux) | |
+quit(Arg *arg) | |
{ | |
running = False; | |
} | |
diff --git a/util.c b/util.c | |
t@@ -75,8 +75,9 @@ swap(void **p1, void **p2) | |
} | |
void | |
-spawn(char *argv[]) | |
+spawn(Arg *arg) | |
{ | |
+ char **argv = (char **)arg->argv; | |
if(!argv || !argv[0]) | |
return; | |
if(fork() == 0) { |