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