diff options
| author | anselm@garbe.us <unknown> | 2012-07-08 09:43:11 +0200 | 
|---|---|---|
| committer | anselm@garbe.us <unknown> | 2012-07-08 09:43:11 +0200 | 
| commit | 940feed3146d6911c79a0a4469f6ede071a4773e (patch) | |
| tree | ef2698c097ec38b9f8f5dac5d4d10f2eaf3a0978 | |
| parent | 606b44179dfeec8d31930488aa91c8d4808235a7 (diff) | |
reverted to old updategeom() after several complains, we need to optimize the old way
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | dwm.c | 123 | 
2 files changed, 71 insertions, 54 deletions
| @@ -1,5 +1,5 @@  # dwm version -VERSION = 6.1 +VERSION = 6.0-tip  # Customize below to fit your system @@ -236,7 +236,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 void updategeom(void); +static Bool updategeom(void);  static void updatebarpos(Monitor *m);  static void updatebars(void);  static void updateclientlist(void); @@ -574,18 +574,23 @@ 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(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(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); +		}  	}  } @@ -1072,8 +1077,8 @@ initfont(const char *fontstr) {  static Bool  isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {  	while(n--) -		/* 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) +		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)  			return False;  	return True;  } @@ -1883,74 +1888,86 @@ updateclientlist() {  			                (unsigned char *) &(c->win), 1);  } -void +Bool  updategeom(void) { -	/* 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.*/ +	Bool dirty = False;  #ifdef XINERAMA  	if(XineramaIsActive(dpy)) { -		int i, j, n; +		int i, j, n, nn;  		Client *c; -		Monitor *m, *oldmons = mons; -		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n); +		Monitor *m; +		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);  		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) * n))) -			die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * n); -		for(i = 0, j = 0; i < n; i++) +		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); -		/* create new monitor structure */ -		n = j; -		mons = m = createmon(); /* new first monitor */ -		for(i = 1; i < n; i++) { -			m->next = createmon(); -			m = m->next; -		} -		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); +		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); +				}  		} -		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); +		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);  			} -			oldmons = m->next; -			cleanupmon(m);  		} +		free(unique);  	}  	else  #endif /* XINERAMA */  	/* default monitor setup */  	{ -		if(!mons) /* only true if !XINERAMA compile flag */ +		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);  		}  	} -	selmon = mons; -	selmon = wintomon(root); +	if(dirty) { +		selmon = mons; +		selmon = wintomon(root); +	} +	return dirty;  }  void | 
