static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
+static Monitor *createmon(void);
static void destroynotify(XEvent *e);
static void detach(Client *c);
static void detachstack(Client *c);
static void unfocus(Client *c);
static void unmanage(Client *c, Bool destroyed);
static void unmapnotify(XEvent *e);
-static void updategeom(void);
+static Bool updategeom(void);
static void updatebarpos(Monitor *m);
static void updatebars(void);
static void updatenumlockmask(void);
if(ev->window == root) {
sw = ev->width;
sh = ev->height;
- updategeom();
- if(dc.drawable != 0)
- XFreePixmap(dpy, dc.drawable);
- dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
- updatebars();
- for(m = mons; m; m = m->next)
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
- arrange();
+ if(updategeom()) {
+ if(dc.drawable != 0)
+ XFreePixmap(dpy, dc.drawable);
+ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
+ updatebars();
+ for(m = mons; m; m = m->next)
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+ arrange();
+ }
}
}
XSync(dpy, False);
}
+Monitor *
+createmon(void) {
+ Monitor *m;
+
+ if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
+ m->tagset[0] = m->tagset[1] = 1;
+ m->mfact = mfact;
+ m->showbar = showbar;
+ m->topbar = topbar;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ m->ltsymbol = layouts[0].symbol;
+ return m;
+}
+
void
destroynotify(XEvent *e) {
Client *c;
return ret;
}
+#ifdef XINERAMA
+static Bool
+isuniquegeom(XineramaScreenInfo *unique, size_t len, XineramaScreenInfo *info) {
+ unsigned int i;
+
+ for(i = 0; i < len; i++)
+ if(unique[i].x_org == info->x_org && unique[i].y_org == info->y_org
+ && unique[i].width == info->width && unique[i].height == info->height)
+ return False;
+ return True;
+}
+#endif /* XINERAMA */
+
void
keypress(XEvent *e) {
unsigned int i;
m->by = -bh;
}
-void
+Bool
updategeom(void) {
- int i, n = 1;
- Client *c;
- Monitor *newmons = NULL, *m = NULL, *tm;
+ Bool dirty = False;
-#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++) {
- if(!(m = (Monitor *)malloc(sizeof(Monitor))))
- die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
- m->next = newmons;
- newmons = m;
- }
- /* initialise monitor(s) */
#ifdef XINERAMA
if(XineramaIsActive(dpy)) {
- for(i = 0, m = newmons; m; m = m->next, i++) {
- m->num = info[i].screen_number;
- m->mx = m->wx = info[i].x_org;
- m->my = m->wy = info[i].y_org;
- m->mw = m->ww = info[i].width;
- m->mh = m->wh = info[i].height;
- }
+ int i, j, n, nn;
+ Monitor *m;
+ XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
+ XineramaScreenInfo *unique = NULL;
+
+ info = XineramaQueryScreens(dpy, &nn);
+ for(n = 0, m = mons; m; m = m->next, n++);
+ /* only consider unique geometries as separate screens */
+ if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
+ die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
+ for(i = 0, j = 0; i < nn; i++)
+ if(isuniquegeom(unique, j, &info[i]))
+ memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
XFree(info);
+ nn = j;
+ if(n <= nn) {
+ for(i = 0; i < (nn - n); i++) { /* new monitors available */
+ for(m = mons; m && m->next; m = m->next);
+ if(m)
+ m->next = createmon();
+ else
+ mons = createmon();
+ }
+ for(i = 0, m = mons; i < nn && m; m = m->next, i++)
+ if(i >= n
+ || (unique[i].x_org != m->mx || unique[i].y_org != m->my
+ || unique[i].width != m->mw || unique[i].height != m->mh))
+ {
+ dirty = True;
+ m->num = unique[i].screen_number;
+ m->mx = m->wx = unique[i].x_org;
+ m->my = m->wy = unique[i].y_org;
+ m->mw = m->ww = unique[i].width;
+ m->mh = m->wh = unique[i].height;
+ updatebarpos(m);
+ }
+ }
+ else { /* less monitors available */
+ cleanup();
+ setup();
+ }
+ free(unique);
}
else
#endif /* XINERAMA */
/* default monitor setup */
{
- m->num = 0;
- m->mx = m->wx = 0;
- m->my = m->wy = 0;
- m->mw = m->ww = sw;
- m->mh = m->wh = sh;
- }
- /* bar geometry setup */
- for(m = newmons; m; m = m->next) {
- m->sel = m->stack = m->clients = NULL;
- m->seltags = 0;
- m->sellt = 0;
- m->tagset[0] = m->tagset[1] = 1;
- m->mfact = mfact;
- m->showbar = showbar;
- m->topbar = topbar;
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- m->ltsymbol = layouts[0].symbol;
- updatebarpos(m);
- }
- /* 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(!mons)
+ mons = createmon();
+ if(mons->mw != sw || mons->mh != sh) {
+ dirty = True;
+ mons->mw = mons->ww = sw;
+ mons->mh = mons->wh = sh;
+ updatebarpos(mons);
}
- /* select focused monitor */
- cleanupmons();
- selmon = mons = newmons;
- selmon = wintomon(root);
+ }
+ if(dirty) {
+ selmon = mons;
+ selmon = wintomon(root);
+ }
+ return dirty;
}
void