new experimental updategeom() additions that should avoid several problems with Xinerama, this is EXPERIMENTAL and might break something, the algorithms in use are quite complex and cumbersome, patches and comments welcome
This commit is contained in:
		
							parent
							
								
									e7300e0f6f
								
							
						
					
					
						commit
						82ec7a7ed4
					
				
							
								
								
									
										75
									
								
								dwm.c
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								dwm.c
									
									
									
									
									
								
							| @ -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); | ||||
| @ -535,7 +535,7 @@ configurenotify(XEvent *e) { | ||||
| 	if(ev->window == root) { | ||||
| 		sw = ev->width; | ||||
| 		sh = ev->height; | ||||
| 		updategeom(); | ||||
| 		if(updategeom()) { | ||||
| 			if(dc.drawable != 0) | ||||
| 				XFreePixmap(dpy, dc.drawable); | ||||
| 			dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); | ||||
| @ -544,6 +544,7 @@ configurenotify(XEvent *e) { | ||||
| 				XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); | ||||
| 			arrange(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| @ -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) | ||||
| 	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; | ||||
| 	n = nn; /* we only consider unique geometries as separate screens */ | ||||
| 			} | ||||
| 	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; | ||||
| @ -1720,14 +1768,18 @@ updategeom(void) { | ||||
| 	/* initialise monitor(s) */ | ||||
| #ifdef XINERAMA | ||||
| 	if(XineramaIsActive(dpy)) { | ||||
| 		for(i = 0, m = newmons; m; m = m->next, i++) { | ||||
| 		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 */ | ||||
| @ -1767,6 +1819,7 @@ updategeom(void) { | ||||
| 	cleanupmons(); | ||||
| 	selmon = mons = newmons; | ||||
| 	selmon = wintomon(root); | ||||
| 	return True; | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anselm R Garbe
						Anselm R Garbe