/* macros */
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
-#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
+#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
#define LENGTH(X) (sizeof X / sizeof X[0])
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- Bool isfixed, isfloating, isurgent, neverfocus, oldstate;
+ Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
Client *next;
Client *snext;
Monitor *mon;
static void monocle(Monitor *m);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
-static Monitor *ptrtomon(int x, int y);
+static void pop(Client *);
static void propertynotify(XEvent *e);
+static Monitor *ptrtomon(int x, int y);
static void quit(const Arg *arg);
static void resize(Client *c, int x, int y, int w, int h, Bool interact);
static void resizeclient(Client *c, int x, int y, int w, int h);
}
else if(ev->x < x + blw)
click = ClkLtSymbol;
- else if(ev->x > selmon->wx + selmon->ww - TEXTW(stext))
+ else if(ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
XFree(wmh);
}
+void
+clientmessage(XEvent *e) {
+ XClientMessageEvent *cme = &e->xclient;
+ Client *c = wintoclient(cme->window);
+
+ if(!c)
+ return;
+ if(cme->message_type == netatom[NetWMState] && cme->data.l[1] == netatom[NetWMFullscreen]) {
+ if(cme->data.l[0] && !c->isfullscreen) {
+ XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
+ c->isfullscreen = True;
+ c->oldstate = c->isfloating;
+ c->oldbw = c->bw;
+ c->bw = 0;
+ c->isfloating = True;
+ resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
+ XRaiseWindow(dpy, c->win);
+ }
+ else {
+ XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)0, 0);
+ c->isfullscreen = False;
+ c->isfloating = c->oldstate;
+ c->bw = c->oldbw;
+ c->x = c->oldx;
+ c->y = c->oldy;
+ c->w = c->oldw;
+ c->h = c->oldh;
+ resizeclient(c, c->x, c->y, c->w, c->h);
+ arrange(c->mon);
+ }
+ }
+ else if(cme->message_type == netatom[NetActiveWindow]) {
+ if(!ISVISIBLE(c)) {
+ c->mon->seltags ^= 1;
+ c->mon->tagset[c->mon->seltags] = c->tags;
+ }
+ pop(c);
+ }
+}
+
void
configure(Client *c) {
XConfigureEvent ce;
configurenotify(XEvent *e) {
Monitor *m;
XConfigureEvent *ev = &e->xconfigure;
+ Bool dirty;
if(ev->window == root) {
+ dirty = (sw != ev->width);
sw = ev->width;
sh = ev->height;
- if(updategeom()) {
+ if(updategeom() || dirty) {
if(dc.drawable != 0)
XFreePixmap(dpy, dc.drawable);
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
void
drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
int x;
- XGCValues gcv;
- XRectangle r = { dc.x, dc.y, dc.w, dc.h };
- gcv.foreground = col[invert ? ColBG : ColFG];
- XChangeGC(dpy, dc.gc, GCForeground, &gcv);
+ XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
x = (dc.font.ascent + dc.font.descent + 2) / 4;
- r.x = dc.x + 1;
- r.y = dc.y + 1;
- if(filled) {
- r.width = r.height = x + 1;
- XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
- }
- else if(empty) {
- r.width = r.height = x;
- XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
- }
+ if(filled)
+ XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1);
+ else if(empty)
+ XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x);
}
void
drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
char buf[256];
int i, x, y, h, len, olen;
- XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
- XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
+ XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
if(!text)
return;
olen = strlen(text);
void
enternotify(XEvent *e) {
+ Client *c;
Monitor *m;
XCrossingEvent *ev = &e->xcrossing;
if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
return;
+ c = wintoclient(ev->window);
if((m = wintomon(ev->window)) && m != selmon) {
unfocus(selmon->sel, True);
selmon = m;
}
+ else if(c == selmon->sel || c == NULL)
+ return;
focus((wintoclient(ev->window)));
}
applyrules(c);
}
/* geometry */
- c->x = c->oldx = wa->x + c->mon->wx;
- c->y = c->oldy = wa->y + c->mon->wy;
+ c->x = c->oldx = wa->x;
+ c->y = c->oldy = wa->y;
c->w = c->oldw = wa->width;
c->h = c->oldh = wa->height;
c->oldbw = wa->border_width;
return;
do {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch (ev.type) {
+ switch(ev.type) {
case ConfigureRequest:
case Expose:
case MapRequest:
return c;
}
-Monitor *
-ptrtomon(int x, int y) {
- Monitor *m;
-
- for(m = mons; m; m = m->next)
- if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh))
- return m;
- return selmon;
+void
+pop(Client *c) {
+ detach(c);
+ attach(c);
+ focus(c);
+ arrange(c->mon);
}
void
else if(ev->state == PropertyDelete)
return; /* ignore */
else if((c = wintoclient(ev->window))) {
- switch (ev->atom) {
+ switch(ev->atom) {
default: break;
case XA_WM_TRANSIENT_FOR:
if(!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
}
}
-void
-clientmessage(XEvent *e) {
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
+Monitor *
+ptrtomon(int x, int y) {
+ Monitor *m;
- if(!c)
- return;
- if(cme->message_type == netatom[NetWMState] && cme->data.l[1] == netatom[NetWMFullscreen]) {
- if(cme->data.l[0]) {
- XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
- c->oldstate = c->isfloating;
- c->oldbw = c->bw;
- c->bw = 0;
- c->isfloating = True;
- resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
- XRaiseWindow(dpy, c->win);
- }
- else {
- XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)0, 0);
- c->isfloating = c->oldstate;
- c->bw = c->oldbw;
- c->x = c->oldx;
- c->y = c->oldy;
- c->w = c->oldw;
- c->h = c->oldh;
- resizeclient(c, c->x, c->y, c->w, c->h);
- arrange(c->mon);
- }
- }
- else if(cme->message_type == netatom[NetActiveWindow]) {
- if(!ISVISIBLE(c)) {
- Arg a = { .ui = c->tags };
- view(&a);
- }
- detach(c);
- attach(c);
- focus(c);
- arrange(c->mon);
- }
+ for(m = mons; m; m = m->next)
+ if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh))
+ return m;
+ return selmon;
}
-
void
quit(const Arg *arg) {
running = False;
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+ netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
return;
if(ISVISIBLE(c)) { /* show clients top down */
XMoveWindow(dpy, c->win, c->x, c->y);
- if(!c->mon->lt[c->mon->sellt]->arrange || c->isfloating)
+ if((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
resize(c, c->x, c->y, c->w, c->h, False);
showhide(c->snext);
}
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
- exit(0);
+ exit(EXIT_SUCCESS);
}
}
void
updatebars(void) {
Monitor *m;
- XSetWindowAttributes wa;
-
- wa.override_redirect = True;
- wa.background_pixmap = ParentRelative;
- wa.event_mask = ButtonPressMask|ExposureMask;
+ XSetWindowAttributes wa = {
+ .override_redirect = True,
+ .background_pixmap = ParentRelative,
+ .event_mask = ButtonPressMask|ExposureMask
+ };
for(m = mons; m; m = m->next) {
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
Client *c = selmon->sel;
if(!selmon->lt[selmon->sellt]->arrange
- || selmon->lt[selmon->sellt]->arrange == monocle
|| (selmon->sel && selmon->sel->isfloating))
return;
if(c == nexttiled(selmon->clients))
if(!c || !(c = nexttiled(c->next)))
return;
- detach(c);
- attach(c);
- focus(c);
- arrange(c->mon);
+ pop(c);
}
int
main(int argc, char *argv[]) {
if(argc == 2 && !strcmp("-v", argv[1]))
- die("dwm-"VERSION", © 2006-2010 dwm engineers, see LICENSE for details\n");
+ die("dwm-"VERSION", © 2006-2011 dwm engineers, see LICENSE for details\n");
else if(argc != 1)
die("usage: dwm [-v]\n");
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
run();
cleanup();
XCloseDisplay(dpy);
- return 0;
+ return EXIT_SUCCESS;
}