diff options
| author | anselm@garbe.us <unknown> | 2012-06-23 10:12:46 +0200 | 
|---|---|---|
| committer | anselm@garbe.us <unknown> | 2012-06-23 10:12:46 +0200 | 
| commit | 20f6917910306bcb5275d726b01b42a3b5e868b4 (patch) | |
| tree | bdaa8ba91f24bee1e2d0b2becde2848cdc30a896 | |
| parent | 820cbb3545e60e4d2bad120fb6e691c80058a98c (diff) | |
drastically changed updategeom() handling, see comment in updategeom() for details
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | dwm.c | 123 | 
2 files changed, 54 insertions, 71 deletions
| @@ -1,5 +1,5 @@  # dwm version -VERSION = 6.0-tip +VERSION = 6.1  # Customize below to fit your system @@ -235,7 +235,7 @@ static void toggleview(const Arg *arg);  static void unfocus(Client *c, Bool setfocus);  static void unmanage(Client *c, Bool destroyed);  static void unmapnotify(XEvent *e); -static Bool updategeom(void); +static void updategeom(void);  static void updatebarpos(Monitor *m);  static void updatebars(void);  static void updateclientlist(void); @@ -573,23 +573,18 @@ void  configurenotify(XEvent *e) {  	Monitor *m;  	XConfigureEvent *ev = &e->xconfigure; -	Bool dirty; -	// TODO: updategeom handling sucks, needs to be simplified  	if(ev->window == root) { -		dirty = (sw != ev->width || sh != ev->height);  		sw = ev->width;  		sh = ev->height; -		if(updategeom() || dirty) { -			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); -			focus(NULL); -			arrange(NULL); -		} +		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); +		focus(NULL); +		arrange(NULL);  	}  } @@ -1076,8 +1071,8 @@ initfont(const char *fontstr) {  static Bool  isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {  	while(n--) -		if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org -		&& unique[n].width == info->width && unique[n].height == info->height) +		/* treat origin (x, y) as fixpoint for uniqueness only, first screen wins */ +		if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org)  			return False;  	return True;  } @@ -1887,86 +1882,74 @@ updateclientlist() {  			                (unsigned char *) &(c->win), 1);  } -Bool +void  updategeom(void) { -	Bool dirty = False; +	/* Starting with dwm 6.1 this function uses a new (simpler) strategy: +	 * whenever screen changes are reported, we destroy all monitors +	 * and recreate all unique origin monitors and add all clients to +	 * the first monitor, only. In several circumstances this may suck, +	 * but dealing with all corner-cases sucks even more.*/  #ifdef XINERAMA  	if(XineramaIsActive(dpy)) { -		int i, j, n, nn; +		int i, j, n;  		Client *c; -		Monitor *m; -		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); +		Monitor *m, *oldmons = mons; +		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n);  		XineramaScreenInfo *unique = NULL; -		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(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * n))) +			die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * n); +		for(i = 0, j = 0; i < n; 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 = i; -					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); -				} +		/* create new monitor structure */ +		n = j; +		mons = m = createmon(); /* new first monitor */ +		for(i = 1; i < n; i++) { +			m->next = createmon(); +			m = m->next;  		} -		else { /* less monitors available nn < n */ -			for(i = nn; i < n; i++) { -				for(m = mons; m && m->next; m = m->next); -				while(m->clients) { -					dirty = True; -					c = m->clients; -					m->clients = c->next; -					detachstack(c); -					c->mon = mons; -					attach(c); -					attachstack(c); -				} -				if(m == selmon) -					selmon = mons; -				cleanupmon(m); -			} +		for(i = 0, m = mons; i < n && m; m = m->next, i++) { +			m->num = i; +			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);  		}  		free(unique); +		/* re-attach old clients and cleanup old monitor structure */ +		while(oldmons) { +			m = oldmons; +			while(m->clients) { +				c = m->clients; +				m->clients = c->next; +				detachstack(c); +				c->mon = mons; +				attach(c); +				attachstack(c); +			} +			oldmons = m->next; +			cleanupmon(m); +		}  	}  	else  #endif /* XINERAMA */  	/* default monitor setup */  	{ -		if(!mons) +		if(!mons) /* only true if !XINERAMA compile flag */  			mons = createmon();  		if(mons->mw != sw || mons->mh != sh) { -			dirty = True;  			mons->mw = mons->ww = sw;  			mons->mh = mons->wh = sh;  			updatebarpos(mons);  		}  	} -	if(dirty) { -		selmon = mons; -		selmon = wintomon(root); -	} -	return dirty; +	selmon = mons; +	selmon = wintomon(root);  }  void | 
