reverted to old updategeom() after several complains, we need to optimize the old way 940feed3
anselm@garbe.us · 2012-07-08 09:43 2 file(s) · +71 −54
config.mk +1 −1
1 1
# dwm version
2 -
VERSION = 6.1
2 +
VERSION = 6.0-tip
3 3
4 4
# Customize below to fit your system
5 5
dwm.c +70 −53
236 236
static void unfocus(Client *c, Bool setfocus);
237 237
static void unmanage(Client *c, Bool destroyed);
238 238
static void unmapnotify(XEvent *e);
239 -
static void updategeom(void);
239 +
static Bool updategeom(void);
240 240
static void updatebarpos(Monitor *m);
241 241
static void updatebars(void);
242 242
static void updateclientlist(void);
574 574
configurenotify(XEvent *e) {
575 575
	Monitor *m;
576 576
	XConfigureEvent *ev = &e->xconfigure;
577 +
	Bool dirty;
577 578
579 +
	// TODO: updategeom handling sucks, needs to be simplified
578 580
	if(ev->window == root) {
581 +
		dirty = (sw != ev->width || sh != ev->height);
579 582
		sw = ev->width;
580 583
		sh = ev->height;
581 -
		if(dc.drawable != 0)
582 -
			XFreePixmap(dpy, dc.drawable);
583 -
		dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
584 -
		updatebars();
585 -
		for(m = mons; m; m = m->next)
586 -
			XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
587 -
		focus(NULL);
588 -
		arrange(NULL);
584 +
		if(updategeom() || dirty) {
585 +
			if(dc.drawable != 0)
586 +
				XFreePixmap(dpy, dc.drawable);
587 +
			dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
588 +
			updatebars();
589 +
			for(m = mons; m; m = m->next)
590 +
				XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
591 +
			focus(NULL);
592 +
			arrange(NULL);
593 +
		}
589 594
	}
590 595
}
591 596
1072 1077
static Bool
1073 1078
isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {
1074 1079
	while(n--)
1075 -
		/* treat origin (x, y) as fixpoint for uniqueness only, first screen wins */
1076 -
		if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org)
1080 +
		if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
1081 +
		&& unique[n].width == info->width && unique[n].height == info->height)
1077 1082
			return False;
1078 1083
	return True;
1079 1084
}
1883 1888
			                (unsigned char *) &(c->win), 1);
1884 1889
}
1885 1890
1886 -
void
1891 +
Bool
1887 1892
updategeom(void) {
1888 -
	/* Starting with dwm 6.1 this function uses a new (simpler) strategy:
1889 -
	 * whenever screen changes are reported, we destroy all monitors
1890 -
	 * and recreate all unique origin monitors and add all clients to
1891 -
	 * the first monitor, only. In several circumstances this may suck,
1892 -
	 * but dealing with all corner-cases sucks even more.*/
1893 +
	Bool dirty = False;
1893 1894
1894 1895
#ifdef XINERAMA
1895 1896
	if(XineramaIsActive(dpy)) {
1896 -
		int i, j, n;
1897 +
		int i, j, n, nn;
1897 1898
		Client *c;
1898 -
		Monitor *m, *oldmons = mons;
1899 -
		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n);
1899 +
		Monitor *m;
1900 +
		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
1900 1901
		XineramaScreenInfo *unique = NULL;
1901 1902
1903 +
		for(n = 0, m = mons; m; m = m->next, n++);
1902 1904
		/* only consider unique geometries as separate screens */
1903 -
		if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * n)))
1904 -
			die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * n);
1905 -
		for(i = 0, j = 0; i < n; i++)
1905 +
		if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
1906 +
			die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
1907 +
		for(i = 0, j = 0; i < nn; i++)
1906 1908
			if(isuniquegeom(unique, j, &info[i]))
1907 1909
				memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
1908 1910
		XFree(info);
1909 -
		/* create new monitor structure */
1910 -
		n = j;
1911 -
		mons = m = createmon(); /* new first monitor */
1912 -
		for(i = 1; i < n; i++) {
1913 -
			m->next = createmon();
1914 -
			m = m->next;
1911 +
		nn = j;
1912 +
		if(n <= nn) {
1913 +
			for(i = 0; i < (nn - n); i++) { /* new monitors available */
1914 +
				for(m = mons; m && m->next; m = m->next);
1915 +
				if(m)
1916 +
					m->next = createmon();
1917 +
				else
1918 +
					mons = createmon();
1919 +
			}
1920 +
			for(i = 0, m = mons; i < nn && m; m = m->next, i++)
1921 +
				if(i >= n
1922 +
				|| (unique[i].x_org != m->mx || unique[i].y_org != m->my
1923 +
				    || unique[i].width != m->mw || unique[i].height != m->mh))
1924 +
				{
1925 +
					dirty = True;
1926 +
					m->num = i;
1927 +
					m->mx = m->wx = unique[i].x_org;
1928 +
					m->my = m->wy = unique[i].y_org;
1929 +
					m->mw = m->ww = unique[i].width;
1930 +
					m->mh = m->wh = unique[i].height;
1931 +
					updatebarpos(m);
1932 +
				}
1915 1933
		}
1916 -
		for(i = 0, m = mons; i < n && m; m = m->next, i++) {
1917 -
			m->num = i;
1918 -
			m->mx = m->wx = unique[i].x_org;
1919 -
			m->my = m->wy = unique[i].y_org;
1920 -
			m->mw = m->ww = unique[i].width;
1921 -
			m->mh = m->wh = unique[i].height;
1922 -
			updatebarpos(m);
1934 +
		else { /* less monitors available nn < n */
1935 +
			for(i = nn; i < n; i++) {
1936 +
				for(m = mons; m && m->next; m = m->next);
1937 +
				while(m->clients) {
1938 +
					dirty = True;
1939 +
					c = m->clients;
1940 +
					m->clients = c->next;
1941 +
					detachstack(c);
1942 +
					c->mon = mons;
1943 +
					attach(c);
1944 +
					attachstack(c);
1945 +
				}
1946 +
				if(m == selmon)
1947 +
					selmon = mons;
1948 +
				cleanupmon(m);
1949 +
			}
1923 1950
		}
1924 1951
		free(unique);
1925 -
		/* re-attach old clients and cleanup old monitor structure */
1926 -
		while(oldmons) {
1927 -
			m = oldmons;
1928 -
			while(m->clients) {
1929 -
				c = m->clients;
1930 -
				m->clients = c->next;
1931 -
				detachstack(c);
1932 -
				c->mon = mons;
1933 -
				attach(c);
1934 -
				attachstack(c);
1935 -
			}
1936 -
			oldmons = m->next;
1937 -
			cleanupmon(m);
1938 -
		}
1939 1952
	}
1940 1953
	else
1941 1954
#endif /* XINERAMA */
1942 1955
	/* default monitor setup */
1943 1956
	{
1944 -
		if(!mons) /* only true if !XINERAMA compile flag */
1957 +
		if(!mons)
1945 1958
			mons = createmon();
1946 1959
		if(mons->mw != sw || mons->mh != sh) {
1960 +
			dirty = True;
1947 1961
			mons->mw = mons->ww = sw;
1948 1962
			mons->mh = mons->wh = sh;
1949 1963
			updatebarpos(mons);
1950 1964
		}
1951 1965
	}
1952 -
	selmon = mons;
1953 -
	selmon = wintomon(root);
1966 +
	if(dirty) {
1967 +
		selmon = mons;
1968 +
		selmon = wintomon(root);
1969 +
	}
1970 +
	return dirty;
1954 1971
}
1955 1972
1956 1973
void