dwm

dynamic window manager
git clone git://git.suckless.org/dwm
Log | Files | Refs | README | LICENSE

commit adaa28a6e600f636f5e86244ccef69e98419ba1a
parent dba23062bad40afb1a90f60b6897cf9e1ca5035b
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Sat, 15 Jul 2006 17:00:56 +0200

proceeded with cleaning up, sorting functions, etc

Diffstat:
Mclient.c | 411++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mdraw.c | 146++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mdwm.h | 39+++++++++++++++++++--------------------
Mevent.c | 266++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mmain.c | 71+++++++++++++++++++++++++++++------------------------------------------
Mtag.c | 118++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mutil.c | 24+++++++++++++-----------
7 files changed, 532 insertions(+), 543 deletions(-)

diff --git a/client.c b/client.c @@ -2,21 +2,14 @@ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ +#include "dwm.h" #include <stdlib.h> -#include <stdio.h> #include <string.h> #include <X11/Xatom.h> #include <X11/Xutil.h> -#include "dwm.h" - -void -ban(Client *c) -{ - XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); - XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); -} +/* static functions */ static void resizetitle(Client *c) @@ -35,70 +28,141 @@ resizetitle(Client *c) XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); } +static int +xerrordummy(Display *dsply, XErrorEvent *ee) +{ + return 0; +} + +/* extern functions */ + void -settitle(Client *c) +ban(Client *c) { - XTextProperty name; - int n; - char **list = NULL; + XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); + XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); +} - name.nitems = 0; - c->name[0] = 0; - XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); - if(!name.nitems) - XGetWMName(dpy, c->win, &name); - if(!name.nitems) +void +focus(Client *c) +{ + Client *old = sel; + XEvent ev; + + XFlush(dpy); + sel = c; + if(old && old != c) + drawtitle(old); + drawtitle(c); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XFlush(dpy); + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + +void +focusnext(Arg *arg) +{ + Client *c; + + if(!sel) return; - if(name.encoding == XA_STRING) - strncpy(c->name, (char *)name.value, sizeof(c->name)); - else { - if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success - && n > 0 && *list) - { - strncpy(c->name, *list, sizeof(c->name)); - XFreeStringList(list); - } + + if(!(c = getnext(sel->next))) + c = getnext(clients); + if(c) { + higher(c); + c->revert = sel; + focus(c); } - XFree(name.value); - resizetitle(c); } void -setsize(Client *c) +focusprev(Arg *arg) { - XSizeHints size; - long msize; - if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) - size.flags = PSize; - c->flags = size.flags; - if(c->flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; + Client *c; + + if(!sel) + return; + + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { + higher(c); + focus(c); } - else - c->basew = c->baseh = 0; - if(c->flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; +} + +Client * +getclient(Window w) +{ + Client *c; + for(c = clients; c; c = c->next) + if(c->win == w) + return c; + return NULL; +} + +Client * +getctitle(Window w) +{ + Client *c; + for(c = clients; c; c = c->next) + if(c->title == w) + return c; + return NULL; +} + +void +gravitate(Client *c, Bool invert) +{ + int dx = 0, dy = 0; + + switch(c->grav) { + case StaticGravity: + case NorthWestGravity: + case NorthGravity: + case NorthEastGravity: + dy = c->border; + break; + case EastGravity: + case CenterGravity: + case WestGravity: + dy = -(c->h / 2) + c->border; + break; + case SouthEastGravity: + case SouthGravity: + case SouthWestGravity: + dy = -c->h; + break; + default: + break; } - else - c->incw = c->inch = 0; - if(c->flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; + + switch (c->grav) { + case StaticGravity: + case NorthWestGravity: + case WestGravity: + case SouthWestGravity: + dx = c->border; + break; + case NorthGravity: + case CenterGravity: + case SouthGravity: + dx = -(c->w / 2) + c->border; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + dx = -(c->w + c->border); + break; + default: + break; } - else - c->maxw = c->maxh = 0; - if(c->flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; + + if(invert) { + dx = -dx; + dy = -dy; } - else - c->minw = c->minh = 0; - if(c->flags & PWinGravity) - c->grav = size.win_gravity; - else - c->grav = NorthWestGravity; + c->x += dx; + c->y += dy; } void @@ -109,26 +173,21 @@ higher(Client *c) } void -lower(Client *c) +killclient(Arg *arg) { - XLowerWindow(dpy, c->title); - XLowerWindow(dpy, c->win); + if(!sel) + return; + if(sel->proto & WM_PROTOCOL_DELWIN) + sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); + else + XKillClient(dpy, sel->win); } void -focus(Client *c) +lower(Client *c) { - Client *old = sel; - XEvent ev; - - XFlush(dpy); - sel = c; - if(old && old != c) - drawtitle(old); - drawtitle(c); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XFlush(dpy); - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + XLowerWindow(dpy, c->title); + XLowerWindow(dpy, c->win); } void @@ -195,61 +254,18 @@ manage(Window w, XWindowAttributes *wa) } void -gravitate(Client *c, Bool invert) +maximize(Arg *arg) { - int dx = 0, dy = 0; - - switch(c->grav) { - case StaticGravity: - case NorthWestGravity: - case NorthGravity: - case NorthEastGravity: - dy = c->border; - break; - case EastGravity: - case CenterGravity: - case WestGravity: - dy = -(c->h / 2) + c->border; - break; - case SouthEastGravity: - case SouthGravity: - case SouthWestGravity: - dy = -c->h; - break; - default: - break; - } - - switch (c->grav) { - case StaticGravity: - case NorthWestGravity: - case WestGravity: - case SouthWestGravity: - dx = c->border; - break; - case NorthGravity: - case CenterGravity: - case SouthGravity: - dx = -(c->w / 2) + c->border; - break; - case NorthEastGravity: - case EastGravity: - case SouthEastGravity: - dx = -(c->w + c->border); - break; - default: - break; - } - - if(invert) { - dx = -dx; - dy = -dy; - } - c->x += dx; - c->y += dy; + 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 resize(Client *c, Bool inc) { @@ -290,10 +306,70 @@ resize(Client *c, Bool inc) XFlush(dpy); } -static int -xerrordummy(Display *dsply, XErrorEvent *ee) +void +setsize(Client *c) { - return 0; + XSizeHints size; + long msize; + if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) + size.flags = PSize; + c->flags = size.flags; + if(c->flags & PBaseSize) { + c->basew = size.base_width; + c->baseh = size.base_height; + } + else + c->basew = c->baseh = 0; + if(c->flags & PResizeInc) { + c->incw = size.width_inc; + c->inch = size.height_inc; + } + else + c->incw = c->inch = 0; + if(c->flags & PMaxSize) { + c->maxw = size.max_width; + c->maxh = size.max_height; + } + else + c->maxw = c->maxh = 0; + if(c->flags & PMinSize) { + c->minw = size.min_width; + c->minh = size.min_height; + } + else + c->minw = c->minh = 0; + if(c->flags & PWinGravity) + c->grav = size.win_gravity; + else + c->grav = NorthWestGravity; +} + +void +settitle(Client *c) +{ + XTextProperty name; + int n; + char **list = NULL; + + name.nitems = 0; + c->name[0] = 0; + XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); + if(!name.nitems) + XGetWMName(dpy, c->win, &name); + if(!name.nitems) + return; + if(name.encoding == XA_STRING) + strncpy(c->name, (char *)name.value, sizeof(c->name)); + else { + if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success + && n > 0 && *list) + { + strncpy(c->name, *list, sizeof(c->name)); + XFreeStringList(list); + } + } + XFree(name.value); + resizetitle(c); } void @@ -325,26 +401,6 @@ unmanage(Client *c) focus(sel); } -Client * -getctitle(Window w) -{ - Client *c; - for(c = clients; c; c = c->next) - if(c->title == w) - return c; - return NULL; -} - -Client * -getclient(Window w) -{ - Client *c; - for(c = clients; c; c = c->next) - if(c->win == w) - return c; - return NULL; -} - void zoom(Arg *arg) { @@ -366,58 +422,3 @@ zoom(Arg *arg) 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 @@ -2,13 +2,34 @@ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ +#include "dwm.h" #include <stdio.h> #include <string.h> - #include <X11/Xlocale.h> -#include "dwm.h" +/* static functions */ + +static void +drawborder(void) +{ + XPoint points[5]; + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, dc.gc, dc.border); + points[0].x = dc.x; + points[0].y = dc.y; + points[1].x = dc.w - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = dc.h - 1; + points[3].x = -(dc.w - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(dc.h - 1); + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); +} + +/* extern functions */ void drawall() @@ -53,59 +74,6 @@ drawstatus() } void -drawtitle(Client *c) -{ - int i; - Bool istile = arrange == dotile; - - if(c == sel) { - drawstatus(); - 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], !istile, True); - } - } - dc.x += dc.w; - dc.w = textw(c->name); - drawtext(c->name, !istile, True); - XCopyArea(dpy, dc.drawable, c->title, dc.gc, - 0, 0, c->tw, c->th, 0, 0); - XFlush(dpy); -} - -static void -drawborder(void) -{ - XPoint points[5]; - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(dpy, dc.gc, dc.border); - points[0].x = dc.x; - points[0].y = dc.y; - points[1].x = dc.w - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = dc.h - 1; - points[3].x = -(dc.w - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(dc.h - 1); - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); -} - -void drawtext(const char *text, Bool invert, Bool border) { int x, y, w, h; @@ -155,6 +123,40 @@ drawtext(const char *text, Bool invert, Bool border) } } +void +drawtitle(Client *c) +{ + int i; + Bool istile = arrange == dotile; + + if(c == sel) { + drawstatus(); + 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], !istile, True); + } + } + dc.x += dc.w; + dc.w = textw(c->name); + drawtext(c->name, !istile, True); + XCopyArea(dpy, dc.drawable, c->title, dc.gc, + 0, 0, c->tw, c->th, 0, 0); + XFlush(dpy); +} + unsigned long getcolor(const char *colstr) { @@ -165,23 +167,6 @@ getcolor(const char *colstr) return color.pixel; } -unsigned int -textnw(char *text, unsigned int len) -{ - XRectangle r; - if(dc.font.set) { - XmbTextExtents(dc.font.set, text, len, NULL, &r); - return r.width; - } - return XTextWidth(dc.font.xfont, text, len); -} - -unsigned int -textw(char *text) -{ - return textnw(text, strlen(text)) + dc.font.height; -} - void setfont(const char *fontstr) { @@ -232,3 +217,20 @@ setfont(const char *fontstr) } dc.font.height = dc.font.ascent + dc.font.descent; } + +unsigned int +textnw(char *text, unsigned int len) +{ + XRectangle r; + if(dc.font.set) { + XmbTextExtents(dc.font.set, text, len, NULL, &r); + return r.width; + } + return XTextWidth(dc.font.xfont, text, len); +} + +unsigned int +textw(char *text) +{ + return textnw(text, strlen(text)) + dc.font.height; +} diff --git a/dwm.h b/dwm.h @@ -104,53 +104,52 @@ 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); extern void focus(Client *c); -extern void settitle(Client *c); -extern void resize(Client *c, Bool inc); -extern void setsize(Client *c); +extern void focusnext(Arg *arg); +extern void focusprev(Arg *arg); +extern Client *getclient(Window w); extern Client *getctitle(Window w); +extern void gravitate(Client *c, Bool invert); extern void higher(Client *c); +extern void killclient(Arg *arg); extern void lower(Client *c); -extern void gravitate(Client *c, Bool invert); -extern void zoom(Arg *arg); +extern void manage(Window w, XWindowAttributes *wa); extern void maximize(Arg *arg); -extern void focusprev(Arg *arg); -extern void focusnext(Arg *arg); -extern void killclient(Arg *arg); +extern void resize(Client *c, Bool inc); +extern void setsize(Client *c); +extern void settitle(Client *c); +extern void unmanage(Client *c); +extern void zoom(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); +extern void drawtitle(Client *c); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textnw(char *text, unsigned int len); extern unsigned int textw(char *text); -extern unsigned int texth(void); /* event.c */ extern void grabkeys(); /* main.c */ +extern int getproto(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); +extern int xerror(Display *dsply, XErrorEvent *ee); /* tag.c */ -extern Client *getnext(Client *c); -extern void settags(Client *c); +extern void appendtag(Arg *arg); extern void dofloat(Arg *arg); extern void dotile(Arg *arg); -extern void view(Arg *arg); -extern void appendtag(Arg *arg); +extern Client *getnext(Client *c); extern void replacetag(Arg *arg); +extern void settags(Client *c); +extern void view(Arg *arg); /* util.c */ -extern void eprint(const char *errstr, ...); extern void *emallocz(unsigned int size); +extern void eprint(const char *errstr, ...); extern void spawn(Arg *arg); diff --git a/event.c b/event.c @@ -2,17 +2,12 @@ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * 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" - #define ButtonMask (ButtonPressMask | ButtonReleaseMask) #define MouseMask (ButtonMask | PointerMotionMask) @@ -54,130 +49,10 @@ Key key[] = { /********** CUSTOMIZE **********/ -/* local functions */ -static void buttonpress(XEvent *e); -static void configurerequest(XEvent *e); -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); - -void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ConfigureRequest] = configurerequest, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [LeaveNotify] = leavenotify, - [Expose] = expose, - [KeyPress] = keypress, - [MapRequest] = maprequest, - [PropertyNotify] = propertynotify, - [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 -resizemouse(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 -movemouse(Client *c) -{ - XEvent ev; - int x1, y1, ocx, ocy, di; - unsigned int dui; - Window dummy; +/* static functions */ - 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 movemouse(Client *c); +static void resizemouse(Client *c); static void buttonpress(XEvent *e) @@ -280,15 +155,6 @@ enternotify(XEvent *e) } static void -leavenotify(XEvent *e) -{ - XCrossingEvent *ev = &e->xcrossing; - - if((ev->window == root) && !ev->same_screen) - issel = True; -} - -static void expose(XEvent *e) { XExposeEvent *ev = &e->xexpose; @@ -303,6 +169,32 @@ expose(XEvent *e) } 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 +leavenotify(XEvent *e) +{ + XCrossingEvent *ev = &e->xcrossing; + + if((ev->window == root) && !ev->same_screen) + issel = True; +} + +static void maprequest(XEvent *e) { XMapRequestEvent *ev = &e->xmaprequest; @@ -322,6 +214,40 @@ maprequest(XEvent *e) } static void +movemouse(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 propertynotify(XEvent *e) { XPropertyEvent *ev = &e->xproperty; @@ -355,6 +281,40 @@ propertynotify(XEvent *e) } static void +resizemouse(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 unmapnotify(XEvent *e) { Client *c; @@ -363,3 +323,33 @@ unmapnotify(XEvent *e) if((c = getclient(ev->window))) unmanage(c); } + +/* extern functions */ + +void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, + [ConfigureRequest] = configurerequest, + [DestroyNotify] = destroynotify, + [EnterNotify] = enternotify, + [LeaveNotify] = leavenotify, + [Expose] = expose, + [KeyPress] = keypress, + [MapRequest] = maprequest, + [PropertyNotify] = propertynotify, + [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); + } +} diff --git a/main.c b/main.c @@ -3,31 +3,17 @@ * See LICENSE file for license details. */ +#include "dwm.h" + #include <errno.h> -#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> - #include <X11/cursorfont.h> #include <X11/Xatom.h> #include <X11/Xproto.h> -#include "dwm.h" - -/********** CUSTOMIZE **********/ - -char *tags[TLast] = { - [Tscratch] = "scratch", - [Tdev] = "dev", - [Twww] = "www", - [Twork] = "work", -}; - -/********** CUSTOMIZE **********/ - -/* X structs */ Display *dpy; Window root, barwin; Atom wm_atom[WMLast], net_atom[NetLast]; @@ -48,8 +34,17 @@ static const char version[] = "dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; static int (*xerrorxlib)(Display *, XErrorEvent *); +/* static functions */ + static void -usage() { eprint("usage: dwm [-v]\n"); } +cleanup() +{ + while(sel) { + resize(sel, True); + unmanage(sel); + } + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); +} static void scan() @@ -73,22 +68,6 @@ scan() 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) { @@ -109,6 +88,19 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) return res; } +/* + * Startup Error handler to check if another window manager + * is already running. + */ +static int +xerrorstart(Display *dsply, XErrorEvent *ee) +{ + otherwm = True; + return -1; +} + +/* extern functions */ + int getproto(Window w) { @@ -144,15 +136,10 @@ sendevent(Window w, Atom a, long value) XFlush(dpy); } -/* - * Startup Error handler to check if another window manager - * is already running. - */ -static int -xerrorstart(Display *dsply, XErrorEvent *ee) +void +quit(Arg *arg) { - otherwm = True; - return -1; + running = False; } /* @@ -201,7 +188,7 @@ main(int argc, char *argv[]) exit(0); break; default: - usage(); + eprint("usage: dwm [-v]\n"); break; } } diff --git a/tag.c b/tag.c @@ -2,71 +2,39 @@ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ +#include "dwm.h" -#include <stdlib.h> -#include <stdio.h> #include <string.h> -#include <X11/Xatom.h> #include <X11/Xutil.h> -#include "dwm.h" +/********** CUSTOMIZE **********/ + +char *tags[TLast] = { + [Tscratch] = "scratch", + [Tdev] = "dev", + [Twww] = "www", + [Twork] = "work", +}; static Rule rule[] = { /* class instance tags dofloat */ { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, }; -void (*arrange)(Arg *) = dotile; +/********** CUSTOMIZE **********/ -Client * -getnext(Client *c) -{ - for(; c && !c->tags[tsel]; c = c->next); - return c; -} +/* extern functions */ + +void (*arrange)(Arg *) = dotile; void -settags(Client *c) +appendtag(Arg *arg) { - 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]; + if(!sel) 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, sizeof(rule[i].class)) - && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) - { - 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; + sel->tags[arg->i] = tags[arg->i]; arrange(NULL); - drawall(); } void @@ -147,14 +115,11 @@ dotile(Arg *arg) drawall(); } -void -appendtag(Arg *arg) +Client * +getnext(Client *c) { - if(!sel) - return; - - sel->tags[arg->i] = tags[arg->i]; - arrange(NULL); + for(; c && !c->tags[tsel]; c = c->next); + return c; } void @@ -169,3 +134,46 @@ replacetag(Arg *arg) appendtag(arg); } +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, sizeof(rule[i].class)) + && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) + { + 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(); +} diff --git a/util.c b/util.c @@ -2,24 +2,15 @@ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ +#include "dwm.h" #include <stdarg.h> #include <stdio.h> #include <stdlib.h> -#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> -#include "dwm.h" - -void -eprint(const char *errstr, ...) { - va_list ap; - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(1); -} +/* static functions */ static void bad_malloc(unsigned int size) @@ -29,6 +20,8 @@ bad_malloc(unsigned int size) exit(1); } +/* extern functions */ + void * emallocz(unsigned int size) { @@ -39,6 +32,15 @@ emallocz(unsigned int size) } void +eprint(const char *errstr, ...) { + va_list ap; + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(1); +} + +void spawn(Arg *arg) { char **argv = (char **)arg->argv;