diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | bar.c | 54 | ||||
-rw-r--r-- | client.c | 230 | ||||
-rw-r--r-- | draw.c | 67 | ||||
-rw-r--r-- | dwm.h | 31 | ||||
-rw-r--r-- | event.c | 96 | ||||
-rw-r--r-- | key.c (renamed from dev.c) | 169 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | screen.c | 100 |
9 files changed, 374 insertions, 377 deletions
@@ -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 @@ -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); -} @@ -11,14 +11,12 @@ #include "dwm.h" -void (*arrange)(Arg *) = tiling; - static Rule rule[] = { /* class instance tags floating */ { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, }; -static Client * +Client * next(Client *c) { for(; c && !c->tags[tsel]; c = c->next); @@ -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) { @@ -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; @@ -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); -} @@ -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) { @@ -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 @@ -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]; @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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, GrabModeAsync, + None, cursor[CurResize], CurrentTime) != GrabSuccess) + 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, GrabModeAsync, + None, cursor[CurMove], CurrentTime) != GrabSuccess) + 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: @@ -150,12 +232,6 @@ expose(XEvent *e) } static void -keymapnotify(XEvent *e) -{ - update_keys(); -} - -static void maprequest(XEvent *e) { XMapRequestEvent *ev = &e->xmaprequest; @@ -3,12 +3,23 @@ * See LICENSE file for license details. */ -#include "dwm.h" - +#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 **********/ @@ -19,7 +30,7 @@ const char *term[] = { const char *browse[] = { "firefox", NULL }; const char *xlock[] = { "xlock", NULL }; -static Key key[] = { +Key key[] = { /* modifier key function arguments */ { Mod1Mask, XK_Return, zoom, { 0 } }, { Mod1Mask, XK_k, prevc, { 0 } }, @@ -49,7 +60,7 @@ static Key key[] = { /********** CUSTOMIZE **********/ void -update_keys(void) +grabkeys() { static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; unsigned int i; @@ -58,7 +69,8 @@ update_keys(void) 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); + XGrabKey(dpy, code, key[i].mod, root, True, + GrabModeAsync, GrabModeAsync); } } @@ -79,73 +91,102 @@ keypress(XEvent *e) } } -#define ButtonMask (ButtonPressMask | ButtonReleaseMask) -#define MouseMask (ButtonMask | PointerMotionMask) +static void +zoom(Arg *arg) +{ + Client **l, *c; -void -mresize(Client *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) { - XEvent ev; - int ocx, ocy; + 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); +} - ocx = c->x; - ocy = c->y; - if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize], CurrentTime) != GrabSuccess) +static void +tappend(Arg *arg) +{ + if(!sel) 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; - } + + 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); } } -void -mmove(Client *c) +static void +nextc(Arg *arg) { - 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, GrabModeAsync, - None, cursor[CurMove], CurrentTime) != GrabSuccess) + Client *c; + + if(!sel) 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; - } + + 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); +} + @@ -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 new file mode 100644 index 0000000..f2891cf --- /dev/null +++ b/screen.c @@ -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(); +} + |