got initial Xinerama support working, though there is a lot work todo c2c54cc0
anselm@aab · 2008-02-11 15:55 2 file(s) · +90 −94
config.mk +2 −2
17 17
# flags
18 18
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
19 19
LDFLAGS = -s ${LIBS}
20 -
#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
21 -
#LDFLAGS = -g ${LIBS}
20 +
CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
21 +
LDFLAGS = -g ${LIBS}
22 22
23 23
# Solaris
24 24
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
dwm.c +88 −92
166 166
void initfont(Monitor*, const char *fontstr);
167 167
Bool isoccupied(Monitor *m, unsigned int t);
168 168
Bool isprotodel(Client *c);
169 -
Bool isvisible(Client *c, Monitor *m);
169 +
Bool isvisible(Client *c, int monitor);
170 170
void keypress(XEvent *e);
171 171
void killclient(const char *arg);
172 172
void manage(Window w, XWindowAttributes *wa);
173 173
void mappingnotify(XEvent *e);
174 174
void maprequest(XEvent *e);
175 175
void movemouse(Client *c);
176 -
Client *nexttiled(Client *c, Monitor *m);
176 +
Client *nexttiled(Client *c, int monitor);
177 177
void propertynotify(XEvent *e);
178 178
void quit(const char *arg);
179 179
void reapply(const char *arg);
207 207
int xerrordummy(Display *dsply, XErrorEvent *ee);
208 208
int xerrorstart(Display *dsply, XErrorEvent *ee);
209 209
void zoom(const char *arg);
210 -
int monitorat(int, int);
210 +
int monitorat(void);
211 211
void movetomonitor(const char *arg);
212 212
void selectmonitor(const char *arg);
213 213
214 214
/* variables */
215 215
char stext[256];
216 216
int mcount = 1;
217 -
//double mwfact;
218 217
int (*xerrorxlib)(Display *, XErrorEvent *);
219 218
unsigned int bh, bpos;
220 219
unsigned int blw = 0;
234 233
	[UnmapNotify] = unmapnotify
235 234
};
236 235
Atom wmatom[WMLast], netatom[NetLast];
236 +
Bool isxinerama = False;
237 237
Bool domwfact = True;
238 238
Bool dozoom = True;
239 239
Bool otherwm, readin;
288 288
	if(ch.res_name)
289 289
		XFree(ch.res_name);
290 290
	if(!matched_tag)
291 -
		memcpy(c->tags, monitors[monitorat(-1, -1)].seltags, sizeof initags);
291 +
		memcpy(c->tags, monitors[monitorat()].seltags, sizeof initags);
292 292
	if (!matched_monitor)
293 -
		c->monitor = monitorat(-1, -1);
293 +
		c->monitor = monitorat();
294 294
}
295 295
296 296
void
298 298
	Client *c;
299 299
300 300
	for(c = clients; c; c = c->next)
301 -
		if(isvisible(c, &monitors[c->monitor]))
301 +
		if(isvisible(c, c->monitor))
302 302
			unban(c);
303 303
		else
304 304
			ban(c);
336 336
	Client *c;
337 337
	XButtonPressedEvent *ev = &e->xbutton;
338 338
339 -
	Monitor *m = &monitors[monitorat(-1, -1)];
339 +
	Monitor *m = &monitors[monitorat()];
340 340
341 341
	if(ev->window == m->barwin) {
342 342
		x = 0;
516 516
			if((ev->value_mask & (CWX | CWY))
517 517
			&& !(ev->value_mask & (CWWidth | CWHeight)))
518 518
				configure(c);
519 -
			if(isvisible(c, &monitors[monitorat(-1,-1)]))
519 +
			if(isvisible(c, monitorat()))
520 520
				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
521 521
		}
522 522
		else
678 678
679 679
void
680 680
enternotify(XEvent *e) {
681 -
	unsigned int i;
682 681
	Client *c;
683 682
	XCrossingEvent *ev = &e->xcrossing;
684 683
685 -
	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
686 -
		return;
684 +
	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior);
685 +
		//return;
687 686
	if((c = getclient(ev->window)))
688 687
		focus(c);
689 688
	else {
690 -
		for(i = 0; i < mcount; i++)
691 -
			if(ev->window == monitors[i].root) {
692 -
				selmonitor = i;
693 -
				focus(NULL);
694 -
				break;
695 -
			}
689 +
		selmonitor = monitorat();
690 +
		fprintf(stderr, "updating selmonitor %d\n", selmonitor);
691 +
		focus(NULL);
696 692
	}
697 693
}
698 694
722 718
723 719
	domwfact = dozoom = False;
724 720
	for(c = clients; c; c = c->next)
725 -
		if(isvisible(c, &monitors[selmonitor]))
721 +
		if(isvisible(c, selmonitor))
726 722
			resize(c, c->x, c->y, c->w, c->h, True);
727 723
}
728 724
729 725
void
730 726
focus(Client *c) {
731 -
	Monitor *m = &monitors[c ? c->monitor : selmonitor];
732 -
	if(!c || (c && !isvisible(c, m)))
733 -
		for(c = stack; c && !isvisible(c, m); c = c->snext);
727 +
	Monitor *m;
728 +
729 +
	if(c)
730 +
		selmonitor = c->monitor;
731 +
	m = &monitors[selmonitor];
732 +
	if(!c || (c && !isvisible(c, selmonitor)))
733 +
		for(c = stack; c && !isvisible(c, c->monitor); c = c->snext);
734 734
	if(sel && sel != c) {
735 735
		grabbuttons(sel, False);
736 736
		XSetWindowBorder(dpy, sel->win, monitors[sel->monitor].dc.norm[ColBorder]);
763 763
void
764 764
focusnext(const char *arg) {
765 765
	Client *c;
766 -
	Monitor *m = &monitors[selmonitor];
767 766
768 767
	if(!sel)
769 768
		return;
770 -
	for(c = sel->next; c && !isvisible(c, m); c = c->next);
769 +
	for(c = sel->next; c && !isvisible(c, selmonitor); c = c->next);
771 770
	if(!c)
772 -
		for(c = clients; c && !isvisible(c, m); c = c->next);
771 +
		for(c = clients; c && !isvisible(c, selmonitor); c = c->next);
773 772
	if(c) {
774 773
		focus(c);
775 774
		restack();
779 778
void
780 779
focusprev(const char *arg) {
781 780
	Client *c;
782 -
	Monitor *m = &monitors[selmonitor];
783 781
784 782
	if(!sel)
785 783
		return;
786 -
	for(c = sel->prev; c && !isvisible(c, m); c = c->prev);
784 +
	for(c = sel->prev; c && !isvisible(c, selmonitor); c = c->prev);
787 785
	if(!c) {
788 786
		for(c = clients; c && c->next; c = c->next);
789 -
		for(; c && !isvisible(c, m); c = c->prev);
787 +
		for(; c && !isvisible(c, selmonitor); c = c->prev);
790 788
	}
791 789
	if(c) {
792 790
		focus(c);
1001 999
}
1002 1000
1003 1001
Bool
1004 -
isvisible(Client *c, Monitor *m) {
1002 +
isvisible(Client *c, int monitor) {
1005 1003
	unsigned int i;
1006 1004
1007 1005
	for(i = 0; i < LENGTH(tags); i++)
1008 -
		if(c->tags[i] && monitors[c->monitor].seltags[i] && c->monitor == selmonitor)
1006 +
		if(c->tags[i] && monitors[c->monitor].seltags[i] && c->monitor == monitor)
1009 1007
			return True;
1010 1008
	return False;
1011 1009
}
1049 1047
void
1050 1048
manage(Window w, XWindowAttributes *wa) {
1051 1049
	Client *c, *t = NULL;
1052 -
	Monitor *m = &monitors[selmonitor];
1050 +
	Monitor *m;
1053 1051
	Status rettrans;
1054 1052
	Window trans;
1055 1053
	XWindowChanges wc;
1060 1058
1061 1059
	applyrules(c);
1062 1060
1061 +
	m = &monitors[c->monitor];
1062 +
1063 1063
	c->x = wa->x + m->sx;
1064 1064
	c->y = wa->y + m->sy;
1065 1065
	c->w = wa->width;
1066 1066
	c->h = wa->height;
1067 1067
	c->oldborder = wa->border_width;
1068 1068
1069 -
	if (monitorat(c->x, c->y) != c->monitor) {
1070 -
		c->x = m->sx;
1071 -
		c->y = m->sy;
1072 -
	}
1073 -
1074 1069
	if(c->w == m->sw && c->h == m->sh) {
1075 1070
		c->x = m->sx;
1076 1071
		c->y = m->sy;
1132 1127
		manage(ev->window, &wa);
1133 1128
}
1134 1129
1130 +
int
1131 +
monitorat() {
1132 +
	int i, x, y;
1133 +
	Window win;
1134 +
	unsigned int mask;
1135 +
1136 +
	XQueryPointer(dpy, monitors[selmonitor].root, &win, &win, &x, &y, &i, &i, &mask);
1137 +
	for(i = 0; i < mcount; i++) {
1138 +
		fprintf(stderr, "checking monitor[%d]: %d %d %d %d\n", i, monitors[i].sx, monitors[i].sy, monitors[i].sw, monitors[i].sh);
1139 +
		if((x >= monitors[i].sx && x < monitors[i].sx + monitors[i].sw)
1140 +
		&& (y >= monitors[i].sy && y < monitors[i].sy + monitors[i].sh)) {
1141 +
			fprintf(stderr, "%d,%d -> %d\n", x, y, i);
1142 +
			return i;
1143 +
		}
1144 +
	}
1145 +
	fprintf(stderr, "?,? -> 0\n");
1146 +
	return 0;
1147 +
}
1148 +
1135 1149
void
1136 1150
movemouse(Client *c) {
1137 1151
	int x1, y1, ocx, ocy, di, nx, ny;
1160 1174
			XSync(dpy, False);
1161 1175
			nx = ocx + (ev.xmotion.x - x1);
1162 1176
			ny = ocy + (ev.xmotion.y - y1);
1163 -
			Monitor *m = &monitors[monitorat(nx, ny)];
1177 +
			Monitor *m = &monitors[monitorat()];
1164 1178
			if(abs(m->wax - nx) < SNAP)
1165 1179
				nx = m->wax;
1166 1180
			else if(abs((m->wax + m->waw) - (nx + c->w + 2 * c->border)) < SNAP)
1170 1184
			else if(abs((m->way + m->wah) - (ny + c->h + 2 * c->border)) < SNAP)
1171 1185
				ny = m->way + m->wah - c->h - 2 * c->border;
1172 1186
			resize(c, nx, ny, c->w, c->h, False);
1173 -
			memcpy(c->tags, monitors[monitorat(nx, ny)].seltags, sizeof initags);
1187 +
			memcpy(c->tags, monitors[monitorat()].seltags, sizeof initags);
1174 1188
			break;
1175 1189
		}
1176 1190
	}
1177 1191
}
1178 1192
1179 1193
Client *
1180 -
nexttiled(Client *c, Monitor *m) {
1181 -
	for(; c && (c->isfloating || !isvisible(c, m)); c = c->next);
1194 +
nexttiled(Client *c, int monitor) {
1195 +
	for(; c && (c->isfloating || !isvisible(c, monitor)); c = c->next);
1182 1196
	return c;
1183 1197
}
1184 1198
1230 1244
void
1231 1245
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
1232 1246
	XWindowChanges wc;
1233 -
	Monitor scr = monitors[monitorat(x, y)];
1234 -
	c->monitor = monitorat(x, y);
1247 +
	//Monitor scr = monitors[monitorat()];
1248 +
//	c->monitor = monitorat();
1235 1249
1236 1250
	if(sizehints) {
1237 1251
		/* set minimum possible */
1354 1368
			wc.sibling = sel->win;
1355 1369
		}
1356 1370
		for(i = 0; i < mcount; i++) {
1357 -
			for(c = nexttiled(clients, &monitors[i]); c; c = nexttiled(c->next, &monitors[i])) {
1371 +
			for(c = nexttiled(clients, i); c; c = nexttiled(c->next, i)) {
1358 1372
				if(c == sel)
1359 1373
					continue;
1360 1374
				XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
1467 1481
void
1468 1482
setlayout(const char *arg) {
1469 1483
	unsigned int i;
1470 -
	Monitor *m = &monitors[monitorat(-1, -1)];
1484 +
	Monitor *m = &monitors[monitorat()];
1471 1485
1472 1486
	if(!arg) {
1473 1487
		m->layout++;
1492 1506
setmwfact(const char *arg) {
1493 1507
	double delta;
1494 1508
1495 -
	Monitor *m = &monitors[monitorat(-1, -1)];
1509 +
	Monitor *m = &monitors[monitorat()];
1496 1510
1497 1511
	if(!domwfact)
1498 1512
		return;
1533 1547
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
1534 1548
1535 1549
	// init screens/monitors first
1536 -
	if (XineramaIsActive(dpy)) {
1550 +
	mcount = 1;
1551 +
	if((isxinerama = XineramaIsActive(dpy)))
1537 1552
		info = XineramaQueryScreens(dpy, &mcount);
1538 -
	}
1539 -
	mcount = 1;
1540 1553
	monitors = emallocz(mcount * sizeof(Monitor));
1541 1554
1542 1555
	for(i = 0; i < mcount; i++) {
1543 1556
		/* init geometry */
1544 1557
		m = &monitors[i];
1545 1558
1546 -
		m->screen = i;
1547 -
		m->root = RootWindow(dpy, i);
1559 +
		m->screen = isxinerama ? 0 : i;
1560 +
		m->root = RootWindow(dpy, m->screen);
1548 1561
1549 -
		if (mcount != 1) { // TODO: Xinerama
1562 +
		if (mcount != 1 && isxinerama) {
1550 1563
			m->sx = info[i].x_org;
1551 1564
			m->sy = info[i].y_org;
1552 1565
			m->sw = info[i].width;
1553 1566
			m->sh = info[i].height;
1567 +
			fprintf(stderr, "monitor[%d]: %d,%d,%d,%d\n", i, m->sx, m->sy, m->sw, m->sh);
1554 1568
		}
1555 1569
		else {
1556 1570
			m->sx = 0;
1566 1580
		memcpy(m->prevtags, initags, sizeof initags);
1567 1581
1568 1582
		/* init appearance */
1569 -
		m->dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR, i);
1570 -
		m->dc.norm[ColBG] = getcolor(NORMBGCOLOR, i);
1571 -
		m->dc.norm[ColFG] = getcolor(NORMFGCOLOR, i);
1572 -
		m->dc.sel[ColBorder] = getcolor(SELBORDERCOLOR, i);
1573 -
		m->dc.sel[ColBG] = getcolor(SELBGCOLOR, i);
1574 -
		m->dc.sel[ColFG] = getcolor(SELFGCOLOR, i);
1583 +
		m->dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR, m->screen);
1584 +
		m->dc.norm[ColBG] = getcolor(NORMBGCOLOR, m->screen);
1585 +
		m->dc.norm[ColFG] = getcolor(NORMFGCOLOR, m->screen);
1586 +
		m->dc.sel[ColBorder] = getcolor(SELBORDERCOLOR, m->screen);
1587 +
		m->dc.sel[ColBG] = getcolor(SELBGCOLOR, m->screen);
1588 +
		m->dc.sel[ColFG] = getcolor(SELFGCOLOR, m->screen);
1575 1589
		initfont(m, FONT);
1576 1590
		m->dc.h = bh = m->dc.font.height + 2;
1577 1591
1614 1628
		XChangeWindowAttributes(dpy, m->root, CWEventMask | CWCursor, &wa);
1615 1629
		XSelectInput(dpy, m->root, wa.event_mask);
1616 1630
	}
1631 +
	if(info)
1632 +
		XFree(info);
1617 1633
1618 1634
	/* grab keys */
1619 1635
	grabkeys();
1620 1636
1621 1637
	/* init tags */
1622 1638
	compileregs();
1639 +
1640 +
	selmonitor = monitorat();
1641 +
	fprintf(stderr, "selmonitor == %d\n", selmonitor);
1623 1642
}
1624 1643
1625 1644
void
1681 1700
1682 1701
	domwfact = dozoom = True;
1683 1702
1684 -
	nw = 0; /* gcc stupidity requires this */
1703 +
	nx = ny = nw = 0; /* gcc stupidity requires this */
1685 1704
1686 1705
	for (i = 0; i < mcount; i++) {
1687 1706
		Monitor *m = &monitors[i];
1688 1707
1689 -
		for(n = 0, c = nexttiled(clients, m); c; c = nexttiled(c->next, m))
1708 +
		for(n = 0, c = nexttiled(clients, i); c; c = nexttiled(c->next, i))
1690 1709
			n++;
1691 1710
1692 -
		for(j = 0, c = mc = nexttiled(clients, m); c; c = nexttiled(c->next, m)) {
1711 +
		for(j = 0, c = mc = nexttiled(clients, i); c; c = nexttiled(c->next, i)) {
1693 1712
			/* window geoms */
1694 1713
			mw = (n == 1) ? m->waw : m->mwfact * m->waw;
1695 1714
			th = (n > 1) ? m->wah / (n - 1) : 0;
1712 1731
				else
1713 1732
					nh = th - 2 * c->border;
1714 1733
			}
1734 +
			fprintf(stderr, "tile(%d, %d, %d, %d)\n", nx, ny, nw, nh);
1715 1735
			resize(c, nx, ny, nw, nh, RESIZEHINTS);
1716 1736
			if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw)))
1717 1737
				/* client doesn't accept size constraints */
1722 1742
			j++;
1723 1743
		}
1724 1744
	}
1745 +
	fprintf(stderr, "done\n");
1725 1746
}
1726 1747
void
1727 1748
togglebar(const char *arg) {
1729 1750
		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
1730 1751
	else
1731 1752
		bpos = BarOff;
1732 -
	updatebarpos(&monitors[monitorat(-1,-1)]);
1753 +
	updatebarpos(&monitors[monitorat()]);
1733 1754
	arrange();
1734 1755
}
1735 1756
1761 1782
toggleview(const char *arg) {
1762 1783
	unsigned int i, j;
1763 1784
1764 -
	Monitor *m = &monitors[monitorat(-1, -1)];
1785 +
	Monitor *m = &monitors[monitorat()];
1765 1786
1766 1787
	i = idxoftag(arg);
1767 1788
	m->seltags[i] = !m->seltags[i];
1931 1952
view(const char *arg) {
1932 1953
	unsigned int i;
1933 1954
1934 -
	Monitor *m = &monitors[monitorat(-1, -1)];
1955 +
	Monitor *m = &monitors[monitorat()];
1935 1956
1936 1957
	memcpy(m->prevtags, m->seltags, sizeof initags);
1937 1958
	for(i = 0; i < LENGTH(tags); i++)
1944 1965
viewprevtag(const char *arg) {
1945 1966
	static Bool tmp[LENGTH(tags)];
1946 1967
1947 -
	Monitor *m = &monitors[monitorat(-1, -1)];
1968 +
	Monitor *m = &monitors[monitorat()];
1948 1969
1949 1970
	memcpy(tmp, m->seltags, sizeof initags);
1950 1971
	memcpy(m->seltags, m->prevtags, sizeof initags);
1958 1979
1959 1980
	if(!sel || !dozoom || sel->isfloating)
1960 1981
		return;
1961 -
	if((c = sel) == nexttiled(clients, &monitors[c->monitor]))
1962 -
		if(!(c = nexttiled(c->next, &monitors[c->monitor])))
1982 +
	if((c = sel) == nexttiled(clients, c->monitor))
1983 +
		if(!(c = nexttiled(c->next, c->monitor)))
1963 1984
			return;
1964 1985
	detach(c);
1965 1986
	attach(c);
1967 1988
	arrange();
1968 1989
}
1969 1990
1970 -
int
1971 -
monitorat(int x, int y) {
1972 -
	int i;
1973 -
1974 -
	return 0;
1975 -
	if(!XineramaIsActive(dpy))
1976 -
		return 0;
1977 -
1978 -
	if (x < 0 || y < 0) {
1979 -
		Window win;
1980 -
		unsigned int mask;
1981 -
		XQueryPointer(dpy, DefaultRootWindow(dpy), &win, &win, &x, &y, &i, &i, &mask);
1982 -
	}
1983 -
1984 -
	for(i = 0; i < mcount; i++) {
1985 -
		Monitor *m = &monitors[i];
1986 -
		if((x < 0 || (x >= m->sx && x < m->sx + m->sw))
1987 -
				&& (y < 0 || (y >= m->sy && y < m->sy + m->sh)))
1988 -
		{
1989 -
			return i;
1990 -
		}
1991 -
	}
1992 -
	return 0;
1993 -
}
1994 -
1995 1991
void
1996 1992
movetomonitor(const char *arg) {
1997 1993
	if (sel) {
2005 2001
2006 2002
void
2007 2003
selectmonitor(const char *arg) {
2008 -
	Monitor *m = &monitors[arg ? atoi(arg) : (monitorat(-1, -1)+1) % mcount];
2004 +
	Monitor *m = &monitors[arg ? atoi(arg) : (monitorat()+1) % mcount];
2009 2005
2010 2006
	XWarpPointer(dpy, None, m->root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2);
2011 2007
	focus(NULL);