Skip to content
This repository was archived by the owner on Oct 4, 2018. It is now read-only.

Commit

Permalink
new experimental updategeom() additions that should avoid several pro…
Browse files Browse the repository at this point in the history
…blems with Xinerama, this is EXPERIMENTAL and might break something, the algorithms in use are quite complex and cumbersome, patches and comments welcome
  • Loading branch information
garbeam committed Sep 18, 2009
1 parent 30c3627 commit fb559cd
Showing 1 changed file with 77 additions and 24 deletions.
101 changes: 77 additions & 24 deletions dwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ static void toggleview(const Arg *arg);
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);
Expand Down Expand Up @@ -535,14 +535,15 @@ configurenotify(XEvent *e) {
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();
}
}
}

Expand Down Expand Up @@ -1692,26 +1693,73 @@ updatebarpos(Monitor *m) {
m->by = -bh;
}

void
Bool
updategeom(void) {
int i, n = 1;
int i, j, nn = 1, n = 1;
Client *c;
Monitor *newmons = NULL, *m = NULL, *tm;

#ifdef XINERAMA
int nn;
XineramaScreenInfo *info = NULL;
Bool *flags = 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 */
flags = (Bool *)malloc(sizeof(Bool) * n);
for(i = 0; i < n; i++)
flags[i] = False;
/* next double-loop seeks any combination of retrieved Xinerama info
* with existing monitors, this is used to avoid unnecessary
* re-allocations of monitor structs */
for(i = 0, nn = n; i < n; i++)
for(j = 0, m = mons; m; m = m->next, j++)
if(!flags[j]) {
if((flags[j] = (
info[i].x_org == m->mx
&& info[i].y_org == m->my
&& info[i].width == m->mw
&& info[i].height == m->mh)
))
--nn;
}
if(nn == 0) { /* no need to re-allocate monitors */
j = 0;
for(i = 0, m = mons; m; m = m->next, i++) {
m->num = info[i].screen_number;
if(info[i].x_org != m->mx
|| info[i].y_org != m->my
|| info[i].width != m->mw
|| info[i].height != m->mh)
{
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;
updatebarpos(m);
j++;
}
}
XFree(info);
free(flags);
return j > 0;
}
/* next algorithm only considers unique geometries as separate screens */
for(i = 0; i < n; i++)
flags[i] = False; /* used for ignoring certain monitors */
for(i = 0, nn = n; i < n; i++)
for(j = 0; j < n; j++)
if(i != j && !flags[i]) {
if((flags[i] = (
info[i].x_org == info[j].x_org
&& info[i].y_org == info[j].y_org
&& info[i].width == info[j].width
&& info[i].height == info[j].height)
))
--nn;
}
#endif /* XINERAMA */
/* allocate monitor(s) for the new geometry setup */
for(i = 0; i < n; i++) {
for(i = 0; i < nn; i++) {
if(!(m = (Monitor *)malloc(sizeof(Monitor))))
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
m->next = newmons;
Expand All @@ -1720,14 +1768,18 @@ updategeom(void) {
/* 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;
for(i = 0, m = newmons; m && i < n; i++) {
if(!flags[i]) { /* only use screens that aren't dublettes */
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;
m = m->next;
}
}
XFree(info);
free(flags);
}
else
#endif /* XINERAMA */
Expand Down Expand Up @@ -1767,6 +1819,7 @@ updategeom(void) {
cleanupmons();
selmon = mons = newmons;
selmon = wintomon(root);
return True;
}

void
Expand Down

0 comments on commit fb559cd

Please sign in to comment.