*
* To understand everything else, start reading main().
*/
-#include "dwm.h"
-
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
+#include <X11/Xlib.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
-/* local typedefs */
+/* enums */
+enum { BarTop, BarBot, BarOff }; /* bar position */
+enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
+enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
+enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
+
+/* typedefs */
+typedef struct Client Client;
+struct Client {
+ char name[256];
+ int x, y, w, h;
+ int rx, ry, rw, rh; /* revert geometry */
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int minax, maxax, minay, maxay;
+ long flags;
+ unsigned int border, oldborder;
+ Bool isbanned, isfixed, ismax, isfloating, wasfloating;
+ Bool *tags;
+ Client *next;
+ Client *prev;
+ Client *snext;
+ Window win;
+};
+
+typedef struct {
+ int x, y, w, h;
+ unsigned long norm[ColLast];
+ unsigned long sel[ColLast];
+ Drawable drawable;
+ GC gc;
+ struct {
+ int ascent;
+ int descent;
+ int height;
+ XFontSet set;
+ XFontStruct *xfont;
+ } font;
+} DC; /* draw context */
+
+typedef struct {
+ unsigned long mod;
+ KeySym keysym;
+ void (*func)(const char *arg);
+ const char *arg;
+} Key;
+
+typedef struct {
+ const char *symbol;
+ void (*arrange)(void);
+} Layout;
+
typedef struct {
const char *prop;
const char *tags;
regex_t *tagregex;
} Regs;
+/* function declarations */
+void applyrules(Client *c);
+void arrange(void);
+void attach(Client *c);
+void attachstack(Client *c);
+void ban(Client *c);
+void buttonpress(XEvent *e);
+void checkotherwm(void);
+void cleanup(void);
+void compileregs(void);
+void configure(Client *c);
+void configurenotify(XEvent *e);
+void configurerequest(XEvent *e);
+void destroynotify(XEvent *e);
+void detach(Client *c);
+void detachstack(Client *c);
+void drawbar(void);
+void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]);
+void drawtext(const char *text, unsigned long col[ColLast]);
+void *emallocz(unsigned int size);
+void enternotify(XEvent *e);
+void eprint(const char *errstr, ...);
+void expose(XEvent *e);
+void floating(void); /* default floating layout */
+void focus(Client *c);
+void focusnext(const char *arg);
+void focusprev(const char *arg);
+Client *getclient(Window w);
+unsigned long getcolor(const char *colstr);
+long getstate(Window w);
+Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
+void grabbuttons(Client *c, Bool focused);
+unsigned int idxoftag(const char *tag);
+void initfont(const char *fontstr);
+Bool isarrange(void (*func)());
+Bool isoccupied(unsigned int t);
+Bool isprotodel(Client *c);
+Bool isvisible(Client *c);
+void keypress(XEvent *e);
+void killclient(const char *arg);
+void leavenotify(XEvent *e);
+void manage(Window w, XWindowAttributes *wa);
+void mappingnotify(XEvent *e);
+void maprequest(XEvent *e);
+void movemouse(Client *c);
+Client *nexttiled(Client *c);
+void propertynotify(XEvent *e);
+void quit(const char *arg);
+void resize(Client *c, int x, int y, int w, int h, Bool sizehints);
+void resizemouse(Client *c);
+void restack(void);
+void run(void);
+void scan(void);
+void setclientstate(Client *c, long state);
+void setlayout(const char *arg);
+void setmwfact(const char *arg);
+void setup(void);
+void spawn(const char *arg);
+void tag(const char *arg);
+unsigned int textnw(const char *text, unsigned int len);
+unsigned int textw(const char *text);
+void tile(void);
+void togglebar(const char *arg);
+void togglefloating(const char *arg);
+void togglemax(const char *arg);
+void toggletag(const char *arg);
+void toggleview(const char *arg);
+void unban(Client *c);
+void unmanage(Client *c);
+void unmapnotify(XEvent *e);
+void updatebarpos(void);
+void updatesizehints(Client *c);
+void updatetitle(Client *c);
+void view(const char *arg);
+void viewprevtag(const char *arg); /* views previous selected tags */
+int xerror(Display *dpy, XErrorEvent *ee);
+int xerrordummy(Display *dsply, XErrorEvent *ee);
+int xerrorstart(Display *dsply, XErrorEvent *ee);
+void zoom(const char *arg);
+
/* variables */
char stext[256];
double mwfact;
/* configuration, allows nested code to access above variables */
#include "config.h"
-/* Statically define the number of tags. */
-unsigned int ntags = sizeof tags / sizeof tags[0];
-Bool seltags[sizeof tags / sizeof tags[0]] = {[0] = True};
-Bool prevtags[sizeof tags / sizeof tags[0]] = {[0] = True};
-
-/* functions*/
+/* function implementations */
void
applyrules(Client *c) {
static char buf[512];
for(i = 0; i < nrules; i++)
if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) {
c->isfloating = rules[i].isfloating;
- for(j = 0; regs[i].tagregex && j < ntags; j++) {
+ for(j = 0; regs[i].tagregex && j < NTAGS; j++) {
if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
matched = True;
c->tags[j] = True;
if(barwin == ev->window) {
x = 0;
- for(i = 0; i < ntags; i++) {
+ for(i = 0; i < NTAGS; i++) {
x += textw(tags[i]);
if(ev->x < x) {
if(ev->button == Button1) {
movemouse(c);
}
else if(ev->button == Button2) {
- if(ISTILE && !c->isfixed && c->isfloating)
+ if((ISTILE) && !c->isfixed && c->isfloating)
togglefloating(NULL);
else
zoom(NULL);
int i, x;
dc.x = dc.y = 0;
- for(i = 0; i < ntags; i++) {
+ for(i = 0; i < NTAGS; i++) {
dc.w = textw(tags[i]);
if(seltags[i]) {
drawtext(tags[i], dc.sel);
idxoftag(const char *tag) {
unsigned int i;
- for(i = 0; i < ntags; i++)
- if(tags[i] == tag)
- return i;
- return 0;
+ for(i = 0; (i < NTAGS) && (tags[i] != tag); i++);
+ return (i < NTAGS) ? i : 0;
}
void
isvisible(Client *c) {
unsigned int i;
- for(i = 0; i < ntags; i++)
+ for(i = 0; i < NTAGS; i++)
if(c->tags[i] && seltags[i])
return True;
return False;
default: break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
- if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
+ if(!c->isfloating && (c->isfloating = (NULL != getclient(trans))))
arrange();
break;
case XA_WM_NORMAL_HINTS:
void
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
- double dx, dy, max, min, ratio;
XWindowChanges wc;
if(sizehints) {
setmwfact(const char *arg) {
double delta;
- if(!ISTILE)
+ if(!(ISTILE))
return;
/* arg handling, manipulate mwfact */
if(arg == NULL)
if(!sel)
return;
- for(i = 0; i < ntags; i++)
- sel->tags[i] = arg == NULL;
- i = idxoftag(arg);
- if(i >= 0 && i < ntags)
- sel->tags[i] = True;
+ for(i = 0; i < NTAGS; i++)
+ sel->tags[i] = (NULL == arg);
+ sel->tags[idxoftag(arg)] = True;
arrange();
}
else
nh = th - 2 * c->border;
}
- resize(c, nx, ny, nw, nh, RESIZEHINTS);
+ resize(c, nx, ny, nw, nh, True);
+ if((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw))
+ /* client doesn't accept size constraints */
+ resize(c, nx, ny, nw, nh, False);
if(n > 1 && th != wah)
ny = c->y + c->h + 2 * c->border;
}
return;
i = idxoftag(arg);
sel->tags[i] = !sel->tags[i];
- for(j = 0; j < ntags && !sel->tags[j]; j++);
- if(j == ntags)
- sel->tags[i] = True;
+ for(j = 0; j < NTAGS && !sel->tags[j]; j++);
+ if(j == NTAGS)
+ sel->tags[i] = True; /* at least one tag must be enabled */
arrange();
}
i = idxoftag(arg);
seltags[i] = !seltags[i];
- for(j = 0; j < ntags && !seltags[j]; j++);
- if(j == ntags)
+ for(j = 0; j < NTAGS && !seltags[j]; j++);
+ if(j == NTAGS)
seltags[i] = True; /* at least one tag must be viewed */
arrange();
}
unsigned int i;
memcpy(prevtags, seltags, sizeof seltags);
- for(i = 0; i < ntags; i++)
+ for(i = 0; i < NTAGS; i++)
seltags[i] = arg == NULL;
- i = idxoftag(arg);
- if(i >= 0 && i < ntags)
- seltags[i] = True;
+ seltags[idxoftag(arg)] = True;
arrange();
}
zoom(const char *arg) {
Client *c;
- if(!sel || !ISTILE || sel->isfloating)
+ if(!sel || !(ISTILE) || sel->isfloating)
return;
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))