trearranged - dwm - [fork] customized build of dwm, the dynamic window manager | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 29355bd38284ed9aec8d3ffabde61db73947c9f9 | |
parent 91a1f6926e2594156219c1caaf4729c5d86498a5 | |
Author: Anselm R. Garbe <[email protected]> | |
Date: Fri, 14 Jul 2006 22:33:38 +0200 | |
rearranged | |
Diffstat: | |
M Makefile | 2 +- | |
D bar.c | 54 -----------------------------… | |
M client.c | 230 +----------------------------… | |
D dev.c | 151 -----------------------------… | |
M draw.c | 67 +++++++++++++++++++++++++++++… | |
M dwm.h | 31 ++++++++++++-----------------… | |
M event.c | 96 +++++++++++++++++++++++++++--… | |
A key.c | 192 +++++++++++++++++++++++++++++… | |
M main.c | 2 +- | |
A screen.c | 100 +++++++++++++++++++++++++++++… | |
10 files changed, 461 insertions(+), 464 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
t@@ -3,7 +3,7 @@ | |
include config.mk | |
-SRC = bar.c client.c dev.c draw.c event.c main.c util.c | |
+SRC = client.c draw.c event.c key.c main.c screen.c util.c | |
OBJ = ${SRC:.c=.o} | |
MAN1 = dwm.1 | |
BIN = dwm | |
diff --git a/bar.c b/bar.c | |
t@@ -1,54 +0,0 @@ | |
-/* | |
- * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
- * See LICENSE file for license details. | |
- */ | |
- | |
-#include "dwm.h" | |
- | |
-void | |
-barclick(XButtonPressedEvent *e) | |
-{ | |
- int x = 0; | |
- Arg a; | |
- for(a.i = 0; a.i < TLast; a.i++) { | |
- x += textw(tags[a.i]) + dc.font.height; | |
- if(e->x < x) { | |
- view(&a); | |
- return; | |
- } | |
- } | |
-} | |
- | |
-void | |
-draw_bar() | |
-{ | |
- int i, modw; | |
- char *mode = arrange == tiling ? "#" : "~"; | |
- | |
- dc.x = dc.y = 0; | |
- dc.w = bw; | |
- drawtext(NULL, False, False); | |
- | |
- modw = textw(mode) + dc.font.height; | |
- dc.w = 0; | |
- for(i = 0; i < TLast; i++) { | |
- dc.x += dc.w; | |
- dc.w = textw(tags[i]) + dc.font.height; | |
- drawtext(tags[i], i == tsel, True); | |
- } | |
- if(sel) { | |
- dc.x += dc.w; | |
- dc.w = textw(sel->name) + dc.font.height; | |
- drawtext(sel->name, True, True); | |
- } | |
- dc.w = textw(stext) + dc.font.height; | |
- dc.x = bx + bw - dc.w - modw; | |
- drawtext(stext, False, False); | |
- | |
- dc.x = bx + bw - modw; | |
- dc.w = modw; | |
- drawtext(mode, True, True); | |
- | |
- XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); | |
- XFlush(dpy); | |
-} | |
diff --git a/client.c b/client.c | |
t@@ -11,14 +11,12 @@ | |
#include "dwm.h" | |
-void (*arrange)(Arg *) = tiling; | |
- | |
static Rule rule[] = { | |
/* class instance tags … | |
{ "Firefox-bin", "Gecko", { [Twww] = "www" }, … | |
}; | |
-static Client * | |
+Client * | |
next(Client *c) | |
{ | |
for(; c && !c->tags[tsel]; c = c->next); | |
t@@ -26,202 +24,12 @@ next(Client *c) | |
} | |
void | |
-zoom(Arg *arg) | |
-{ | |
- Client **l, *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if(sel == next(clients) && sel->next) { | |
- if((c = next(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 | |
-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; | |
- craise(sel); | |
- resize(sel, False); | |
-} | |
- | |
-void | |
-view(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- tsel = arg->i; | |
- arrange(NULL); | |
- | |
- for(c = clients; c; c = next(c->next)) | |
- draw_client(c); | |
- draw_bar(); | |
-} | |
- | |
-void | |
-tappend(Arg *arg) | |
-{ | |
- if(!sel) | |
- return; | |
- | |
- sel->tags[arg->i] = tags[arg->i]; | |
- arrange(NULL); | |
-} | |
- | |
-void | |
-ttrunc(Arg *arg) | |
-{ | |
- int i; | |
- if(!sel) | |
- return; | |
- | |
- for(i = 0; i < TLast; i++) | |
- sel->tags[i] = NULL; | |
- tappend(arg); | |
-} | |
- | |
-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; | |
- for(c = clients; c; c = c->next) { | |
- if(c->tags[tsel]) | |
- resize(c, True); | |
- else | |
- ban_client(c); | |
- } | |
- if(sel && !sel->tags[tsel]) { | |
- if((sel = next(clients))) { | |
- craise(sel); | |
- focus(sel); | |
- } | |
- } | |
- draw_bar(); | |
-} | |
- | |
-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) { | |
- craise(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_client(c); | |
- } | |
- if(!sel || (sel && !sel->tags[tsel])) { | |
- if((sel = next(clients))) { | |
- craise(sel); | |
- focus(sel); | |
- } | |
- } | |
- draw_bar(); | |
-} | |
- | |
-void | |
-prevc(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | |
- craise(c); | |
- focus(c); | |
- } | |
-} | |
- | |
-void | |
-nextc(Arg *arg) | |
-{ | |
- Client *c; | |
- | |
- if(!sel) | |
- return; | |
- | |
- if(!(c = next(sel->next))) | |
- c = next(clients); | |
- if(c) { | |
- craise(c); | |
- c->revert = sel; | |
- focus(c); | |
- } | |
-} | |
- | |
-void | |
-ckill(Arg *arg) | |
-{ | |
- if(!sel) | |
- return; | |
- if(sel->proto & WM_PROTOCOL_DELWIN) | |
- send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]… | |
- else | |
- XKillClient(dpy, sel->win); | |
-} | |
- | |
static void | |
resize_title(Client *c) | |
{ | |
t@@ -230,8 +38,8 @@ resize_title(Client *c) | |
c->tw = 0; | |
for(i = 0; i < TLast; i++) | |
if(c->tags[i]) | |
- c->tw += textw(c->tags[i]) + dc.font.height; | |
- c->tw += textw(c->name) + dc.font.height; | |
+ c->tw += textw(c->tags[i]); | |
+ c->tw += textw(c->name); | |
if(c->tw > c->w) | |
c->tw = c->w + 2; | |
c->tx = c->x + c->w - c->tw + 2; | |
t@@ -584,35 +392,3 @@ getclient(Window w) | |
return c; | |
return NULL; | |
} | |
- | |
-void | |
-draw_client(Client *c) | |
-{ | |
- int i; | |
- if(c == sel) { | |
- draw_bar(); | |
- XUnmapWindow(dpy, c->title); | |
- XSetWindowBorder(dpy, c->win, dc.fg); | |
- return; | |
- } | |
- | |
- XSetWindowBorder(dpy, c->win, dc.bg); | |
- XMapWindow(dpy, c->title); | |
- | |
- dc.x = dc.y = 0; | |
- | |
- dc.w = 0; | |
- for(i = 0; i < TLast; i++) { | |
- if(c->tags[i]) { | |
- dc.x += dc.w; | |
- dc.w = textw(c->tags[i]) + dc.font.height; | |
- drawtext(c->tags[i], False, True); | |
- } | |
- } | |
- dc.x += dc.w; | |
- dc.w = textw(c->name) + dc.font.height; | |
- drawtext(c->name, False, True); | |
- XCopyArea(dpy, dc.drawable, c->title, dc.gc, | |
- 0, 0, c->tw, c->th, 0, 0); | |
- XFlush(dpy); | |
-} | |
diff --git a/dev.c b/dev.c | |
t@@ -1,151 +0,0 @@ | |
-/* | |
- * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |
- * See LICENSE file for license details. | |
- */ | |
- | |
-#include "dwm.h" | |
- | |
-#include <stdlib.h> | |
-#include <string.h> | |
-#include <unistd.h> | |
-#include <X11/keysym.h> | |
- | |
-/********** 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 }; | |
- | |
-static 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 | |
-update_keys(void) | |
-{ | |
- 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, Gra… | |
- } | |
-} | |
- | |
-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; | |
- } | |
-} | |
- | |
-#define ButtonMask (ButtonPressMask | ButtonReleaseMask) | |
-#define MouseMask (ButtonMask | PointerMotionMask) | |
- | |
-void | |
-mresize(Client *c) | |
-{ | |
- XEvent ev; | |
- int ocx, ocy; | |
- | |
- ocx = c->x; | |
- ocy = c->y; | |
- if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAs… | |
- None, cursor[CurResize], CurrentTime) != GrabS… | |
- return; | |
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); | |
- for(;;) { | |
- XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
- switch(ev.type) { | |
- default: break; | |
- case Expose: | |
- handler[Expose](&ev); | |
- break; | |
- case MotionNotify: | |
- XFlush(dpy); | |
- c->w = abs(ocx - ev.xmotion.x); | |
- c->h = abs(ocy - ev.xmotion.y); | |
- c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; | |
- c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; | |
- resize(c, True); | |
- break; | |
- case ButtonRelease: | |
- XUngrabPointer(dpy, CurrentTime); | |
- return; | |
- } | |
- } | |
-} | |
- | |
-void | |
-mmove(Client *c) | |
-{ | |
- XEvent ev; | |
- int x1, y1, ocx, ocy, di; | |
- unsigned int dui; | |
- Window dummy; | |
- | |
- ocx = c->x; | |
- ocy = c->y; | |
- if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAs… | |
- None, cursor[CurMove], CurrentTime) != GrabSuc… | |
- return; | |
- XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | |
- for(;;) { | |
- XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
- switch (ev.type) { | |
- default: break; | |
- case Expose: | |
- handler[Expose](&ev); | |
- break; | |
- case MotionNotify: | |
- XFlush(dpy); | |
- c->x = ocx + (ev.xmotion.x - x1); | |
- c->y = ocy + (ev.xmotion.y - y1); | |
- resize(c, False); | |
- break; | |
- case ButtonRelease: | |
- XUngrabPointer(dpy, CurrentTime); | |
- return; | |
- } | |
- } | |
-} | |
diff --git a/draw.c b/draw.c | |
t@@ -10,6 +10,71 @@ | |
#include "dwm.h" | |
+void | |
+draw_bar() | |
+{ | |
+ int i; | |
+ | |
+ dc.x = dc.y = 0; | |
+ dc.w = bw; | |
+ drawtext(NULL, False, False); | |
+ | |
+ if(arrange == floating) { | |
+ dc.w = textw("~"); | |
+ drawtext("~", False, False); | |
+ } | |
+ else | |
+ 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(sel) { | |
+ dc.x += dc.w; | |
+ dc.w = textw(sel->name); | |
+ drawtext(sel->name, True, True); | |
+ } | |
+ dc.w = textw(stext); | |
+ dc.x = bx + bw - dc.w; | |
+ drawtext(stext, False, False); | |
+ | |
+ XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); | |
+ XFlush(dpy); | |
+} | |
+ | |
+void | |
+draw_client(Client *c) | |
+{ | |
+ int i; | |
+ if(c == sel) { | |
+ draw_bar(); | |
+ XUnmapWindow(dpy, c->title); | |
+ XSetWindowBorder(dpy, c->win, dc.fg); | |
+ return; | |
+ } | |
+ | |
+ XSetWindowBorder(dpy, c->win, dc.bg); | |
+ XMapWindow(dpy, c->title); | |
+ | |
+ dc.x = dc.y = 0; | |
+ | |
+ dc.w = 0; | |
+ for(i = 0; i < TLast; i++) { | |
+ if(c->tags[i]) { | |
+ dc.x += dc.w; | |
+ dc.w = textw(c->tags[i]); | |
+ drawtext(c->tags[i], False, True); | |
+ } | |
+ } | |
+ dc.x += dc.w; | |
+ dc.w = textw(c->name); | |
+ drawtext(c->name, False, True); | |
+ XCopyArea(dpy, dc.drawable, c->title, dc.gc, | |
+ 0, 0, c->tw, c->th, 0, 0); | |
+ XFlush(dpy); | |
+} | |
+ | |
static void | |
drawborder(void) | |
{ | |
t@@ -103,7 +168,7 @@ textnw(char *text, unsigned int len) | |
unsigned int | |
textw(char *text) | |
{ | |
- return textnw(text, strlen(text)); | |
+ return textnw(text, strlen(text)) + dc.font.height; | |
} | |
void | |
diff --git a/dwm.h b/dwm.h | |
t@@ -94,6 +94,7 @@ extern Cursor cursor[CurLast]; | |
extern Bool running, issel; | |
extern void (*handler[LASTEvent])(XEvent *); | |
extern void (*arrange)(Arg *); | |
+extern Key key[]; | |
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw; | |
extern char *tags[TLast], stext[1024]; | |
t@@ -101,35 +102,24 @@ extern char *tags[TLast], stext[1024]; | |
extern DC dc; | |
extern Client *clients, *sel; | |
-/* bar.c */ | |
-extern void draw_bar(); | |
-extern void barclick(XButtonPressedEvent *e); | |
- | |
/* 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, Bool inc); | |
extern void update_size(Client *c); | |
extern Client *gettitle(Window w); | |
extern void craise(Client *c); | |
extern void lower(Client *c); | |
-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); | |
-extern void ttrunc(Arg *arg); | |
-extern void tappend(Arg *arg); | |
-extern void view(Arg *arg); | |
-extern void zoom(Arg *arg); | |
extern void gravitate(Client *c, Bool invert); | |
+extern void ban_client(Client *c); | |
+extern Client *next(Client *c); | |
/* draw.c */ | |
+extern void draw_bar(); | |
+extern void draw_client(Client *c); | |
extern void drawtext(const char *text, Bool invert, Bool border); | |
extern unsigned long initcolor(const char *colstr); | |
extern void initfont(const char *fontstr); | |
t@@ -137,11 +127,9 @@ extern unsigned int textnw(char *text, unsigned int len); | |
extern unsigned int textw(char *text); | |
extern unsigned int texth(void); | |
-/* dev.c */ | |
-extern void update_keys(void); | |
+/* key.c */ | |
+extern void grabkeys(); | |
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); | |
t@@ -149,6 +137,11 @@ extern void send_message(Window w, Atom a, long value); | |
extern int win_proto(Window w); | |
extern void quit(Arg *arg); | |
+/* screen.c */ | |
+extern void floating(Arg *arg); | |
+extern void tiling(Arg *arg); | |
+extern void view(Arg *arg); | |
+ | |
/* util.c */ | |
extern void error(const char *errstr, ...); | |
extern void *emallocz(unsigned int size); | |
diff --git a/event.c b/event.c | |
t@@ -7,11 +7,15 @@ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
+#include <unistd.h> | |
#include <X11/keysym.h> | |
#include <X11/Xatom.h> | |
#include "dwm.h" | |
+#define ButtonMask (ButtonPressMask | ButtonReleaseMask) | |
+#define MouseMask (ButtonMask | PointerMotionMask) | |
+ | |
/* local functions */ | |
static void buttonpress(XEvent *e); | |
static void configurerequest(XEvent *e); | |
t@@ -19,7 +23,6 @@ static void destroynotify(XEvent *e); | |
static void enternotify(XEvent *e); | |
static void leavenotify(XEvent *e); | |
static void expose(XEvent *e); | |
-static void keymapnotify(XEvent *e); | |
static void maprequest(XEvent *e); | |
static void propertynotify(XEvent *e); | |
static void unmapnotify(XEvent *e); | |
t@@ -32,21 +35,100 @@ void (*handler[LASTEvent]) (XEvent *) = { | |
[LeaveNotify] = leavenotify, | |
[Expose] = expose, | |
[KeyPress] = keypress, | |
- [KeymapNotify] = keymapnotify, | |
[MapRequest] = maprequest, | |
[PropertyNotify] = propertynotify, | |
[UnmapNotify] = unmapnotify | |
}; | |
static void | |
+mresize(Client *c) | |
+{ | |
+ XEvent ev; | |
+ int ocx, ocy; | |
+ | |
+ ocx = c->x; | |
+ ocy = c->y; | |
+ if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAs… | |
+ None, cursor[CurResize], CurrentTime) != GrabS… | |
+ return; | |
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); | |
+ for(;;) { | |
+ XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
+ switch(ev.type) { | |
+ default: break; | |
+ case Expose: | |
+ handler[Expose](&ev); | |
+ break; | |
+ case MotionNotify: | |
+ XFlush(dpy); | |
+ c->w = abs(ocx - ev.xmotion.x); | |
+ c->h = abs(ocy - ev.xmotion.y); | |
+ c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; | |
+ c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; | |
+ resize(c, True); | |
+ break; | |
+ case ButtonRelease: | |
+ XUngrabPointer(dpy, CurrentTime); | |
+ return; | |
+ } | |
+ } | |
+} | |
+ | |
+static void | |
+mmove(Client *c) | |
+{ | |
+ XEvent ev; | |
+ int x1, y1, ocx, ocy, di; | |
+ unsigned int dui; | |
+ Window dummy; | |
+ | |
+ ocx = c->x; | |
+ ocy = c->y; | |
+ if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAs… | |
+ None, cursor[CurMove], CurrentTime) != GrabSuc… | |
+ return; | |
+ XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | |
+ for(;;) { | |
+ XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | |
+ switch (ev.type) { | |
+ default: break; | |
+ case Expose: | |
+ handler[Expose](&ev); | |
+ break; | |
+ case MotionNotify: | |
+ XFlush(dpy); | |
+ c->x = ocx + (ev.xmotion.x - x1); | |
+ c->y = ocy + (ev.xmotion.y - y1); | |
+ resize(c, False); | |
+ break; | |
+ case ButtonRelease: | |
+ XUngrabPointer(dpy, CurrentTime); | |
+ return; | |
+ } | |
+ } | |
+} | |
+ | |
+static void | |
buttonpress(XEvent *e) | |
{ | |
+ int x; | |
+ Arg a; | |
XButtonPressedEvent *ev = &e->xbutton; | |
Client *c; | |
- if(barwin == ev->window) | |
- barclick(ev); | |
+ if(barwin == ev->window) { | |
+ x = (arrange == floating) ? textw("~") : 0; | |
+ for(a.i = 0; a.i < TLast; a.i++) { | |
+ x += textw(tags[a.i]); | |
+ if(ev->x < x) { | |
+ view(&a); | |
+ break; | |
+ } | |
+ } | |
+ } | |
else if((c = getclient(ev->window))) { | |
+ if(arrange == tiling && !c->floating) | |
+ return; | |
craise(c); | |
switch(ev->button) { | |
default: | |
t@@ -150,12 +232,6 @@ expose(XEvent *e) | |
} | |
static void | |
-keymapnotify(XEvent *e) | |
-{ | |
- update_keys(); | |
-} | |
- | |
-static void | |
maprequest(XEvent *e) | |
{ | |
XMapRequestEvent *ev = &e->xmaprequest; | |
diff --git a/key.c b/key.c | |
t@@ -0,0 +1,192 @@ | |
+/* | |
+ * (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 == next(clients) && sel->next) { | |
+ if((c = next(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; | |
+ craise(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)) { | |
+ craise(c); | |
+ focus(c); | |
+ } | |
+} | |
+ | |
+static void | |
+nextc(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ if(!sel) | |
+ return; | |
+ | |
+ if(!(c = next(sel->next))) | |
+ c = next(clients); | |
+ if(c) { | |
+ craise(c); | |
+ c->revert = sel; | |
+ focus(c); | |
+ } | |
+} | |
+ | |
+static void | |
+ckill(Arg *arg) | |
+{ | |
+ if(!sel) | |
+ return; | |
+ if(sel->proto & WM_PROTOCOL_DELWIN) | |
+ send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]… | |
+ else | |
+ XKillClient(dpy, sel->win); | |
+} | |
+ | |
diff --git a/main.c b/main.c | |
t@@ -239,7 +239,7 @@ main(int argc, char *argv[]) | |
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); | |
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); | |
- update_keys(); | |
+ grabkeys(); | |
/* style */ | |
dc.bg = initcolor(BGCOLOR); | |
diff --git a/screen.c b/screen.c | |
t@@ -0,0 +1,100 @@ | |
+/* | |
+ * (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 = next(c->next)) | |
+ draw_client(c); | |
+ draw_bar(); | |
+} | |
+ | |
+void | |
+floating(Arg *arg) | |
+{ | |
+ Client *c; | |
+ | |
+ arrange = floating; | |
+ for(c = clients; c; c = c->next) { | |
+ if(c->tags[tsel]) | |
+ resize(c, True); | |
+ else | |
+ ban_client(c); | |
+ } | |
+ if(sel && !sel->tags[tsel]) { | |
+ if((sel = next(clients))) { | |
+ craise(sel); | |
+ focus(sel); | |
+ } | |
+ } | |
+ draw_bar(); | |
+} | |
+ | |
+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) { | |
+ craise(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_client(c); | |
+ } | |
+ if(!sel || (sel && !sel->tags[tsel])) { | |
+ if((sel = next(clients))) { | |
+ craise(sel); | |
+ focus(sel); | |
+ } | |
+ } | |
+ draw_bar(); | |
+} | |
+ |