proceeded with cleaning up, sorting functions, etc

This commit is contained in:
Anselm R. Garbe 2006-07-15 17:00:56 +02:00
parent dba23062ba
commit adaa28a6e6
7 changed files with 540 additions and 551 deletions

423
client.c
View file

@ -2,21 +2,14 @@
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "dwm.h" /* static functions */
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 void static void
resizetitle(Client *c) resizetitle(Client *c)
@ -35,84 +28,19 @@ resizetitle(Client *c)
XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
} }
void static int
settitle(Client *c) xerrordummy(Display *dsply, XErrorEvent *ee)
{ {
XTextProperty name; return 0;
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 /* extern functions */
setsize(Client *c)
{
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 void
higher(Client *c) ban(Client *c)
{ {
XRaiseWindow(dpy, c->win); XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
XRaiseWindow(dpy, c->title); XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
}
void
lower(Client *c)
{
XLowerWindow(dpy, c->title);
XLowerWindow(dpy, c->win);
} }
void void
@ -131,6 +59,137 @@ focus(Client *c)
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
} }
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
focusprev(Arg *arg)
{
Client *c;
if(!sel)
return;
if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
higher(c);
focus(c);
}
}
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;
}
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;
}
void
higher(Client *c)
{
XRaiseWindow(dpy, c->win);
XRaiseWindow(dpy, c->title);
}
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);
}
void
lower(Client *c)
{
XLowerWindow(dpy, c->title);
XLowerWindow(dpy, c->win);
}
void void
manage(Window w, XWindowAttributes *wa) manage(Window w, XWindowAttributes *wa)
{ {
@ -195,61 +254,18 @@ manage(Window w, XWindowAttributes *wa)
} }
void void
gravitate(Client *c, Bool invert) maximize(Arg *arg)
{ {
int dx = 0, dy = 0; if(!sel)
return;
switch(c->grav) { sel->x = sx;
case StaticGravity: sel->y = sy + bh;
case NorthWestGravity: sel->w = sw - 2 * sel->border;
case NorthGravity: sel->h = sh - 2 * sel->border - bh;
case NorthEastGravity: higher(sel);
dy = c->border; resize(sel, False);
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;
} }
void void
resize(Client *c, Bool inc) resize(Client *c, Bool inc)
{ {
@ -290,10 +306,70 @@ resize(Client *c, Bool inc)
XFlush(dpy); XFlush(dpy);
} }
static int void
xerrordummy(Display *dsply, XErrorEvent *ee) 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 void
@ -325,26 +401,6 @@ unmanage(Client *c)
focus(sel); 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 void
zoom(Arg *arg) zoom(Arg *arg)
{ {
@ -366,58 +422,3 @@ zoom(Arg *arg)
arrange(NULL); arrange(NULL);
focus(sel); 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);
}

146
draw.c
View file

@ -2,13 +2,34 @@
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <X11/Xlocale.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 void
drawall() drawall()
@ -52,59 +73,6 @@ drawstatus()
XFlush(dpy); XFlush(dpy);
} }
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 void
drawtext(const char *text, Bool invert, Bool border) drawtext(const char *text, Bool invert, Bool border)
{ {
@ -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 unsigned long
getcolor(const char *colstr) getcolor(const char *colstr)
{ {
@ -165,23 +167,6 @@ getcolor(const char *colstr)
return color.pixel; 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 void
setfont(const char *fontstr) setfont(const char *fontstr)
{ {
@ -232,3 +217,20 @@ setfont(const char *fontstr)
} }
dc.font.height = dc.font.ascent + dc.font.descent; 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;
}

43
dwm.h
View file

@ -104,53 +104,52 @@ extern Client *clients, *sel;
/* client.c */ /* client.c */
extern void ban(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 focus(Client *c);
extern void settitle(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 manage(Window w, XWindowAttributes *wa);
extern void maximize(Arg *arg);
extern void resize(Client *c, Bool inc); extern void resize(Client *c, Bool inc);
extern void setsize(Client *c); extern void setsize(Client *c);
extern Client *getctitle(Window w); extern void settitle(Client *c);
extern void higher(Client *c); extern void unmanage(Client *c);
extern void lower(Client *c);
extern void gravitate(Client *c, Bool invert);
extern void zoom(Arg *arg); extern void zoom(Arg *arg);
extern void maximize(Arg *arg);
extern void focusprev(Arg *arg);
extern void focusnext(Arg *arg);
extern void killclient(Arg *arg);
/* draw.c */ /* draw.c */
extern void drawall(); extern void drawall();
extern void drawstatus(); extern void drawstatus();
extern void drawtitle(Client *c);
extern void drawtext(const char *text, Bool invert, Bool border); extern void drawtext(const char *text, Bool invert, Bool border);
extern void drawtitle(Client *c);
extern unsigned long getcolor(const char *colstr); extern unsigned long getcolor(const char *colstr);
extern void setfont(const char *fontstr); extern void setfont(const char *fontstr);
extern unsigned int textnw(char *text, unsigned int len); extern unsigned int textnw(char *text, unsigned int len);
extern unsigned int textw(char *text); extern unsigned int textw(char *text);
extern unsigned int texth(void);
/* event.c */ /* event.c */
extern void grabkeys(); extern void grabkeys();
/* main.c */ /* main.c */
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 getproto(Window w);
extern void quit(Arg *arg);
extern void sendevent(Window w, Atom a, long value);
extern int xerror(Display *dsply, XErrorEvent *ee);
/* tag.c */ /* tag.c */
extern Client *getnext(Client *c); extern void appendtag(Arg *arg);
extern void settags(Client *c);
extern void dofloat(Arg *arg); extern void dofloat(Arg *arg);
extern void dotile(Arg *arg); extern void dotile(Arg *arg);
extern void view(Arg *arg); extern Client *getnext(Client *c);
extern void appendtag(Arg *arg);
extern void replacetag(Arg *arg); extern void replacetag(Arg *arg);
extern void settags(Client *c);
extern void view(Arg *arg);
/* util.c */ /* util.c */
extern void eprint(const char *errstr, ...);
extern void *emallocz(unsigned int size); extern void *emallocz(unsigned int size);
extern void eprint(const char *errstr, ...);
extern void spawn(Arg *arg); extern void spawn(Arg *arg);

266
event.c
View file

@ -2,17 +2,12 @@
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include "dwm.h"
#define ButtonMask (ButtonPressMask | ButtonReleaseMask) #define ButtonMask (ButtonPressMask | ButtonReleaseMask)
#define MouseMask (ButtonMask | PointerMotionMask) #define MouseMask (ButtonMask | PointerMotionMask)
@ -54,130 +49,10 @@ Key key[] = {
/********** CUSTOMIZE **********/ /********** CUSTOMIZE **********/
/* local functions */ /* static 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 *) = { static void movemouse(Client *c);
[ButtonPress] = buttonpress, static void resizemouse(Client *c);
[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;
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 static void
buttonpress(XEvent *e) buttonpress(XEvent *e)
@ -279,15 +154,6 @@ enternotify(XEvent *e)
issel = True; issel = True;
} }
static void
leavenotify(XEvent *e)
{
XCrossingEvent *ev = &e->xcrossing;
if((ev->window == root) && !ev->same_screen)
issel = True;
}
static void static void
expose(XEvent *e) expose(XEvent *e)
{ {
@ -302,6 +168,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 static void
maprequest(XEvent *e) maprequest(XEvent *e)
{ {
@ -321,6 +213,40 @@ maprequest(XEvent *e)
manage(ev->window, &wa); manage(ev->window, &wa);
} }
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 static void
propertynotify(XEvent *e) propertynotify(XEvent *e)
{ {
@ -354,6 +280,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 static void
unmapnotify(XEvent *e) unmapnotify(XEvent *e)
{ {
@ -363,3 +323,33 @@ unmapnotify(XEvent *e)
if((c = getclient(ev->window))) if((c = getclient(ev->window)))
unmanage(c); 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);
}
}

71
main.c
View file

@ -3,31 +3,17 @@
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <errno.h> #include <errno.h>
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xproto.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; Display *dpy;
Window root, barwin; Window root, barwin;
Atom wm_atom[WMLast], net_atom[NetLast]; Atom wm_atom[WMLast], net_atom[NetLast];
@ -48,8 +34,17 @@ static const char version[] =
"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; "dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
static int (*xerrorxlib)(Display *, XErrorEvent *); static int (*xerrorxlib)(Display *, XErrorEvent *);
/* static functions */
static void static void
usage() { eprint("usage: dwm [-v]\n"); } cleanup()
{
while(sel) {
resize(sel, True);
unmanage(sel);
}
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
}
static void static void
scan() scan()
@ -73,22 +68,6 @@ scan()
XFree(wins); 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 static int
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) 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; 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 int
getproto(Window w) getproto(Window w)
{ {
@ -144,15 +136,10 @@ sendevent(Window w, Atom a, long value)
XFlush(dpy); XFlush(dpy);
} }
/* void
* Startup Error handler to check if another window manager quit(Arg *arg)
* is already running.
*/
static int
xerrorstart(Display *dsply, XErrorEvent *ee)
{ {
otherwm = True; running = False;
return -1;
} }
/* /*
@ -201,7 +188,7 @@ main(int argc, char *argv[])
exit(0); exit(0);
break; break;
default: default:
usage(); eprint("usage: dwm [-v]\n");
break; break;
} }
} }

118
tag.c
View file

@ -2,71 +2,39 @@
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "dwm.h" /********** CUSTOMIZE **********/
char *tags[TLast] = {
[Tscratch] = "scratch",
[Tdev] = "dev",
[Twww] = "www",
[Twork] = "work",
};
static Rule rule[] = { static Rule rule[] = {
/* class instance tags dofloat */ /* class instance tags dofloat */
{ "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, { "Firefox-bin", "Gecko", { [Twww] = "www" }, False },
}; };
/********** CUSTOMIZE **********/
/* extern functions */
void (*arrange)(Arg *) = dotile; void (*arrange)(Arg *) = dotile;
Client *
getnext(Client *c)
{
for(; c && !c->tags[tsel]; c = c->next);
return c;
}
void void
settags(Client *c) appendtag(Arg *arg)
{ {
XClassHint ch; if(!sel)
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; return;
}
if(XGetClassHint(dpy, c->win, &ch)) { sel->tags[arg->i] = tags[arg->i];
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); arrange(NULL);
drawall();
} }
void void
@ -147,14 +115,11 @@ dotile(Arg *arg)
drawall(); drawall();
} }
void Client *
appendtag(Arg *arg) getnext(Client *c)
{ {
if(!sel) for(; c && !c->tags[tsel]; c = c->next);
return; return c;
sel->tags[arg->i] = tags[arg->i];
arrange(NULL);
} }
void void
@ -169,3 +134,46 @@ replacetag(Arg *arg)
appendtag(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();
}

24
util.c
View file

@ -2,24 +2,15 @@
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
*/ */
#include "dwm.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include "dwm.h" /* static functions */
void
eprint(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
}
static void static void
bad_malloc(unsigned int size) bad_malloc(unsigned int size)
@ -29,6 +20,8 @@ bad_malloc(unsigned int size)
exit(1); exit(1);
} }
/* extern functions */
void * void *
emallocz(unsigned int size) emallocz(unsigned int size)
{ {
@ -38,6 +31,15 @@ emallocz(unsigned int size)
return res; return res;
} }
void
eprint(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
}
void void
spawn(Arg *arg) spawn(Arg *arg)
{ {