proceeded with multihead/Xinerama support 62b18fb9
anselm@anselm1 · 2007-12-22 14:30 3 file(s) · +158 −162
LICENSE +1 −0
5 5
© 2006-2007 Jukka Salmi <jukka at salmi dot ch>
6 6
© 2007 Premysl Hruby <dfenze at gmail dot com>
7 7
© 2007 Szabolcs Nagy <nszabolcs at gmail dot com>
8 +
© 2007 Christof Musik
8 9
9 10
Permission is hereby granted, free of charge, to any person obtaining a
10 11
copy of this software and associated documentation files (the "Software"),
config.def.h +5 −5
15 15
const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "www" };
16 16
Bool initags[LENGTH(tags)] = {[0] = True};
17 17
Rule rules[] = {
18 -
	/* class:instance:title regex	tags regex	isfloating */
19 -
	{ "Firefox",			"www",		False },
20 -
	{ "Gimp",			NULL,		True },
21 -
	{ "MPlayer",			NULL,		True },
22 -
	{ "Acroread",			NULL,		True },
18 +
	/* class:instance:title regex	tags regex	isfloating */	/* monitor */
19 +
	{ "Firefox",			"www",		False,		-1 },
20 +
	{ "Gimp",			NULL,		True,		-1 },
21 +
	{ "MPlayer",			NULL,		True,		-1 },
22 +
	{ "Acroread",			NULL,		True,		-1 },
23 23
};
24 24
25 25
/* layout(s) */
dwm.c +152 −157
117 117
} Regs;
118 118
119 119
typedef struct {
120 -
	int id;
120 +
	int screen;
121 +
	Window root;
121 122
	Window barwin;
122 -
//TODO: Window root;
123 -
//TODO: int screen;
124 123
	int sx, sy, sw, sh, wax, way, wah, waw;
125 124
	DC dc;
126 125
	Bool *seltags;
158 157
void focusnext(const char *arg);
159 158
void focusprev(const char *arg);
160 159
Client *getclient(Window w);
161 -
unsigned long getcolor(const char *colstr);
160 +
unsigned long getcolor(const char *colstr, int screen);
162 161
long getstate(Window w);
163 162
Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
164 163
void grabbuttons(Client *c, Bool focused);
170 169
Bool isvisible(Client *c, Monitor *m);
171 170
void keypress(XEvent *e);
172 171
void killclient(const char *arg);
173 -
void leavenotify(XEvent *e);
174 172
void manage(Window w, XWindowAttributes *wa);
175 173
void mappingnotify(XEvent *e);
176 174
void maprequest(XEvent *e);
215 213
216 214
/* variables */
217 215
char stext[256];
218 -
int mcount, screen;
216 +
int mcount = 1;
219 217
//double mwfact;
220 -
//int screen, sx, sy, sw, sh, wax, way, waw, wah;
221 218
int (*xerrorxlib)(Display *, XErrorEvent *);
222 219
unsigned int bh, bpos;
223 220
unsigned int blw = 0;
231 228
	[Expose] = expose,
232 229
	[FocusIn] = focusin,
233 230
	[KeyPress] = keypress,
234 -
	[LeaveNotify] = leavenotify,
235 231
	[MappingNotify] = mappingnotify,
236 232
	[MapRequest] = maprequest,
237 233
	[PropertyNotify] = propertynotify,
242 238
Bool dozoom = True;
243 239
Bool otherwm, readin;
244 240
Bool running = True;
245 -
//Bool selscreen = True;
246 241
Client *clients = NULL;
247 242
Client *sel = NULL;
248 243
Client *stack = NULL;
249 244
Cursor cursor[CurLast];
250 245
Display *dpy;
251 246
DC dc = {0};
252 -
Window root;
253 -
//Layout *layout = NULL;
254 -
//Window barwin, root;
255 247
Regs *regs = NULL;
256 248
Monitor *monitors;
257 249
int selmonitor = 0;
402 394
	XSetErrorHandler(xerrorstart);
403 395
404 396
	/* this causes an error if some other window manager is running */
405 -
	XSelectInput(dpy, root, SubstructureRedirectMask);
397 +
	XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
406 398
	XSync(dpy, False);
407 399
	if(otherwm)
408 400
		eprint("dwm: another window manager is already running\n");
426 418
			XFreeFontSet(dpy, m->dc.font.set);
427 419
		else
428 420
			XFreeFont(dpy, m->dc.font.xfont);
429 -
		XUngrabKey(dpy, AnyKey, AnyModifier, root);
421 +
		XUngrabKey(dpy, AnyKey, AnyModifier, m->root);
430 422
		XFreePixmap(dpy, m->dc.drawable);
431 423
		XFreeGC(dpy, m->dc.gc);
432 424
		XDestroyWindow(dpy, m->barwin);
487 479
	XConfigureEvent *ev = &e->xconfigure;
488 480
	Monitor *m = &monitors[selmonitor];
489 481
490 -
	if(ev->window == root && (ev->width != m->sw || ev->height != m->sh)) {
482 +
	if(ev->window == m->root && (ev->width != m->sw || ev->height != m->sh)) {
491 483
		m->sw = ev->width;
492 484
		m->sh = ev->height;
493 485
		XFreePixmap(dpy, dc.drawable);
494 -
		dc.drawable = XCreatePixmap(dpy, root, m->sw, bh, DefaultDepth(dpy, screen));
486 +
		dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen));
495 487
		XResizeWindow(dpy, m->barwin, m->sw, bh);
496 488
		updatebarpos(m);
497 489
		arrange();
582 574
			m->dc.w = textw(m, tags[i]);
583 575
			if(m->seltags[i]) {
584 576
				drawtext(m, tags[i], m->dc.sel);
585 -
				drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.sel);
577 +
				drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.sel);
586 578
			}
587 579
			else {
588 580
				drawtext(m, tags[i], m->dc.norm);
589 -
				drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.norm);
581 +
				drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.norm);
590 582
			}
591 583
			m->dc.x += m->dc.w;
592 584
		}
602 594
		drawtext(m, stext, m->dc.norm);
603 595
		if((m->dc.w = m->dc.x - x) > bh) {
604 596
			m->dc.x = x;
605 -
			if(sel && sel->monitor == m->id) {
597 +
			if(sel && sel->monitor == selmonitor) {
606 598
				drawtext(m, sel->name, m->dc.sel);
607 599
				drawsquare(m, False, sel->isfloating, m->dc.sel);
608 600
			}
686 678
687 679
void
688 680
enternotify(XEvent *e) {
681 +
	unsigned int i;
689 682
	Client *c;
690 683
	XCrossingEvent *ev = &e->xcrossing;
691 684
693 686
		return;
694 687
	if((c = getclient(ev->window)))
695 688
		focus(c);
696 -
	else if(ev->window == root) {
697 -
		selmonitor = True;
698 -
		focus(NULL);
689 +
	else {
690 +
		for(i = 0; i < mcount; i++)
691 +
			if(ev->window == monitors[i].root) {
692 +
				selmonitor = i;
693 +
				focus(NULL);
694 +
				break;
695 +
			}
699 696
	}
700 697
}
701 698
731 728
732 729
void
733 730
focus(Client *c) {
734 -
	Monitor *m = &monitors[monitorat(-1, -1)];
731 +
	Monitor *m = &monitors[c ? c->monitor : selmonitor];
735 732
	if(!c || (c && !isvisible(c, m)))
736 733
		for(c = stack; c && !isvisible(c, m); c = c->snext);
737 734
	if(sel && sel != c) {
746 743
	sel = c;
747 744
	drawbar();
748 745
	if(c) {
749 -
		XSetWindowBorder(dpy, c->win, monitors[c->monitor].dc.sel[ColBorder]);
746 +
		XSetWindowBorder(dpy, c->win, m->dc.sel[ColBorder]);
750 747
		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
751 -
		selmonitor = monitorat(c->x, c->y);
748 +
		selmonitor = c->monitor;
752 749
	}
753 750
	else {
754 -
		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
755 -
		selmonitor = monitorat(-1, -1);
751 +
		XSetInputFocus(dpy, m->root, RevertToPointerRoot, CurrentTime);
756 752
	}
757 753
}
758 754
807 803
}
808 804
809 805
unsigned long
810 -
getcolor(const char *colstr) {
806 +
getcolor(const char *colstr, int screen) {
811 807
	Colormap cmap = DefaultColormap(dpy, screen);
812 808
	XColor color;
813 809
899 895
900 896
void
901 897
grabkeys(void)  {
902 -
	unsigned int i;
898 +
	unsigned int i, j;
903 899
	KeyCode code;
900 +
	XModifierKeymap *modmap;
904 901
905 -
	XUngrabKey(dpy, AnyKey, AnyModifier, root);
906 -
	for(i = 0; i < LENGTH(keys); i++) {
907 -
		code = XKeysymToKeycode(dpy, keys[i].keysym);
908 -
		XGrabKey(dpy, code, keys[i].mod, root, True,
909 -
				GrabModeAsync, GrabModeAsync);
910 -
		XGrabKey(dpy, code, keys[i].mod | LockMask, root, True,
911 -
				GrabModeAsync, GrabModeAsync);
912 -
		XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True,
913 -
				GrabModeAsync, GrabModeAsync);
914 -
		XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True,
915 -
				GrabModeAsync, GrabModeAsync);
902 +
	/* init modifier map */
903 +
	modmap = XGetModifierMapping(dpy);
904 +
	for(i = 0; i < 8; i++)
905 +
		for(j = 0; j < modmap->max_keypermod; j++) {
906 +
			if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
907 +
				numlockmask = (1 << i);
908 +
		}
909 +
	XFreeModifiermap(modmap);
910 +
911 +
	for(i = 0; i < mcount; i++) {
912 +
		Monitor *m = &monitors[i];
913 +
		XUngrabKey(dpy, AnyKey, AnyModifier, m->root);
914 +
		for(j = 0; j < LENGTH(keys); j++) {
915 +
			code = XKeysymToKeycode(dpy, keys[j].keysym);
916 +
			XGrabKey(dpy, code, keys[j].mod, m->root, True,
917 +
					GrabModeAsync, GrabModeAsync);
918 +
			XGrabKey(dpy, code, keys[j].mod | LockMask, m->root, True,
919 +
					GrabModeAsync, GrabModeAsync);
920 +
			XGrabKey(dpy, code, keys[j].mod | numlockmask, m->root, True,
921 +
					GrabModeAsync, GrabModeAsync);
922 +
			XGrabKey(dpy, code, keys[j].mod | numlockmask | LockMask, m->root, True,
923 +
					GrabModeAsync, GrabModeAsync);
924 +
		}
916 925
	}
917 926
}
918 927
971 980
	Client *c;
972 981
973 982
	for(c = clients; c; c = c->next)
974 -
		if(c->tags[t] && c->monitor == m->id)
983 +
		if(c->tags[t] && c->monitor == selmonitor)
975 984
			return True;
976 985
	return False;
977 986
}
996 1005
	unsigned int i;
997 1006
998 1007
	for(i = 0; i < LENGTH(tags); i++)
999 -
		if(c->tags[i] && monitors[c->monitor].seltags[i] && m->id == c->monitor)
1008 +
		if(c->tags[i] && monitors[c->monitor].seltags[i] && c->monitor == selmonitor)
1000 1009
			return True;
1001 1010
	return False;
1002 1011
}
1038 1047
}
1039 1048
1040 1049
void
1041 -
leavenotify(XEvent *e) {
1042 -
	XCrossingEvent *ev = &e->xcrossing;
1043 -
1044 -
	if((ev->window == root) && !ev->same_screen) {
1045 -
		selmonitor = False;
1046 -
		focus(NULL);
1047 -
	}
1048 -
}
1049 -
1050 -
void
1051 1050
manage(Window w, XWindowAttributes *wa) {
1052 1051
	Client *c, *t = NULL;
1052 +
	Monitor *m = &monitors[selmonitor];
1053 +
	Status rettrans;
1053 1054
	Window trans;
1054 -
	Status rettrans;
1055 1055
	XWindowChanges wc;
1056 1056
1057 1057
	c = emallocz(sizeof(Client));
1059 1059
	c->win = w;
1060 1060
1061 1061
	applyrules(c);
1062 -
	Monitor *m = &monitors[c->monitor];
1063 1062
1064 -
	c->x = wa->x+m->sx;
1065 -
	c->y = wa->y+m->sy;
1063 +
	c->x = wa->x + m->sx;
1064 +
	c->y = wa->y + m->sy;
1066 1065
	c->w = wa->width;
1067 1066
	c->h = wa->height;
1068 1067
	c->oldborder = wa->border_width;
1142 1141
1143 1142
	ocx = nx = c->x;
1144 1143
	ocy = ny = c->y;
1145 -
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1144 +
	if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1146 1145
			None, cursor[CurMove], CurrentTime) != GrabSuccess)
1147 1146
		return;
1148 -
	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
1147 +
	XQueryPointer(dpy, monitors[selmonitor].root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
1149 1148
	for(;;) {
1150 1149
		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev);
1151 1150
		switch (ev.type) {
1232 1231
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
1233 1232
	XWindowChanges wc;
1234 1233
	Monitor scr = monitors[monitorat(x, y)];
1235 -
	c->monitor = scr.id;
1234 +
	c->monitor = monitorat(x, y);
1236 1235
1237 1236
	if(sizehints) {
1238 1237
		/* set minimum possible */
1305 1304
1306 1305
	ocx = c->x;
1307 1306
	ocy = c->y;
1308 -
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1307 +
	if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1309 1308
			None, cursor[CurResize], CurrentTime) != GrabSuccess)
1310 1309
		return;
1311 1310
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1);
1429 1428
1430 1429
void
1431 1430
scan(void) {
1432 -
	unsigned int i, num;
1431 +
	unsigned int i, j, num;
1433 1432
	Window *wins, d1, d2;
1434 1433
	XWindowAttributes wa;
1435 1434
1436 -
	wins = NULL;
1437 -
	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
1438 -
		for(i = 0; i < num; i++) {
1439 -
			if(!XGetWindowAttributes(dpy, wins[i], &wa)
1440 -
			|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
1441 -
				continue;
1442 -
			if(wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
1443 -
				manage(wins[i], &wa);
1435 +
	for(i = 0; i < mcount; i++) {
1436 +
		Monitor *m = &monitors[i];
1437 +
		wins = NULL;
1438 +
		if(XQueryTree(dpy, m->root, &d1, &d2, &wins, &num)) {
1439 +
			for(j = 0; j < num; j++) {
1440 +
				if(!XGetWindowAttributes(dpy, wins[j], &wa)
1441 +
				|| wa.override_redirect || XGetTransientForHint(dpy, wins[j], &d1))
1442 +
					continue;
1443 +
				if(wa.map_state == IsViewable || getstate(wins[j]) == IconicState)
1444 +
					manage(wins[j], &wa);
1445 +
			}
1446 +
			for(j = 0; j < num; j++) { /* now the transients */
1447 +
				if(!XGetWindowAttributes(dpy, wins[j], &wa))
1448 +
					continue;
1449 +
				if(XGetTransientForHint(dpy, wins[j], &d1)
1450 +
				&& (wa.map_state == IsViewable || getstate(wins[j]) == IconicState))
1451 +
					manage(wins[j], &wa);
1452 +
			}
1444 1453
		}
1445 -
		for(i = 0; i < num; i++) { /* now the transients */
1446 -
			if(!XGetWindowAttributes(dpy, wins[i], &wa))
1447 -
				continue;
1448 -
			if(XGetTransientForHint(dpy, wins[i], &d1)
1449 -
			&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
1450 -
				manage(wins[i], &wa);
1451 -
		}
1454 +
		if(wins)
1455 +
			XFree(wins);
1452 1456
	}
1453 -
	if(wins)
1454 -
		XFree(wins);
1455 1457
}
1456 1458
1457 1459
void
1513 1515
void
1514 1516
setup(void) {
1515 1517
	unsigned int i, j, k;
1516 -
	XModifierKeymap *modmap;
1518 +
	Monitor *m;
1517 1519
	XSetWindowAttributes wa;
1518 -
	int s = 1;
1519 -
	GC g;
1520 1520
	XineramaScreenInfo *info = NULL;
1521 1521
1522 1522
	/* init atoms */
1526 1526
	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
1527 1527
	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
1528 1528
	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
1529 -
	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
1530 -
			PropModeReplace, (unsigned char *) netatom, NetLast);
1531 1529
1532 1530
	/* init cursors */
1533 -
	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
1531 +
	wa.cursor = cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
1534 1532
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
1535 1533
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
1536 1534
1537 -
1538 -
	/* init modifier map */
1539 -
	modmap = XGetModifierMapping(dpy);
1540 -
	for(i = 0; i < 8; i++)
1541 -
		for(j = 0; j < modmap->max_keypermod; j++) {
1542 -
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
1543 -
			== XKeysymToKeycode(dpy, XK_Num_Lock))
1544 -
				numlockmask = (1 << i);
1545 -
		}
1546 -
	XFreeModifiermap(modmap);
1547 -
1548 -
	/* select for events */
1549 -
	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
1550 -
		| EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
1551 -
	wa.cursor = cursor[CurNormal];
1552 -
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
1553 -
	XSelectInput(dpy, root, wa.event_mask);
1554 -
1555 -
	/* grab keys */
1556 -
	grabkeys();
1557 -
1558 -
	/* init tags */
1559 -
	compileregs();
1560 -
1535 +
	// init screens/monitors first
1561 1536
	if (XineramaIsActive(dpy)) {
1562 -
		info = XineramaQueryScreens(dpy, &s);
1537 +
		info = XineramaQueryScreens(dpy, &mcount);
1563 1538
	}
1539 +
	mcount = 1;
1540 +
	monitors = emallocz(mcount * sizeof(Monitor));
1564 1541
1565 -
	monitors = emallocz(s*sizeof(Monitor));
1566 -
	mcount = s;
1542 +
	for(i = 0; i < mcount; i++) {
1543 +
		/* init geometry */
1544 +
		m = &monitors[i];
1567 1545
1568 -
	for(i = 0; i < s; i++) {
1569 -
		/* init geometry */
1570 -
		if (mcount != 1) {
1571 -
			monitors[i].sx = info[i].x_org;
1572 -
			monitors[i].sy = info[i].y_org;
1573 -
			monitors[i].sw = info[i].width;
1574 -
			monitors[i].sh = info[i].height;
1546 +
		m->screen = i;
1547 +
		m->root = RootWindow(dpy, i);
1548 +
1549 +
		if (mcount != 1) { // TODO: Xinerama
1550 +
			m->sx = info[i].x_org;
1551 +
			m->sy = info[i].y_org;
1552 +
			m->sw = info[i].width;
1553 +
			m->sh = info[i].height;
1575 1554
		}
1576 1555
		else {
1577 -
			monitors[i].sx = 0;
1578 -
			monitors[i].sy = 0;
1579 -
			monitors[i].sw = DisplayWidth(dpy, screen);
1580 -
			monitors[i].sh = DisplayHeight(dpy, screen);
1556 +
			m->sx = 0;
1557 +
			m->sy = 0;
1558 +
			m->sw = DisplayWidth(dpy, m->screen);
1559 +
			m->sh = DisplayHeight(dpy, m->screen);
1581 1560
		}
1582 1561
1583 -
		monitors[i].id = i;
1584 -
		monitors[i].seltags = emallocz(sizeof initags);
1585 -
		monitors[i].prevtags = emallocz(sizeof initags);
1562 +
		m->seltags = emallocz(sizeof initags);
1563 +
		m->prevtags = emallocz(sizeof initags);
1586 1564
1587 -
		memcpy(monitors[i].seltags, initags, sizeof initags);
1588 -
		memcpy(monitors[i].prevtags, initags, sizeof initags);
1565 +
		memcpy(m->seltags, initags, sizeof initags);
1566 +
		memcpy(m->prevtags, initags, sizeof initags);
1589 1567
1590 1568
		/* init appearance */
1591 -
		monitors[i].dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
1592 -
		monitors[i].dc.norm[ColBG] = getcolor(NORMBGCOLOR);
1593 -
		monitors[i].dc.norm[ColFG] = getcolor(NORMFGCOLOR);
1594 -
		monitors[i].dc.sel[ColBorder] = getcolor(SELBORDERCOLOR);
1595 -
		monitors[i].dc.sel[ColBG] = getcolor(SELBGCOLOR);
1596 -
		monitors[i].dc.sel[ColFG] = getcolor(SELFGCOLOR);
1597 -
		initfont(&(monitors[i]), FONT);
1598 -
		monitors[i].dc.h = bh = monitors[i].dc.font.height + 2;
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);
1575 +
		initfont(m, FONT);
1576 +
		m->dc.h = bh = m->dc.font.height + 2;
1599 1577
1600 1578
		/* init layouts */
1601 -
		monitors[i].mwfact = MWFACT;
1602 -
		monitors[i].layout = &layouts[0];
1579 +
		m->mwfact = MWFACT;
1580 +
		m->layout = &layouts[0];
1603 1581
		for(blw = k = 0; k < LENGTH(layouts); k++) {
1604 -
			j = textw(&monitors[i], layouts[k].symbol);
1582 +
			j = textw(m, layouts[k].symbol);
1605 1583
			if(j > blw)
1606 1584
				blw = j;
1607 1585
		}
1608 1586
1587 +
		// TODO: bpos per screen?
1609 1588
		bpos = BARPOS;
1610 1589
		wa.override_redirect = 1;
1611 1590
		wa.background_pixmap = ParentRelative;
1612 1591
		wa.event_mask = ButtonPressMask | ExposureMask;
1613 1592
1614 1593
		/* init bars */
1615 -
		monitors[i].barwin = XCreateWindow(dpy, root, monitors[i].sx, monitors[i].sy, monitors[i].sw, bh, 0,
1616 -
				DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
1594 +
		m->barwin = XCreateWindow(dpy, m->root, m->sx, m->sy, m->sw, bh, 0,
1595 +
				DefaultDepth(dpy, m->screen), CopyFromParent, DefaultVisual(dpy, m->screen),
1617 1596
				CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
1618 -
		XDefineCursor(dpy, monitors[i].barwin, cursor[CurNormal]);
1619 -
		updatebarpos(&monitors[i]);
1620 -
		XMapRaised(dpy, monitors[i].barwin);
1597 +
		XDefineCursor(dpy, m->barwin, cursor[CurNormal]);
1598 +
		updatebarpos(m);
1599 +
		XMapRaised(dpy, m->barwin);
1621 1600
		strcpy(stext, "dwm-"VERSION);
1622 -
		monitors[i].dc.drawable = XCreatePixmap(dpy, root, monitors[i].sw, bh, DefaultDepth(dpy, screen));
1623 -
		g = XCreateGC(dpy, root, 0, 0);
1624 -
		monitors[i].dc.gc = XCreateGC(dpy, root, 0, 0);
1625 -
		XSetLineAttributes(dpy, monitors[i].dc.gc, 1, LineSolid, CapButt, JoinMiter);
1626 -
		if(!monitors[i].dc.font.set)
1627 -
			XSetFont(dpy, monitors[i].dc.gc, monitors[i].dc.font.xfont->fid);
1601 +
		m->dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen));
1602 +
		m->dc.gc = XCreateGC(dpy, m->root, 0, 0);
1603 +
		XSetLineAttributes(dpy, m->dc.gc, 1, LineSolid, CapButt, JoinMiter);
1604 +
		if(!m->dc.font.set)
1605 +
			XSetFont(dpy, m->dc.gc, m->dc.font.xfont->fid);
1606 +
1607 +
		/* EWMH support per monitor */
1608 +
		XChangeProperty(dpy, m->root, netatom[NetSupported], XA_ATOM, 32,
1609 +
				PropModeReplace, (unsigned char *) netatom, NetLast);
1610 +
1611 +
		/* select for events */
1612 +
		wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
1613 +
				| EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
1614 +
		XChangeWindowAttributes(dpy, m->root, CWEventMask | CWCursor, &wa);
1615 +
		XSelectInput(dpy, m->root, wa.event_mask);
1628 1616
	}
1617 +
1618 +
	/* grab keys */
1619 +
	grabkeys();
1620 +
1621 +
	/* init tags */
1622 +
	compileregs();
1629 1623
}
1630 1624
1631 1625
void
1978 1972
monitorat(int x, int y) {
1979 1973
	int i;
1980 1974
1975 +
	return 0;
1981 1976
	if(!XineramaIsActive(dpy))
1982 1977
		return 0;
1983 1978
1984 1979
	if (x < 0 || y < 0) {
1985 1980
		Window win;
1986 1981
		unsigned int mask;
1987 -
		XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask);
1982 +
		XQueryPointer(dpy, DefaultRootWindow(dpy), &win, &win, &x, &y, &i, &i, &mask);
1988 1983
	}
1989 1984
1990 -
	for(i = 0; i < mcount; i++)
1991 -
		if((x < 0 || (x >= monitors[i].sx && x < monitors[i].sx + monitors[i].sw))
1992 -
				&& (y < 0 || (y >= monitors[i].sy && y < monitors[i].sy + monitors[i].sh)))
1985 +
	for(i = 0; i < mcount; i++) {
1986 +
		Monitor *m = &monitors[i];
1987 +
		if((x < 0 || (x >= m->sx && x < m->sx + m->sw))
1988 +
				&& (y < 0 || (y >= m->sy && y < m->sy + m->sh)))
1993 1989
		{
1994 1990
			return i;
1995 1991
		}
1992 +
	}
1996 1993
	return 0;
1997 1994
}
1998 1995
2011 2008
selectmonitor(const char *arg) {
2012 2009
	Monitor *m = &monitors[arg ? atoi(arg) : (monitorat(-1, -1)+1) % mcount];
2013 2010
2014 -
	XWarpPointer(dpy, None, root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2);
2011 +
	XWarpPointer(dpy, None, m->root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2);
2015 2012
	focus(NULL);
2016 2013
}
2017 2014
2020 2017
main(int argc, char *argv[]) {
2021 2018
	if(argc == 2 && !strcmp("-v", argv[1]))
2022 2019
		eprint("dwm-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, "
2023 -
		       "Jukka Salmi, Premysl Hruby, Szabolcs Nagy\n");
2020 +
		       "Jukka Salmi, Premysl Hruby, Szabolcs Nagy, Christof Musik\n");
2024 2021
	else if(argc != 1)
2025 2022
		eprint("usage: dwm [-v]\n");
2026 2023
2027 2024
	setlocale(LC_CTYPE, "");
2028 2025
	if(!(dpy = XOpenDisplay(0)))
2029 2026
		eprint("dwm: cannot open display\n");
2030 -
	screen = DefaultScreen(dpy);
2031 -
	root = RootWindow(dpy, screen);
2032 2027
2033 2028
	checkotherwm();
2034 2029
	setup();