/* See LICENSE file for copyright and license details.
*
* dynamic window manager is designed like any other X client as well. It is
/* See LICENSE file for copyright and license details.
*
* dynamic window manager is designed like any other X client as well. It is
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
Bool showbar;
Bool topbar;
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
Bool showbar;
Bool topbar;
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void movemouse(const Arg *arg);
static void maprequest(XEvent *e);
static void monocle(Monitor *m);
static void movemouse(const Arg *arg);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static void resize(Client *c, int x, int y, int w, int h);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static void resize(Client *c, int x, int y, int w, int h);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unmanage(Client *c);
static void unmapnotify(XEvent *e);
static void updategeom(void);
static void unmanage(Client *c);
static void unmapnotify(XEvent *e);
static void updategeom(void);
static void updatebars(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatebars(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static Atom wmatom[WMLast], netatom[NetLast];
static Bool otherwm;
static Bool running = True;
static Atom wmatom[WMLast], netatom[NetLast];
static Bool otherwm;
static Bool running = True;
- if(ev->window == selmon->barwin) {
+ /* focus monitor if necessary */
+ for(m = mons; m; m = m->next)
+ if(ev->window == m->barwin) {
+ if(m != selmon) {
+ unfocus(selmon->stack);
+ selmon = m;
+ focus(NULL);
+ }
+ break;
+ }
+ if(ev->window == selmon->barwin && ev->x >= selmon->btx) {
c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
configure(c);
c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
configure(c);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
}
else
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
}
else
- /*
- dc.w = TEXTW(m->symbol);
- drawtext(NULL, selmon == m ? dc.sel : dc.norm, False);
+ char buf[2];
+ buf[0] = m->screen_number + '0';
+ buf[1] = '\0';
+ dc.w = TEXTW(buf);
+ drawtext(buf, selmon == m ? dc.sel : dc.norm, True);
dc.w = TEXTW(tags[i]);
col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
drawtext(tags[i], col, urg & 1 << i);
dc.w = TEXTW(tags[i]);
col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
drawtext(tags[i], col, urg & 1 << i);
- if((dc.w = dc.x - x) > bh) {
- dc.x = x;
- if(sel) {
- drawtext(sel->name, dc.sel, False);
- drawsquare(sel->isfixed, sel->isfloating, False, dc.sel);
- }
- else
- drawtext(NULL, dc.norm, False);
- }
- dc.w = m->ww - x;
- drawtext(NULL, dc.norm, False);
+ if(m->sel) {
+ col = m == selmon ? dc.sel : dc.norm;
+ drawtext(m->sel->name, col, False);
+ drawsquare(m->sel->isfixed, m->sel->isfloating, False, col);
+ }
+ else
+ drawtext(NULL, dc.norm, False);
}
XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
XSync(dpy, False);
}
XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
XSync(dpy, False);
- if(!c || !ISVISIBLE((c->m), c))
- for(c = stack; c && !ISVISIBLE(selmon, c); c = c->snext);
- if(sel && sel != c) {
- grabbuttons(sel, False);
- XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
- }
+ if(!c || !ISVISIBLE(c))
+ for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
+ if(selmon->sel)
+ unfocus(selmon->sel);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
focusin(XEvent *e) { /* there are some broken focus acquiring clients */
XFocusChangeEvent *ev = &e->xfocus;
focusin(XEvent *e) { /* there are some broken focus acquiring clients */
XFocusChangeEvent *ev = &e->xfocus;
- if(sel && ev->window != sel->win)
- XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime);
+ if(selmon->sel && ev->window != selmon->sel->win)
+ XSetInputFocus(dpy, selmon->sel->win, RevertToPointerRoot, CurrentTime);
ev.xclient.message_type = wmatom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = wmatom[WMDelete];
ev.xclient.data.l[1] = CurrentTime;
ev.xclient.message_type = wmatom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = wmatom[WMDelete];
ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
+ XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev);
c->y = sy + sh - HEIGHT(c);
c->x = MAX(c->x, sx);
/* only fix client y-offset, if the client center might cover the bar */
c->y = sy + sh - HEIGHT(c);
c->x = MAX(c->x, sx);
/* only fix client y-offset, if the client center might cover the bar */
- c->y = MAX(c->y, ((selmon->by == 0) && (c->x + (c->w / 2) >= selmon->wx)
- && (c->x + (c->w / 2) < selmon->wx + selmon->ww)) ? bh : sy);
+ c->y = MAX(c->y, ((c->mon->by == 0) && (c->x + (c->w / 2) >= c->mon->wx)
+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : sy);
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw);
}
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw);
}
- XConfigureWindow(dpy, c->win,
- CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- if(m == selmon && (sel->isfloating || !lt[m->sellt]->arrange))
- XRaiseWindow(dpy, sel->win);
+ if(m->sel->isfloating || !lt[m->sellt]->arrange)
+ XRaiseWindow(dpy, m->sel->win);
- for(c = stack; c; c = c->snext)
- if(!c->isfloating && ISVISIBLE(m, c)) {
+ for(c = m->stack; c; c = c->snext)
+ if(!c->isfloating && ISVISIBLE(c)) {
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
wc.sibling = c->win;
}
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
wc.sibling = c->win;
}
XMoveWindow(dpy, c->win, c->x, c->y);
XMoveWindow(dpy, c->win, c->x, c->y);
resize(c, c->x, c->y, c->w, c->h);
showhide(c->snext);
}
resize(c, c->x, c->y, c->w, c->h);
showhide(c->snext);
}
- for(n = 0, c = nexttiled(m, clients); c; c = nexttiled(m, c->next), n++);
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
mw = m->mfact * m->ww;
resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw);
mw = m->mfact * m->ww;
resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw);
- for(i = 0, c = nexttiled(m, c->next); c; c = nexttiled(m, c->next), i++) {
+ for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n)
? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw));
if(h != m->wh)
resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n)
? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw));
if(h != m->wh)
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange();
}
void
togglefloating(const Arg *arg) {
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange();
}
void
togglefloating(const Arg *arg) {
- sel->isfloating = !sel->isfloating || sel->isfixed;
- if(sel->isfloating)
- resize(sel, sel->x, sel->y, sel->w, sel->h);
+ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+ if(selmon->sel->isfloating)
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h);
+void
+unfocus(Client *c) {
+ if(!c)
+ return;
+ grabbuttons(c, False);
+ XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+}
+
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
detach(c);
detachstack(c);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
detach(c);
detachstack(c);
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState);
free(c);
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState);
free(c);
if(XineramaIsActive(dpy)) {
for(i = 0, m = newmons; m; m = m->next, i++) {
m->screen_number = info[i].screen_number;
m->wx = info[i].x_org;
if(XineramaIsActive(dpy)) {
for(i = 0, m = newmons; m; m = m->next, i++) {
m->screen_number = info[i].screen_number;
m->wx = info[i].x_org;
- if(m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
- }
- else
- m->by = -bh;
- /* reassign all clients with same screen number */
- for(c = clients; c; c = c->next)
- if(c->m->screen_number == m->screen_number)
- c->m = m;
- /* reassign left over clients with disappeared screen number */
- for(c = clients; c; c = c->next)
- if(c->m->screen_number >= n)
- c->m = newmons;
+ /* reassign left over clients of disappeared monitors */
+ for(tm = mons; tm; tm = tm->next)
+ while(tm->clients) {
+ c = tm->clients;
+ tm->clients = c->next;
+ detachstack(c);
+ c->mon = newmons;
+ attach(c);
+ attachstack(c);
+ }
- if(!selmon) {
- selmon = newmons;
- int di, x, y;
- unsigned int dui;
- Window dummy;
- if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
- for(m = newmons; m; m = m->next)
- if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh)) {
- selmon = m;
- break;
- }
- }
+ selmon = newmons;
+ if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
+ for(m = newmons; m; m = m->next)
+ if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh)) {
+ selmon = m;
+ break;
+ }
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
}
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
}
- if(c == nexttiled(selmon, clients))
- if(!c || !(c = nexttiled(selmon, c->next)))
+ if(c == nexttiled(selmon->clients))
+ if(!c || !(c = nexttiled(c->next)))