proceeded with multihead/Xinerama support
This commit is contained in:
		
							parent
							
								
									e0d6451086
								
							
						
					
					
						commit
						62b18fb9d4
					
				
							
								
								
									
										1
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								LICENSE
									
									
									
									
									
								
							| @ -5,6 +5,7 @@ MIT/X Consortium License | |||||||
| © 2006-2007 Jukka Salmi <jukka at salmi dot ch> | © 2006-2007 Jukka Salmi <jukka at salmi dot ch> | ||||||
| © 2007 Premysl Hruby <dfenze at gmail dot com> | © 2007 Premysl Hruby <dfenze at gmail dot com> | ||||||
| © 2007 Szabolcs Nagy <nszabolcs at gmail dot com> | © 2007 Szabolcs Nagy <nszabolcs at gmail dot com> | ||||||
|  | © 2007 Christof Musik | ||||||
| 
 | 
 | ||||||
| Permission is hereby granted, free of charge, to any person obtaining a | Permission is hereby granted, free of charge, to any person obtaining a | ||||||
| copy of this software and associated documentation files (the "Software"), | copy of this software and associated documentation files (the "Software"), | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								config.def.h
									
									
									
									
									
								
							| @ -15,11 +15,11 @@ | |||||||
| const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "www" }; | const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "www" }; | ||||||
| Bool initags[LENGTH(tags)] = {[0] = True}; | Bool initags[LENGTH(tags)] = {[0] = True}; | ||||||
| Rule rules[] = { | Rule rules[] = { | ||||||
| 	/* class:instance:title regex	tags regex	isfloating */ | 	/* class:instance:title regex	tags regex	isfloating */	/* monitor */ | ||||||
| 	{ "Firefox",			"www",		False }, | 	{ "Firefox",			"www",		False,		-1 }, | ||||||
| 	{ "Gimp",			NULL,		True }, | 	{ "Gimp",			NULL,		True,		-1 }, | ||||||
| 	{ "MPlayer",			NULL,		True }, | 	{ "MPlayer",			NULL,		True,		-1 }, | ||||||
| 	{ "Acroread",			NULL,		True }, | 	{ "Acroread",			NULL,		True,		-1 }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* layout(s) */ | /* layout(s) */ | ||||||
|  | |||||||
							
								
								
									
										283
									
								
								dwm.c
									
									
									
									
									
								
							
							
						
						
									
										283
									
								
								dwm.c
									
									
									
									
									
								
							| @ -117,10 +117,9 @@ typedef struct { | |||||||
| } Regs; | } Regs; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| 	int id; | 	int screen; | ||||||
|  | 	Window root; | ||||||
| 	Window barwin; | 	Window barwin; | ||||||
| //TODO: Window root;
 |  | ||||||
| //TODO: int screen;
 |  | ||||||
| 	int sx, sy, sw, sh, wax, way, wah, waw; | 	int sx, sy, sw, sh, wax, way, wah, waw; | ||||||
| 	DC dc; | 	DC dc; | ||||||
| 	Bool *seltags; | 	Bool *seltags; | ||||||
| @ -158,7 +157,7 @@ void focusin(XEvent *e); | |||||||
| void focusnext(const char *arg); | void focusnext(const char *arg); | ||||||
| void focusprev(const char *arg); | void focusprev(const char *arg); | ||||||
| Client *getclient(Window w); | Client *getclient(Window w); | ||||||
| unsigned long getcolor(const char *colstr); | unsigned long getcolor(const char *colstr, int screen); | ||||||
| long getstate(Window w); | long getstate(Window w); | ||||||
| Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); | Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); | ||||||
| void grabbuttons(Client *c, Bool focused); | void grabbuttons(Client *c, Bool focused); | ||||||
| @ -170,7 +169,6 @@ Bool isprotodel(Client *c); | |||||||
| Bool isvisible(Client *c, Monitor *m); | Bool isvisible(Client *c, Monitor *m); | ||||||
| void keypress(XEvent *e); | void keypress(XEvent *e); | ||||||
| void killclient(const char *arg); | void killclient(const char *arg); | ||||||
| void leavenotify(XEvent *e); |  | ||||||
| void manage(Window w, XWindowAttributes *wa); | void manage(Window w, XWindowAttributes *wa); | ||||||
| void mappingnotify(XEvent *e); | void mappingnotify(XEvent *e); | ||||||
| void maprequest(XEvent *e); | void maprequest(XEvent *e); | ||||||
| @ -215,9 +213,8 @@ void selectmonitor(const char *arg); | |||||||
| 
 | 
 | ||||||
| /* variables */ | /* variables */ | ||||||
| char stext[256]; | char stext[256]; | ||||||
| int mcount, screen; | int mcount = 1; | ||||||
| //double mwfact;
 | //double mwfact;
 | ||||||
| //int screen, sx, sy, sw, sh, wax, way, waw, wah;
 |  | ||||||
| int (*xerrorxlib)(Display *, XErrorEvent *); | int (*xerrorxlib)(Display *, XErrorEvent *); | ||||||
| unsigned int bh, bpos; | unsigned int bh, bpos; | ||||||
| unsigned int blw = 0; | unsigned int blw = 0; | ||||||
| @ -231,7 +228,6 @@ void (*handler[LASTEvent]) (XEvent *) = { | |||||||
| 	[Expose] = expose, | 	[Expose] = expose, | ||||||
| 	[FocusIn] = focusin, | 	[FocusIn] = focusin, | ||||||
| 	[KeyPress] = keypress, | 	[KeyPress] = keypress, | ||||||
| 	[LeaveNotify] = leavenotify, |  | ||||||
| 	[MappingNotify] = mappingnotify, | 	[MappingNotify] = mappingnotify, | ||||||
| 	[MapRequest] = maprequest, | 	[MapRequest] = maprequest, | ||||||
| 	[PropertyNotify] = propertynotify, | 	[PropertyNotify] = propertynotify, | ||||||
| @ -242,16 +238,12 @@ Bool domwfact = True; | |||||||
| Bool dozoom = True; | Bool dozoom = True; | ||||||
| Bool otherwm, readin; | Bool otherwm, readin; | ||||||
| Bool running = True; | Bool running = True; | ||||||
| //Bool selscreen = True;
 |  | ||||||
| Client *clients = NULL; | Client *clients = NULL; | ||||||
| Client *sel = NULL; | Client *sel = NULL; | ||||||
| Client *stack = NULL; | Client *stack = NULL; | ||||||
| Cursor cursor[CurLast]; | Cursor cursor[CurLast]; | ||||||
| Display *dpy; | Display *dpy; | ||||||
| DC dc = {0}; | DC dc = {0}; | ||||||
| Window root; |  | ||||||
| //Layout *layout = NULL;
 |  | ||||||
| //Window barwin, root;
 |  | ||||||
| Regs *regs = NULL; | Regs *regs = NULL; | ||||||
| Monitor *monitors; | Monitor *monitors; | ||||||
| int selmonitor = 0; | int selmonitor = 0; | ||||||
| @ -402,7 +394,7 @@ checkotherwm(void) { | |||||||
| 	XSetErrorHandler(xerrorstart); | 	XSetErrorHandler(xerrorstart); | ||||||
| 
 | 
 | ||||||
| 	/* this causes an error if some other window manager is running */ | 	/* this causes an error if some other window manager is running */ | ||||||
| 	XSelectInput(dpy, root, SubstructureRedirectMask); | 	XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); | ||||||
| 	XSync(dpy, False); | 	XSync(dpy, False); | ||||||
| 	if(otherwm) | 	if(otherwm) | ||||||
| 		eprint("dwm: another window manager is already running\n"); | 		eprint("dwm: another window manager is already running\n"); | ||||||
| @ -426,7 +418,7 @@ cleanup(void) { | |||||||
| 			XFreeFontSet(dpy, m->dc.font.set); | 			XFreeFontSet(dpy, m->dc.font.set); | ||||||
| 		else | 		else | ||||||
| 			XFreeFont(dpy, m->dc.font.xfont); | 			XFreeFont(dpy, m->dc.font.xfont); | ||||||
| 		XUngrabKey(dpy, AnyKey, AnyModifier, root); | 		XUngrabKey(dpy, AnyKey, AnyModifier, m->root); | ||||||
| 		XFreePixmap(dpy, m->dc.drawable); | 		XFreePixmap(dpy, m->dc.drawable); | ||||||
| 		XFreeGC(dpy, m->dc.gc); | 		XFreeGC(dpy, m->dc.gc); | ||||||
| 		XDestroyWindow(dpy, m->barwin); | 		XDestroyWindow(dpy, m->barwin); | ||||||
| @ -487,11 +479,11 @@ configurenotify(XEvent *e) { | |||||||
| 	XConfigureEvent *ev = &e->xconfigure; | 	XConfigureEvent *ev = &e->xconfigure; | ||||||
| 	Monitor *m = &monitors[selmonitor]; | 	Monitor *m = &monitors[selmonitor]; | ||||||
| 
 | 
 | ||||||
| 	if(ev->window == root && (ev->width != m->sw || ev->height != m->sh)) { | 	if(ev->window == m->root && (ev->width != m->sw || ev->height != m->sh)) { | ||||||
| 		m->sw = ev->width; | 		m->sw = ev->width; | ||||||
| 		m->sh = ev->height; | 		m->sh = ev->height; | ||||||
| 		XFreePixmap(dpy, dc.drawable); | 		XFreePixmap(dpy, dc.drawable); | ||||||
| 		dc.drawable = XCreatePixmap(dpy, root, m->sw, bh, DefaultDepth(dpy, screen)); | 		dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen)); | ||||||
| 		XResizeWindow(dpy, m->barwin, m->sw, bh); | 		XResizeWindow(dpy, m->barwin, m->sw, bh); | ||||||
| 		updatebarpos(m); | 		updatebarpos(m); | ||||||
| 		arrange(); | 		arrange(); | ||||||
| @ -582,11 +574,11 @@ drawbar(void) { | |||||||
| 			m->dc.w = textw(m, tags[i]); | 			m->dc.w = textw(m, tags[i]); | ||||||
| 			if(m->seltags[i]) { | 			if(m->seltags[i]) { | ||||||
| 				drawtext(m, tags[i], m->dc.sel); | 				drawtext(m, tags[i], m->dc.sel); | ||||||
| 				drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.sel); | 				drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.sel); | ||||||
| 			} | 			} | ||||||
| 			else { | 			else { | ||||||
| 				drawtext(m, tags[i], m->dc.norm); | 				drawtext(m, tags[i], m->dc.norm); | ||||||
| 				drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.norm); | 				drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.norm); | ||||||
| 			} | 			} | ||||||
| 			m->dc.x += m->dc.w; | 			m->dc.x += m->dc.w; | ||||||
| 		} | 		} | ||||||
| @ -602,7 +594,7 @@ drawbar(void) { | |||||||
| 		drawtext(m, stext, m->dc.norm); | 		drawtext(m, stext, m->dc.norm); | ||||||
| 		if((m->dc.w = m->dc.x - x) > bh) { | 		if((m->dc.w = m->dc.x - x) > bh) { | ||||||
| 			m->dc.x = x; | 			m->dc.x = x; | ||||||
| 			if(sel && sel->monitor == m->id) { | 			if(sel && sel->monitor == selmonitor) { | ||||||
| 				drawtext(m, sel->name, m->dc.sel); | 				drawtext(m, sel->name, m->dc.sel); | ||||||
| 				drawsquare(m, False, sel->isfloating, m->dc.sel); | 				drawsquare(m, False, sel->isfloating, m->dc.sel); | ||||||
| 			} | 			} | ||||||
| @ -686,6 +678,7 @@ emallocz(unsigned int size) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| enternotify(XEvent *e) { | enternotify(XEvent *e) { | ||||||
|  | 	unsigned int i; | ||||||
| 	Client *c; | 	Client *c; | ||||||
| 	XCrossingEvent *ev = &e->xcrossing; | 	XCrossingEvent *ev = &e->xcrossing; | ||||||
| 
 | 
 | ||||||
| @ -693,9 +686,13 @@ enternotify(XEvent *e) { | |||||||
| 		return; | 		return; | ||||||
| 	if((c = getclient(ev->window))) | 	if((c = getclient(ev->window))) | ||||||
| 		focus(c); | 		focus(c); | ||||||
| 	else if(ev->window == root) { | 	else { | ||||||
| 		selmonitor = True; | 		for(i = 0; i < mcount; i++) | ||||||
|  | 			if(ev->window == monitors[i].root) { | ||||||
|  | 				selmonitor = i; | ||||||
| 				focus(NULL); | 				focus(NULL); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -731,7 +728,7 @@ floating(void) { /* default floating layout */ | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| focus(Client *c) { | focus(Client *c) { | ||||||
| 	Monitor *m = &monitors[monitorat(-1, -1)]; | 	Monitor *m = &monitors[c ? c->monitor : selmonitor]; | ||||||
| 	if(!c || (c && !isvisible(c, m))) | 	if(!c || (c && !isvisible(c, m))) | ||||||
| 		for(c = stack; c && !isvisible(c, m); c = c->snext); | 		for(c = stack; c && !isvisible(c, m); c = c->snext); | ||||||
| 	if(sel && sel != c) { | 	if(sel && sel != c) { | ||||||
| @ -746,13 +743,12 @@ focus(Client *c) { | |||||||
| 	sel = c; | 	sel = c; | ||||||
| 	drawbar(); | 	drawbar(); | ||||||
| 	if(c) { | 	if(c) { | ||||||
| 		XSetWindowBorder(dpy, c->win, monitors[c->monitor].dc.sel[ColBorder]); | 		XSetWindowBorder(dpy, c->win, m->dc.sel[ColBorder]); | ||||||
| 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | ||||||
| 		selmonitor = monitorat(c->x, c->y); | 		selmonitor = c->monitor; | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); | 		XSetInputFocus(dpy, m->root, RevertToPointerRoot, CurrentTime); | ||||||
| 		selmonitor = monitorat(-1, -1); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -807,7 +803,7 @@ getclient(Window w) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned long | unsigned long | ||||||
| getcolor(const char *colstr) { | getcolor(const char *colstr, int screen) { | ||||||
| 	Colormap cmap = DefaultColormap(dpy, screen); | 	Colormap cmap = DefaultColormap(dpy, screen); | ||||||
| 	XColor color; | 	XColor color; | ||||||
| 
 | 
 | ||||||
| @ -899,22 +895,35 @@ grabbuttons(Client *c, Bool focused) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| grabkeys(void)  { | grabkeys(void)  { | ||||||
| 	unsigned int i; | 	unsigned int i, j; | ||||||
| 	KeyCode code; | 	KeyCode code; | ||||||
|  | 	XModifierKeymap *modmap; | ||||||
| 
 | 
 | ||||||
| 	XUngrabKey(dpy, AnyKey, AnyModifier, root); | 	/* init modifier map */ | ||||||
| 	for(i = 0; i < LENGTH(keys); i++) { | 	modmap = XGetModifierMapping(dpy); | ||||||
| 		code = XKeysymToKeycode(dpy, keys[i].keysym); | 	for(i = 0; i < 8; i++) | ||||||
| 		XGrabKey(dpy, code, keys[i].mod, root, True, | 		for(j = 0; j < modmap->max_keypermod; j++) { | ||||||
|  | 			if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) | ||||||
|  | 				numlockmask = (1 << i); | ||||||
|  | 		} | ||||||
|  | 	XFreeModifiermap(modmap); | ||||||
|  | 
 | ||||||
|  | 	for(i = 0; i < mcount; i++) { | ||||||
|  | 		Monitor *m = &monitors[i]; | ||||||
|  | 		XUngrabKey(dpy, AnyKey, AnyModifier, m->root); | ||||||
|  | 		for(j = 0; j < LENGTH(keys); j++) { | ||||||
|  | 			code = XKeysymToKeycode(dpy, keys[j].keysym); | ||||||
|  | 			XGrabKey(dpy, code, keys[j].mod, m->root, True, | ||||||
| 					GrabModeAsync, GrabModeAsync); | 					GrabModeAsync, GrabModeAsync); | ||||||
| 		XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, | 			XGrabKey(dpy, code, keys[j].mod | LockMask, m->root, True, | ||||||
| 					GrabModeAsync, GrabModeAsync); | 					GrabModeAsync, GrabModeAsync); | ||||||
| 		XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True, | 			XGrabKey(dpy, code, keys[j].mod | numlockmask, m->root, True, | ||||||
| 					GrabModeAsync, GrabModeAsync); | 					GrabModeAsync, GrabModeAsync); | ||||||
| 		XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True, | 			XGrabKey(dpy, code, keys[j].mod | numlockmask | LockMask, m->root, True, | ||||||
| 					GrabModeAsync, GrabModeAsync); | 					GrabModeAsync, GrabModeAsync); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| unsigned int | unsigned int | ||||||
| idxoftag(const char *tag) { | idxoftag(const char *tag) { | ||||||
| @ -971,7 +980,7 @@ isoccupied(Monitor *m, unsigned int t) { | |||||||
| 	Client *c; | 	Client *c; | ||||||
| 
 | 
 | ||||||
| 	for(c = clients; c; c = c->next) | 	for(c = clients; c; c = c->next) | ||||||
| 		if(c->tags[t] && c->monitor == m->id) | 		if(c->tags[t] && c->monitor == selmonitor) | ||||||
| 			return True; | 			return True; | ||||||
| 	return False; | 	return False; | ||||||
| } | } | ||||||
| @ -996,7 +1005,7 @@ isvisible(Client *c, Monitor *m) { | |||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| 
 | 
 | ||||||
| 	for(i = 0; i < LENGTH(tags); i++) | 	for(i = 0; i < LENGTH(tags); i++) | ||||||
| 		if(c->tags[i] && monitors[c->monitor].seltags[i] && m->id == c->monitor) | 		if(c->tags[i] && monitors[c->monitor].seltags[i] && c->monitor == selmonitor) | ||||||
| 			return True; | 			return True; | ||||||
| 	return False; | 	return False; | ||||||
| } | } | ||||||
| @ -1037,21 +1046,12 @@ killclient(const char *arg) { | |||||||
| 		XKillClient(dpy, sel->win); | 		XKillClient(dpy, sel->win); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| leavenotify(XEvent *e) { |  | ||||||
| 	XCrossingEvent *ev = &e->xcrossing; |  | ||||||
| 
 |  | ||||||
| 	if((ev->window == root) && !ev->same_screen) { |  | ||||||
| 		selmonitor = False; |  | ||||||
| 		focus(NULL); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| manage(Window w, XWindowAttributes *wa) { | manage(Window w, XWindowAttributes *wa) { | ||||||
| 	Client *c, *t = NULL; | 	Client *c, *t = NULL; | ||||||
| 	Window trans; | 	Monitor *m = &monitors[selmonitor]; | ||||||
| 	Status rettrans; | 	Status rettrans; | ||||||
|  | 	Window trans; | ||||||
| 	XWindowChanges wc; | 	XWindowChanges wc; | ||||||
| 
 | 
 | ||||||
| 	c = emallocz(sizeof(Client)); | 	c = emallocz(sizeof(Client)); | ||||||
| @ -1059,7 +1059,6 @@ manage(Window w, XWindowAttributes *wa) { | |||||||
| 	c->win = w; | 	c->win = w; | ||||||
| 
 | 
 | ||||||
| 	applyrules(c); | 	applyrules(c); | ||||||
| 	Monitor *m = &monitors[c->monitor]; |  | ||||||
| 
 | 
 | ||||||
| 	c->x = wa->x + m->sx; | 	c->x = wa->x + m->sx; | ||||||
| 	c->y = wa->y + m->sy; | 	c->y = wa->y + m->sy; | ||||||
| @ -1142,10 +1141,10 @@ movemouse(Client *c) { | |||||||
| 
 | 
 | ||||||
| 	ocx = nx = c->x; | 	ocx = nx = c->x; | ||||||
| 	ocy = ny = c->y; | 	ocy = ny = c->y; | ||||||
| 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | 	if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | ||||||
| 			None, cursor[CurMove], CurrentTime) != GrabSuccess) | 			None, cursor[CurMove], CurrentTime) != GrabSuccess) | ||||||
| 		return; | 		return; | ||||||
| 	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | 	XQueryPointer(dpy, monitors[selmonitor].root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | ||||||
| 	for(;;) { | 	for(;;) { | ||||||
| 		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); | 		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); | ||||||
| 		switch (ev.type) { | 		switch (ev.type) { | ||||||
| @ -1232,7 +1231,7 @@ void | |||||||
| resize(Client *c, int x, int y, int w, int h, Bool sizehints) { | resize(Client *c, int x, int y, int w, int h, Bool sizehints) { | ||||||
| 	XWindowChanges wc; | 	XWindowChanges wc; | ||||||
| 	Monitor scr = monitors[monitorat(x, y)]; | 	Monitor scr = monitors[monitorat(x, y)]; | ||||||
| 	c->monitor = scr.id; | 	c->monitor = monitorat(x, y); | ||||||
| 
 | 
 | ||||||
| 	if(sizehints) { | 	if(sizehints) { | ||||||
| 		/* set minimum possible */ | 		/* set minimum possible */ | ||||||
| @ -1305,7 +1304,7 @@ resizemouse(Client *c) { | |||||||
| 
 | 
 | ||||||
| 	ocx = c->x; | 	ocx = c->x; | ||||||
| 	ocy = c->y; | 	ocy = c->y; | ||||||
| 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | 	if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | ||||||
| 			None, cursor[CurResize], CurrentTime) != GrabSuccess) | 			None, cursor[CurResize], CurrentTime) != GrabSuccess) | ||||||
| 		return; | 		return; | ||||||
| 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); | 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); | ||||||
| @ -1429,30 +1428,33 @@ run(void) { | |||||||
| 
 | 
 | ||||||
| void | void | ||||||
| scan(void) { | scan(void) { | ||||||
| 	unsigned int i, num; | 	unsigned int i, j, num; | ||||||
| 	Window *wins, d1, d2; | 	Window *wins, d1, d2; | ||||||
| 	XWindowAttributes wa; | 	XWindowAttributes wa; | ||||||
| 
 | 
 | ||||||
|  | 	for(i = 0; i < mcount; i++) { | ||||||
|  | 		Monitor *m = &monitors[i]; | ||||||
| 		wins = NULL; | 		wins = NULL; | ||||||
| 	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { | 		if(XQueryTree(dpy, m->root, &d1, &d2, &wins, &num)) { | ||||||
| 		for(i = 0; i < num; i++) { | 			for(j = 0; j < num; j++) { | ||||||
| 			if(!XGetWindowAttributes(dpy, wins[i], &wa) | 				if(!XGetWindowAttributes(dpy, wins[j], &wa) | ||||||
| 			|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) | 				|| wa.override_redirect || XGetTransientForHint(dpy, wins[j], &d1)) | ||||||
| 					continue; | 					continue; | ||||||
| 			if(wa.map_state == IsViewable || getstate(wins[i]) == IconicState) | 				if(wa.map_state == IsViewable || getstate(wins[j]) == IconicState) | ||||||
| 				manage(wins[i], &wa); | 					manage(wins[j], &wa); | ||||||
| 			} | 			} | ||||||
| 		for(i = 0; i < num; i++) { /* now the transients */ | 			for(j = 0; j < num; j++) { /* now the transients */ | ||||||
| 			if(!XGetWindowAttributes(dpy, wins[i], &wa)) | 				if(!XGetWindowAttributes(dpy, wins[j], &wa)) | ||||||
| 					continue; | 					continue; | ||||||
| 			if(XGetTransientForHint(dpy, wins[i], &d1) | 				if(XGetTransientForHint(dpy, wins[j], &d1) | ||||||
| 			&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) | 				&& (wa.map_state == IsViewable || getstate(wins[j]) == IconicState)) | ||||||
| 				manage(wins[i], &wa); | 					manage(wins[j], &wa); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if(wins) | 		if(wins) | ||||||
| 			XFree(wins); | 			XFree(wins); | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| setclientstate(Client *c, long state) { | setclientstate(Client *c, long state) { | ||||||
| @ -1513,10 +1515,8 @@ setmwfact(const char *arg) { | |||||||
| void | void | ||||||
| setup(void) { | setup(void) { | ||||||
| 	unsigned int i, j, k; | 	unsigned int i, j, k; | ||||||
| 	XModifierKeymap *modmap; | 	Monitor *m; | ||||||
| 	XSetWindowAttributes wa; | 	XSetWindowAttributes wa; | ||||||
| 	int s = 1; |  | ||||||
| 	GC g; |  | ||||||
| 	XineramaScreenInfo *info = NULL; | 	XineramaScreenInfo *info = NULL; | ||||||
| 
 | 
 | ||||||
| 	/* init atoms */ | 	/* init atoms */ | ||||||
| @ -1526,106 +1526,100 @@ setup(void) { | |||||||
| 	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); | 	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); | ||||||
| 	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); | 	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); | ||||||
| 	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | 	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); | ||||||
| 	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, |  | ||||||
| 			PropModeReplace, (unsigned char *) netatom, NetLast); |  | ||||||
| 
 | 
 | ||||||
| 	/* init cursors */ | 	/* init cursors */ | ||||||
| 	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); | 	wa.cursor = cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); | ||||||
| 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); | 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); | ||||||
| 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); | 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); | ||||||
| 
 | 
 | ||||||
| 
 | 	// init screens/monitors first
 | ||||||
| 	/* init modifier map */ |  | ||||||
| 	modmap = XGetModifierMapping(dpy); |  | ||||||
| 	for(i = 0; i < 8; i++) |  | ||||||
| 		for(j = 0; j < modmap->max_keypermod; j++) { |  | ||||||
| 			if(modmap->modifiermap[i * modmap->max_keypermod + j] |  | ||||||
| 			== XKeysymToKeycode(dpy, XK_Num_Lock)) |  | ||||||
| 				numlockmask = (1 << i); |  | ||||||
| 		} |  | ||||||
| 	XFreeModifiermap(modmap); |  | ||||||
| 
 |  | ||||||
| 	/* select for events */ |  | ||||||
| 	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |  | ||||||
| 		| EnterWindowMask | LeaveWindowMask | StructureNotifyMask; |  | ||||||
| 	wa.cursor = cursor[CurNormal]; |  | ||||||
| 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); |  | ||||||
| 	XSelectInput(dpy, root, wa.event_mask); |  | ||||||
| 
 |  | ||||||
| 	/* grab keys */ |  | ||||||
| 	grabkeys(); |  | ||||||
| 
 |  | ||||||
| 	/* init tags */ |  | ||||||
| 	compileregs(); |  | ||||||
| 
 |  | ||||||
| 	if (XineramaIsActive(dpy)) { | 	if (XineramaIsActive(dpy)) { | ||||||
| 		info = XineramaQueryScreens(dpy, &s); | 		info = XineramaQueryScreens(dpy, &mcount); | ||||||
| 	} | 	} | ||||||
|  | 	mcount = 1; | ||||||
|  | 	monitors = emallocz(mcount * sizeof(Monitor)); | ||||||
| 
 | 
 | ||||||
| 	monitors = emallocz(s*sizeof(Monitor)); | 	for(i = 0; i < mcount; i++) { | ||||||
| 	mcount = s; |  | ||||||
| 
 |  | ||||||
| 	for(i = 0; i < s; i++) { |  | ||||||
| 		/* init geometry */ | 		/* init geometry */ | ||||||
| 		if (mcount != 1) { | 		m = &monitors[i]; | ||||||
| 			monitors[i].sx = info[i].x_org; | 
 | ||||||
| 			monitors[i].sy = info[i].y_org; | 		m->screen = i; | ||||||
| 			monitors[i].sw = info[i].width; | 		m->root = RootWindow(dpy, i); | ||||||
| 			monitors[i].sh = info[i].height; | 
 | ||||||
|  | 		if (mcount != 1) { // TODO: Xinerama
 | ||||||
|  | 			m->sx = info[i].x_org; | ||||||
|  | 			m->sy = info[i].y_org; | ||||||
|  | 			m->sw = info[i].width; | ||||||
|  | 			m->sh = info[i].height; | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			monitors[i].sx = 0; | 			m->sx = 0; | ||||||
| 			monitors[i].sy = 0; | 			m->sy = 0; | ||||||
| 			monitors[i].sw = DisplayWidth(dpy, screen); | 			m->sw = DisplayWidth(dpy, m->screen); | ||||||
| 			monitors[i].sh = DisplayHeight(dpy, screen); | 			m->sh = DisplayHeight(dpy, m->screen); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		monitors[i].id = i; | 		m->seltags = emallocz(sizeof initags); | ||||||
| 		monitors[i].seltags = emallocz(sizeof initags); | 		m->prevtags = emallocz(sizeof initags); | ||||||
| 		monitors[i].prevtags = emallocz(sizeof initags); |  | ||||||
| 
 | 
 | ||||||
| 		memcpy(monitors[i].seltags, initags, sizeof initags); | 		memcpy(m->seltags, initags, sizeof initags); | ||||||
| 		memcpy(monitors[i].prevtags, initags, sizeof initags); | 		memcpy(m->prevtags, initags, sizeof initags); | ||||||
| 
 | 
 | ||||||
| 		/* init appearance */ | 		/* init appearance */ | ||||||
| 		monitors[i].dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); | 		m->dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR, i); | ||||||
| 		monitors[i].dc.norm[ColBG] = getcolor(NORMBGCOLOR); | 		m->dc.norm[ColBG] = getcolor(NORMBGCOLOR, i); | ||||||
| 		monitors[i].dc.norm[ColFG] = getcolor(NORMFGCOLOR); | 		m->dc.norm[ColFG] = getcolor(NORMFGCOLOR, i); | ||||||
| 		monitors[i].dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); | 		m->dc.sel[ColBorder] = getcolor(SELBORDERCOLOR, i); | ||||||
| 		monitors[i].dc.sel[ColBG] = getcolor(SELBGCOLOR); | 		m->dc.sel[ColBG] = getcolor(SELBGCOLOR, i); | ||||||
| 		monitors[i].dc.sel[ColFG] = getcolor(SELFGCOLOR); | 		m->dc.sel[ColFG] = getcolor(SELFGCOLOR, i); | ||||||
| 		initfont(&(monitors[i]), FONT); | 		initfont(m, FONT); | ||||||
| 		monitors[i].dc.h = bh = monitors[i].dc.font.height + 2; | 		m->dc.h = bh = m->dc.font.height + 2; | ||||||
| 
 | 
 | ||||||
| 		/* init layouts */ | 		/* init layouts */ | ||||||
| 		monitors[i].mwfact = MWFACT; | 		m->mwfact = MWFACT; | ||||||
| 		monitors[i].layout = &layouts[0]; | 		m->layout = &layouts[0]; | ||||||
| 		for(blw = k = 0; k < LENGTH(layouts); k++) { | 		for(blw = k = 0; k < LENGTH(layouts); k++) { | ||||||
| 			j = textw(&monitors[i], layouts[k].symbol); | 			j = textw(m, layouts[k].symbol); | ||||||
| 			if(j > blw) | 			if(j > blw) | ||||||
| 				blw = j; | 				blw = j; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// TODO: bpos per screen?
 | ||||||
| 		bpos = BARPOS; | 		bpos = BARPOS; | ||||||
| 		wa.override_redirect = 1; | 		wa.override_redirect = 1; | ||||||
| 		wa.background_pixmap = ParentRelative; | 		wa.background_pixmap = ParentRelative; | ||||||
| 		wa.event_mask = ButtonPressMask | ExposureMask; | 		wa.event_mask = ButtonPressMask | ExposureMask; | ||||||
| 
 | 
 | ||||||
| 		/* init bars */ | 		/* init bars */ | ||||||
| 		monitors[i].barwin = XCreateWindow(dpy, root, monitors[i].sx, monitors[i].sy, monitors[i].sw, bh, 0, | 		m->barwin = XCreateWindow(dpy, m->root, m->sx, m->sy, m->sw, bh, 0, | ||||||
| 				DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), | 				DefaultDepth(dpy, m->screen), CopyFromParent, DefaultVisual(dpy, m->screen), | ||||||
| 				CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | 				CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | ||||||
| 		XDefineCursor(dpy, monitors[i].barwin, cursor[CurNormal]); | 		XDefineCursor(dpy, m->barwin, cursor[CurNormal]); | ||||||
| 		updatebarpos(&monitors[i]); | 		updatebarpos(m); | ||||||
| 		XMapRaised(dpy, monitors[i].barwin); | 		XMapRaised(dpy, m->barwin); | ||||||
| 		strcpy(stext, "dwm-"VERSION); | 		strcpy(stext, "dwm-"VERSION); | ||||||
| 		monitors[i].dc.drawable = XCreatePixmap(dpy, root, monitors[i].sw, bh, DefaultDepth(dpy, screen)); | 		m->dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen)); | ||||||
| 		g = XCreateGC(dpy, root, 0, 0); | 		m->dc.gc = XCreateGC(dpy, m->root, 0, 0); | ||||||
| 		monitors[i].dc.gc = XCreateGC(dpy, root, 0, 0); | 		XSetLineAttributes(dpy, m->dc.gc, 1, LineSolid, CapButt, JoinMiter); | ||||||
| 		XSetLineAttributes(dpy, monitors[i].dc.gc, 1, LineSolid, CapButt, JoinMiter); | 		if(!m->dc.font.set) | ||||||
| 		if(!monitors[i].dc.font.set) | 			XSetFont(dpy, m->dc.gc, m->dc.font.xfont->fid); | ||||||
| 			XSetFont(dpy, monitors[i].dc.gc, monitors[i].dc.font.xfont->fid); | 
 | ||||||
|  | 		/* EWMH support per monitor */ | ||||||
|  | 		XChangeProperty(dpy, m->root, netatom[NetSupported], XA_ATOM, 32, | ||||||
|  | 				PropModeReplace, (unsigned char *) netatom, NetLast); | ||||||
|  | 
 | ||||||
|  | 		/* select for events */ | ||||||
|  | 		wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ||||||
|  | 				| EnterWindowMask | LeaveWindowMask | StructureNotifyMask; | ||||||
|  | 		XChangeWindowAttributes(dpy, m->root, CWEventMask | CWCursor, &wa); | ||||||
|  | 		XSelectInput(dpy, m->root, wa.event_mask); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	/* grab keys */ | ||||||
|  | 	grabkeys(); | ||||||
|  | 
 | ||||||
|  | 	/* init tags */ | ||||||
|  | 	compileregs(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -1978,21 +1972,24 @@ int | |||||||
| monitorat(int x, int y) { | monitorat(int x, int y) { | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
|  | 	return 0; | ||||||
| 	if(!XineramaIsActive(dpy)) | 	if(!XineramaIsActive(dpy)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	if (x < 0 || y < 0) { | 	if (x < 0 || y < 0) { | ||||||
| 		Window win; | 		Window win; | ||||||
| 		unsigned int mask; | 		unsigned int mask; | ||||||
| 		XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask); | 		XQueryPointer(dpy, DefaultRootWindow(dpy), &win, &win, &x, &y, &i, &i, &mask); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for(i = 0; i < mcount; i++) | 	for(i = 0; i < mcount; i++) { | ||||||
| 		if((x < 0 || (x >= monitors[i].sx && x < monitors[i].sx + monitors[i].sw)) | 		Monitor *m = &monitors[i]; | ||||||
| 				&& (y < 0 || (y >= monitors[i].sy && y < monitors[i].sy + monitors[i].sh))) | 		if((x < 0 || (x >= m->sx && x < m->sx + m->sw)) | ||||||
|  | 				&& (y < 0 || (y >= m->sy && y < m->sy + m->sh))) | ||||||
| 		{ | 		{ | ||||||
| 			return i; | 			return i; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -2011,7 +2008,7 @@ void | |||||||
| selectmonitor(const char *arg) { | selectmonitor(const char *arg) { | ||||||
| 	Monitor *m = &monitors[arg ? atoi(arg) : (monitorat(-1, -1)+1) % mcount]; | 	Monitor *m = &monitors[arg ? atoi(arg) : (monitorat(-1, -1)+1) % mcount]; | ||||||
| 
 | 
 | ||||||
| 	XWarpPointer(dpy, None, root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2); | 	XWarpPointer(dpy, None, m->root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2); | ||||||
| 	focus(NULL); | 	focus(NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -2020,15 +2017,13 @@ int | |||||||
| main(int argc, char *argv[]) { | main(int argc, char *argv[]) { | ||||||
| 	if(argc == 2 && !strcmp("-v", argv[1])) | 	if(argc == 2 && !strcmp("-v", argv[1])) | ||||||
| 		eprint("dwm-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, " | 		eprint("dwm-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, " | ||||||
| 		       "Jukka Salmi, Premysl Hruby, Szabolcs Nagy\n"); | 		       "Jukka Salmi, Premysl Hruby, Szabolcs Nagy, Christof Musik\n"); | ||||||
| 	else if(argc != 1) | 	else if(argc != 1) | ||||||
| 		eprint("usage: dwm [-v]\n"); | 		eprint("usage: dwm [-v]\n"); | ||||||
| 
 | 
 | ||||||
| 	setlocale(LC_CTYPE, ""); | 	setlocale(LC_CTYPE, ""); | ||||||
| 	if(!(dpy = XOpenDisplay(0))) | 	if(!(dpy = XOpenDisplay(0))) | ||||||
| 		eprint("dwm: cannot open display\n"); | 		eprint("dwm: cannot open display\n"); | ||||||
| 	screen = DefaultScreen(dpy); |  | ||||||
| 	root = RootWindow(dpy, screen); |  | ||||||
| 
 | 
 | ||||||
| 	checkotherwm(); | 	checkotherwm(); | ||||||
| 	setup(); | 	setup(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 anselm@anselm1
						anselm@anselm1