proceeded with cleaning up, sorting functions, etc

keyboard
Anselm R. Garbe 19 years ago
parent dba23062ba
commit adaa28a6e6
  1. 409
      client.c
  2. 146
      draw.c
  3. 39
      dwm.h
  4. 266
      event.c
  5. 71
      main.c
  6. 118
      tag.c
  7. 24
      util.c

@ -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,70 +28,141 @@ 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);
} }
static int
xerrordummy(Display *dsply, XErrorEvent *ee)
{
return 0;
}
/* extern functions */
void void
settitle(Client *c) ban(Client *c)
{ {
XTextProperty name; XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
int n; XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
char **list = NULL; }
name.nitems = 0; void
c->name[0] = 0; focus(Client *c)
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)); Client *old = sel;
XFreeStringList(list); 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(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
higher(c);
c->revert = sel;
focus(c);
} }
XFree(name.value);
resizetitle(c);
} }
void void
setsize(Client *c) focusprev(Arg *arg)
{ {
XSizeHints size; Client *c;
long msize;
if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) if(!sel)
size.flags = PSize; return;
c->flags = size.flags;
if(c->flags & PBaseSize) { if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
c->basew = size.base_width; higher(c);
c->baseh = size.base_height; focus(c);
} }
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; Client *
if(c->flags & PMaxSize) { getclient(Window w)
c->maxw = size.max_width; {
c->maxh = size.max_height; Client *c;
for(c = clients; c; c = c->next)
if(c->win == w)
return c;
return NULL;
} }
else
c->maxw = c->maxh = 0; Client *
if(c->flags & PMinSize) { getctitle(Window w)
c->minw = size.min_width; {
c->minh = size.min_height; Client *c;
for(c = clients; c; c = c->next)
if(c->title == w)
return c;
return NULL;
} }
else
c->minw = c->minh = 0; void
if(c->flags & PWinGravity) gravitate(Client *c, Bool invert)
c->grav = size.win_gravity; {
else int dx = 0, dy = 0;
c->grav = NorthWestGravity;
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 void
@ -109,26 +173,21 @@ higher(Client *c)
} }
void void
lower(Client *c) killclient(Arg *arg)
{ {
XLowerWindow(dpy, c->title); if(!sel)
XLowerWindow(dpy, c->win); return;
if(sel->proto & WM_PROTOCOL_DELWIN)
sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
else
XKillClient(dpy, sel->win);
} }
void void
focus(Client *c) lower(Client *c)
{ {
Client *old = sel; XLowerWindow(dpy, c->title);
XEvent ev; XLowerWindow(dpy, c->win);
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 void
@ -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

@ -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,31 +123,48 @@ drawtext(const char *text, Bool invert, Bool border)
} }
} }
unsigned long void
getcolor(const char *colstr) drawtitle(Client *c)
{ {
XColor color; int i;
Colormap cmap = DefaultColormap(dpy, screen); Bool istile = arrange == dotile;
XAllocNamedColor(dpy, cmap, colstr, &color, &color); if(c == sel) {
return color.pixel; drawstatus();
XUnmapWindow(dpy, c->title);
XSetWindowBorder(dpy, c->win, dc.fg);
return;
} }
unsigned int XSetWindowBorder(dpy, c->win, dc.bg);
textnw(char *text, unsigned int len) XMapWindow(dpy, c->title);
{
XRectangle r; dc.x = dc.y = 0;
if(dc.font.set) {
XmbTextExtents(dc.font.set, text, len, NULL, &r); dc.w = 0;
return r.width; 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);
} }
return XTextWidth(dc.font.xfont, text, len); }
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 int unsigned long
textw(char *text) getcolor(const char *colstr)
{ {
return textnw(text, strlen(text)) + dc.font.height; XColor color;
Colormap cmap = DefaultColormap(dpy, screen);
XAllocNamedColor(dpy, cmap, colstr, &color, &color);
return color.pixel;
} }
void void
@ -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;
}

39
dwm.h

@ -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 resize(Client *c, Bool inc); extern void focusprev(Arg *arg);
extern void setsize(Client *c); extern Client *getclient(Window w);
extern Client *getctitle(Window w); extern Client *getctitle(Window w);
extern void gravitate(Client *c, Bool invert);
extern void higher(Client *c); extern void higher(Client *c);
extern void killclient(Arg *arg);
extern void lower(Client *c); extern void lower(Client *c);
extern void gravitate(Client *c, Bool invert); extern void manage(Window w, XWindowAttributes *wa);
extern void zoom(Arg *arg);
extern void maximize(Arg *arg); extern void maximize(Arg *arg);
extern void focusprev(Arg *arg); extern void resize(Client *c, Bool inc);
extern void focusnext(Arg *arg); extern void setsize(Client *c);
extern void killclient(Arg *arg); extern void settitle(Client *c);
extern void unmanage(Client *c);
extern void zoom(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 int getproto(Window w);
extern void quit(Arg *arg); extern void quit(Arg *arg);
extern int xerror(Display *dsply, XErrorEvent *ee);
extern void sendevent(Window w, Atom a, long value); extern void sendevent(Window w, Atom a, long value);
extern int getproto(Window w); 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);

@ -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 *) = {
[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;
ocx = c->x; static void movemouse(Client *c);
ocy = c->y; static void resizemouse(Client *c);
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);
}
}

@ -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

@ -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 },
}; };
void (*arrange)(Arg *) = dotile; /********** CUSTOMIZE **********/
Client * /* extern functions */
getnext(Client *c)
{ void (*arrange)(Arg *) = dotile;
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)) {
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) sel->tags[arg->i] = tags[arg->i];
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();
}

@ -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)
{ {

Loading…
Cancel
Save