static void setmfact(const Arg *arg);
static void setup(void);
static void showhide(Client *c);
-static void sigchld(int signal);
+static void sigchld(int unused);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c);
-static void unmanage(Client *c);
+static void unmanage(Client *c, Bool destroyed);
static void unmapnotify(XEvent *e);
static void updategeom(void);
static void updatebarpos(Monitor *m);
/* adjust for aspect limits */
if(c->mina > 0 && c->maxa > 0) {
if(c->maxa < (float)*w / *h)
- *w = *h * c->maxa;
+ *w = *h * c->maxa + 0.5;
else if(c->mina < (float)*h / *w)
- *h = *w * c->mina;
+ *h = *w * c->mina + 0.5;
}
if(baseismin) { /* increment calculation requires this */
*w -= c->basew;
selmon->lt[selmon->sellt] = &foo;
for(m = mons; m; m = m->next)
while(m->stack)
- unmanage(m->stack);
+ unmanage(m->stack, False);
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
else
Monitor *m;
XConfigureEvent *ev = &e->xconfigure;
- if(ev->window == root && (ev->width != sw || ev->height != sh)) {
+ if(ev->window == root) {
sw = ev->width;
sh = ev->height;
updategeom();
c->w = ev->width;
if(ev->value_mask & CWHeight)
c->h = ev->height;
- if((c->x - m->mx + c->w) > m->mw && c->isfloating)
+ if((c->x + c->w) > m->mx + m->mw && c->isfloating)
c->x = m->mx + (m->mw / 2 - c->w / 2); /* center in x direction */
- if((c->y - m->my + c->h) > m->mh && c->isfloating)
+ if((c->y + c->h) > m->my + m->mh && c->isfloating)
c->y = m->my + (m->mh / 2 - c->h / 2); /* center in y direction */
if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
configure(c);
XDestroyWindowEvent *ev = &e->xdestroywindow;
if((c = wintoclient(ev->window)))
- unmanage(c);
+ unmanage(c, True);
}
void
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev);
}
- else
+ else {
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XSetCloseDownMode(dpy, DestroyAll);
XKillClient(dpy, selmon->sel->win);
+ XSync(dpy, False);
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ }
}
void
}
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
updatetitle(c);
- if(c == selmon->sel)
- drawbars();
+ if(c == c->mon->sel)
+ drawbar(c->mon);
}
}
}
int w;
XSetWindowAttributes wa;
+ /* clean up any zombies immediately */
+ sigchld(0);
+
/* init screen */
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
void
-sigchld(int signal) {
+sigchld(int unused) {
+ if(signal(SIGCHLD, sigchld) == SIG_ERR)
+ die("Can't install SIGCHLD handler");
while(0 < waitpid(-1, NULL, WNOHANG));
}
void
spawn(const Arg *arg) {
- signal(SIGCHLD, sigchld);
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
void
toggletag(const Arg *arg) {
- unsigned int mask;
+ unsigned int newtags;
if(!selmon->sel)
return;
- mask = selmon->sel->tags ^ (arg->ui & TAGMASK);
- if(mask) {
- selmon->sel->tags = mask;
+ newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+ if(newtags) {
+ selmon->sel->tags = newtags;
arrange();
}
}
void
toggleview(const Arg *arg) {
- unsigned int mask = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
- if(mask) {
- selmon->tagset[selmon->seltags] = mask;
+ if(newtagset) {
+ selmon->tagset[selmon->seltags] = newtagset;
arrange();
}
}
}
void
-unmanage(Client *c) {
+unmanage(Client *c, Bool destroyed) {
XWindowChanges wc;
- wc.border_width = c->oldbw;
/* The server grab construct avoids race conditions. */
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
detach(c);
detachstack(c);
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
+ if(!destroyed) {
+ wc.border_width = c->oldbw;
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
+ XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+ setclientstate(c, WithdrawnState);
+ XSync(dpy, False);
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ }
free(c);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
focus(NULL);
arrange();
}
XUnmapEvent *ev = &e->xunmap;
if((c = wintoclient(ev->window)))
- unmanage(c);
+ unmanage(c, False);
}
void
Monitor *newmons = NULL, *m = NULL, *tm;
#ifdef XINERAMA
+ int nn;
XineramaScreenInfo *info = NULL;
if(XineramaIsActive(dpy))
info = XineramaQueryScreens(dpy, &n);
+ for(i = 1, nn = n; i < n; i++)
+ if(info[i - 1].x_org == info[i].x_org && info[i - 1].y_org == info[i].y_org
+ && info[i - 1].width == info[i].width && info[i - 1].height == info[i].height)
+ --nn;
+ n = nn; /* we only consider unique geometries as separate screens */
#endif /* XINERAMA */
/* allocate monitor(s) for the new geometry setup */
for(i = 0; i < n; i++) {
else
c->minw = c->minh = 0;
if(size.flags & PAspect) {
- c->mina = (float)size.min_aspect.y / (float)size.min_aspect.x;
- c->maxa = (float)size.max_aspect.x / (float)size.max_aspect.y;
+ c->mina = (float)size.min_aspect.y / size.min_aspect.x;
+ c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
}
else
c->maxa = c->mina = 0.0;