tseveral other additions/fixes, dwm is quite usable already - dwm - [fork] cust… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit efa7e514012865fcb3e9ea6e7d5b5c87d84353e5 | |
parent c47da143bdf5b4e3924a411f42648d4b3e86ff00 | |
Author: Anselm R. Garbe <[email protected]> | |
Date: Thu, 13 Jul 2006 18:21:38 +0200 | |
several other additions/fixes, dwm is quite usable already | |
Diffstat: | |
M client.c | 235 ++++++++++++++++++-----------… | |
M dev.c | 22 ++++++++++++++-------- | |
M dwm.h | 8 +++++--- | |
M main.c | 11 ++++++----- | |
4 files changed, 165 insertions(+), 111 deletions(-) | |
--- | |
diff --git a/client.c b/client.c | |
t@@ -13,60 +13,105 @@ | |
static void (*arrange)(Arg *) = floating; | |
+static void | |
+center(Client *c) | |
+{ | |
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | |
+} | |
+ | |
static Client * | |
next(Client *c) | |
{ | |
- for(c = c->next; c && !c->tags[tsel]; c = c->next); | |
+ for(; c && !c->tags[tsel]; c = c->next); | |
return c; | |
} | |
-static Client * | |
-prev(Client *c) | |
+void | |
+zoom(Arg *arg) | |
{ | |
- for(c = c->prev; c && !c->tags[tsel]; c = c->prev); | |
- return c; | |
+ Client **l; | |
+ | |
+ if(!sel) | |
+ return; | |
+ | |
+ for(l = &clients; *l && *l != sel; l = &(*l)->next); | |
+ *l = sel->next; | |
+ | |
+ sel->next = clients; /* pop */ | |
+ clients = sel; | |
+ arrange(NULL); | |
+ center(sel); | |
+ focus(sel); | |
} | |
void | |
max(Arg *arg) | |
{ | |
- if(!csel) | |
+ if(!sel) | |
return; | |
- csel->x = sx; | |
- csel->y = sy; | |
- csel->w = sw - 2 * csel->border; | |
- csel->h = sh - 2 * csel->border; | |
- craise(csel); | |
- resize(csel); | |
+ sel->x = sx; | |
+ sel->y = sy; | |
+ sel->w = sw - 2 * sel->border; | |
+ sel->h = sh - 2 * sel->border; | |
+ craise(sel); | |
+ resize(sel); | |
discard_events(EnterWindowMask); | |
} | |
void | |
+view(Arg *arg) | |
+{ | |
+ tsel = arg->i; | |
+ arrange(NULL); | |
+} | |
+ | |
+void | |
tag(Arg *arg) | |
{ | |
- if(!csel) | |
+ int i, n; | |
+ if(!sel) | |
return; | |
- if(arg->i == tsel) | |
- return; | |
+ if(arg->i == tsel) { | |
+ for(n = i = 0; i < TLast; i++) | |
+ if(sel->tags[i]) | |
+ n++; | |
+ if(n < 2) | |
+ return; | |
+ } | |
- if(csel->tags[arg->i]) | |
- csel->tags[arg->i] = NULL; /* toggle tag */ | |
+ if(sel->tags[arg->i]) | |
+ sel->tags[arg->i] = NULL; /* toggle tag */ | |
else | |
- csel->tags[arg->i] = tags[arg->i]; | |
+ sel->tags[arg->i] = tags[arg->i]; | |
arrange(NULL); | |
} | |
+static void | |
+ban_client(Client *c) | |
+{ | |
+ XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
+ XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); | |
+} | |
+ | |
void | |
floating(Arg *arg) | |
{ | |
Client *c; | |
arrange = floating; | |
- if(!csel) | |
- return; | |
- for(c = csel; c; c = next(c)) | |
- resize(c); | |
+ for(c = clients; c; c = c->next) { | |
+ if(c->tags[tsel]) | |
+ resize(c); | |
+ else | |
+ ban_client(c); | |
+ } | |
+ if(sel && !sel->tags[tsel]) { | |
+ if((sel = next(clients))) { | |
+ craise(sel); | |
+ focus(sel); | |
+ } | |
+ } | |
discard_events(EnterWindowMask); | |
} | |
t@@ -78,31 +123,43 @@ tiling(Arg *arg) | |
float rt, fd; | |
arrange = tiling; | |
- if(!csel) | |
- return; | |
- for(n = 0, c = csel; c; c = next(c), n++); | |
- rt = sqrt(n); | |
- if(modff(rt, &fd) < 0.5) | |
- rows = floor(rt); | |
- else | |
- rows = ceil(rt); | |
- if(rows * rows < n) | |
- cols = rows + 1; | |
+ for(n = 0, c = clients; c; c = next(c->next), n++); | |
+ if(n) { | |
+ rt = sqrt(n); | |
+ if(modff(rt, &fd) < 0.5) | |
+ rows = floor(rt); | |
+ else | |
+ rows = ceil(rt); | |
+ if(rows * rows < n) | |
+ cols = rows + 1; | |
+ else | |
+ cols = rows; | |
+ | |
+ gw = (sw - 2) / cols; | |
+ gh = (sh - 2) / rows; | |
+ } | |
else | |
- cols = rows; | |
- | |
- gw = (sw - 2) / cols; | |
- gh = (sh - 2) / rows; | |
- | |
- for(i = j = 0, c = csel; c; c = next(c)) { | |
- c->x = i * gw; | |
- c->y = j * gh; | |
- c->w = gw; | |
- c->h = gh; | |
- resize(c); | |
- if(++i == cols) { | |
- j++; | |
- i = 0; | |
+ cols = rows = gw = gh = 0; | |
+ | |
+ for(i = j = 0, c = clients; c; c = c->next) { | |
+ if(c->tags[tsel]) { | |
+ c->x = i * gw; | |
+ c->y = j * gh; | |
+ c->w = gw; | |
+ c->h = gh; | |
+ resize(c); | |
+ if(++i == cols) { | |
+ j++; | |
+ i = 0; | |
+ } | |
+ } | |
+ else | |
+ ban_client(c); | |
+ } | |
+ if(sel && !sel->tags[tsel]) { | |
+ if((sel = next(clients))) { | |
+ craise(sel); | |
+ focus(sel); | |
} | |
} | |
discard_events(EnterWindowMask); | |
t@@ -113,14 +170,12 @@ prevc(Arg *arg) | |
{ | |
Client *c; | |
- if(!csel) | |
+ if(!sel) | |
return; | |
- if(!(c = prev(csel))) | |
- c = prev(cend); | |
- if(c) { | |
+ if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
craise(c); | |
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2… | |
+ center(c); | |
focus(c); | |
} | |
} | |
t@@ -130,15 +185,15 @@ nextc(Arg *arg) | |
{ | |
Client *c; | |
- if(!csel) | |
+ if(!sel) | |
return; | |
- if(!(c = next(csel))) | |
- c = next(cstart); | |
- | |
+ if(!(c = next(sel->next))) | |
+ c = next(clients); | |
if(c) { | |
craise(c); | |
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2… | |
+ center(c); | |
+ c->revert = sel; | |
focus(c); | |
} | |
} | |
t@@ -146,14 +201,12 @@ nextc(Arg *arg) | |
void | |
ckill(Arg *arg) | |
{ | |
- Client *c = csel; | |
- | |
- if(!c) | |
+ if(!sel) | |
return; | |
- if(c->proto & WM_PROTOCOL_DELWIN) | |
- send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | |
+ if(sel->proto & WM_PROTOCOL_DELWIN) | |
+ send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]… | |
else | |
- XKillClient(dpy, c->win); | |
+ XKillClient(dpy, sel->win); | |
} | |
static void | |
t@@ -256,12 +309,12 @@ lower(Client *c) | |
void | |
focus(Client *c) | |
{ | |
- if(csel && csel != c) { | |
- XSetWindowBorder(dpy, csel->win, dc.bg); | |
- XMapWindow(dpy, csel->title); | |
- draw_client(csel); | |
+ if(sel && sel != c) { | |
+ XSetWindowBorder(dpy, sel->win, dc.bg); | |
+ XMapWindow(dpy, sel->title); | |
+ draw_client(sel); | |
} | |
- csel = c; | |
+ sel = c; | |
XUnmapWindow(dpy, c->title); | |
XSetWindowBorder(dpy, c->win, dc.fg); | |
draw_client(c); | |
t@@ -273,7 +326,7 @@ focus(Client *c) | |
void | |
manage(Window w, XWindowAttributes *wa) | |
{ | |
- Client *c; | |
+ Client *c, **l; | |
XSetWindowAttributes twa; | |
c = emallocz(sizeof(Client)); | |
t@@ -284,6 +337,7 @@ manage(Window w, XWindowAttributes *wa) | |
c->h = wa->height; | |
c->th = th; | |
c->border = 1; | |
+ c->proto = win_proto(c->win); | |
update_size(c); | |
XSelectInput(dpy, c->win, | |
StructureNotifyMask | PropertyChangeMask | EnterWindow… | |
t@@ -300,13 +354,9 @@ manage(Window w, XWindowAttributes *wa) | |
update_name(c); | |
- if(!cstart) | |
- cstart = cend = c; | |
- else { | |
- cend->next = c; | |
- c->prev = cend; | |
- cend = c; | |
- } | |
+ for(l = &clients; *l; l = &(*l)->next); | |
+ c->next = *l; /* *l == nil */ | |
+ *l = c; | |
XSetWindowBorderWidth(dpy, c->win, 1); | |
XMapRaised(dpy, c->win); | |
t@@ -318,7 +368,7 @@ manage(Window w, XWindowAttributes *wa) | |
XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | |
GrabModeAsync, GrabModeSync, None, None); | |
arrange(NULL); | |
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | |
+ center(c); | |
focus(c); | |
} | |
t@@ -420,26 +470,21 @@ 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); | |
- 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; | |
+ for(l = &clients; *l && *l != c; l = &(*l)->next); | |
+ *l = c->next; | |
+ for(l = &clients; *l; l = &(*l)->next) | |
+ if((*l)->revert == c) | |
+ (*l)->revert = NULL; | |
+ if(sel == c) | |
+ sel = sel->revert ? sel->revert : clients; | |
free(c); | |
t@@ -447,15 +492,15 @@ unmanage(Client *c) | |
XSetErrorHandler(error_handler); | |
XUngrabServer(dpy); | |
arrange(NULL); | |
- if(csel) | |
- focus(csel); | |
+ if(sel) | |
+ focus(sel); | |
} | |
Client * | |
gettitle(Window w) | |
{ | |
Client *c; | |
- for(c = cstart; c; c = c->next) | |
+ for(c = clients; c; c = c->next) | |
if(c->title == w) | |
return c; | |
return NULL; | |
t@@ -465,7 +510,7 @@ Client * | |
getclient(Window w) | |
{ | |
Client *c; | |
- for(c = cstart; c; c = c->next) | |
+ for(c = clients; c; c = c->next) | |
if(c->win == w) | |
return c; | |
return NULL; | |
t@@ -475,7 +520,7 @@ void | |
draw_client(Client *c) | |
{ | |
int i; | |
- if(c == csel) | |
+ if(c == sel) | |
return; | |
dc.x = dc.y = 0; | |
diff --git a/dev.c b/dev.c | |
t@@ -20,19 +20,25 @@ const char *browse[] = { "firefox", NULL }; | |
const char *xlock[] = { "xlock", NULL }; | |
static Key key[] = { | |
- { Mod1Mask, XK_Return, spawn, { .argv = term } }, | |
+ { Mod1Mask, XK_Return, zoom, { 0 } }, | |
+ { Mod1Mask, XK_t, 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, XK_0, view, { .i = Tscratch } }, | |
+ { Mod1Mask, XK_1, view, { .i = Tdev } }, | |
+ { Mod1Mask, XK_2, view, { .i = Tirc } }, | |
+ { Mod1Mask, XK_3, view, { .i = Twww } }, | |
+ { Mod1Mask, XK_4, view, { .i = Twork } }, | |
+ { Mod1Mask, XK_space, tiling, { 0 } }, | |
+ { Mod1Mask | ShiftMask, XK_space, floating, { 0 } }, | |
+ { Mod1Mask | ShiftMask, XK_0, tag, { .i = Tscratch } }, | |
+ { Mod1Mask | ShiftMask, XK_1, tag, { .i = Tdev } }, | |
+ { Mod1Mask | ShiftMask, XK_2, tag, { .i = Tirc } }, | |
+ { Mod1Mask | ShiftMask, XK_3, tag, { .i = Twww } }, | |
+ { Mod1Mask | ShiftMask, XK_4, tag, { .i = Twork } }, | |
{ Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, | |
{ Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, | |
}; | |
diff --git a/dwm.h b/dwm.h | |
t@@ -68,7 +68,7 @@ struct Client { | |
Window trans; | |
Window title; | |
Client *next; | |
- Client *prev; | |
+ Client *revert; | |
}; | |
struct Key { | |
t@@ -89,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th; | |
extern char stext[1024], *tags[TLast]; | |
extern DC dc; | |
-extern Client *cstart, *cend, *csel; | |
+extern Client *clients, *sel; | |
/* client.c */ | |
extern void manage(Window w, XWindowAttributes *wa); | |
t@@ -109,7 +109,9 @@ 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 tag(Arg *arg); | |
+extern void view(Arg *arg); | |
+extern void zoom(Arg *arg); | |
extern void gravitate(Client *c, Bool invert); | |
/* draw.c */ | |
diff --git a/main.c b/main.c | |
t@@ -38,9 +38,8 @@ int tsel = Tdev; /* default tag */ | |
int screen, sx, sy, sw, sh, th; | |
DC dc = {0}; | |
-Client *cstart = NULL; | |
-Client *cend = NULL; | |
-Client *csel = NULL; | |
+Client *clients = NULL; | |
+Client *sel = NULL; | |
static Bool other_wm_running; | |
static const char version[] = | |
t@@ -169,8 +168,10 @@ startup_error_handler(Display *dpy, XErrorEvent *error) | |
static void | |
cleanup() | |
{ | |
- while(csel) | |
- unmanage(csel); | |
+ while(sel) { | |
+ resize(sel); | |
+ unmanage(sel); | |
+ } | |
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | |
} | |