diff options
| author | anselm@anselm1 <unknown> | 2008-02-28 21:38:53 +0000 | 
|---|---|---|
| committer | anselm@anselm1 <unknown> | 2008-02-28 21:38:53 +0000 | 
| commit | 7bc272a4e4f463c673d12144b3a202db2345e7de (patch) | |
| tree | 0994f5a62464e4298922acc5794e279ec3d52414 | |
| parent | f1719ac2de2aba270c2460807eacae137d3aeadf (diff) | |
| download | dwm-7bc272a4e4f463c673d12144b3a202db2345e7de.tar.gz | |
made the basics of the tagging concept working -- if people want dynamic tags, that's even possible with this concept, the vtags[] array needs to be modified during runtime for this -- the new code is quite experimental, ugly and needs polishing
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | dwm.c | 145 | 
2 files changed, 93 insertions, 54 deletions
| @@ -17,7 +17,7 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXinerama  # flags  CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"  LDFLAGS = -s ${LIBS} -CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" +CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -DAIM_XINERAMA  LDFLAGS = -g ${LIBS}  # Solaris @@ -71,7 +71,6 @@ struct Client {  	unsigned int border, oldborder;  	Bool isbanned, isfixed, isfloating, isurgent;  	Bool *tags; -	View *view;  	Client *next;  	Client *prev;  	Client *snext; @@ -120,7 +119,6 @@ struct View {  };  /* function declarations */ -void addtag(Client *c, const char *t);  void applyrules(Client *c);  void arrange(void);  void attach(Client *c); @@ -132,6 +130,7 @@ void cleanup(void);  void configure(Client *c);  void configurenotify(XEvent *e);  void configurerequest(XEvent *e); +Bool conflicts(Client *c, unsigned int tidx);  void destroynotify(XEvent *e);  void detach(Client *c);  void detachstack(Client *c); @@ -142,6 +141,7 @@ void *emallocz(unsigned int size);  void enternotify(XEvent *e);  void eprint(const char *errstr, ...);  void expose(XEvent *e); +unsigned int firstag(View *v);  void floating(View *v); /* default floating layout */  void focus(Client *c);  void focusin(XEvent *e); @@ -149,6 +149,7 @@ void focusnext(const char *arg);  void focusprev(const char *arg);  Client *getclient(Window w);  unsigned long getcolor(const char *colstr); +View *getview(Client *c);  View *getviewbar(Window barwin);  long getstate(Window w);  Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); @@ -248,20 +249,10 @@ Window root;  #define TAGSZ (LENGTH(tags) * sizeof(Bool))  /* function implementations */ -void -addtag(Client *c, const char *t) { -	unsigned int i, tidx = idxoftag(t); - -	for(i = 0; i < LENGTH(tags); i++) -		if(c->tags[i] && vtags[i] != vtags[tidx]) -			return; /* conflict */ -	c->tags[tidx] = True; -	c->view = &views[vtags[tidx]]; -}  void  applyrules(Client *c) { -	unsigned int i; +	unsigned int i, idx;  	Bool matched = False;  	Rule *r;  	XClassHint ch = { 0 }; @@ -275,8 +266,8 @@ applyrules(Client *c) {  		|| (ch.res_name && strstr(ch.res_name, r->prop)))  		{  			c->isfloating = r->isfloating; -			if(r->tag) { -				addtag(c, r->tag); +			if(r->tag && !conflicts(c, (idx = idxoftag(r->tag)))) { +				c->tags[idx] = True;  				matched = True;  			}  		} @@ -286,8 +277,9 @@ applyrules(Client *c) {  	if(ch.res_name)  		XFree(ch.res_name);  	if(!matched) { -		memcpy(c->tags, seltags, TAGSZ); -		c->view = selview; +		for(i = 0; i < LENGTH(tags); i++) +			if(seltags[i] && vtags[i] == selview->id) +				c->tags[i] = True;  	}  } @@ -327,7 +319,7 @@ void  ban(Client *c) {  	if(c->isbanned)  		return; -	XMoveWindow(dpy, c->win, c->x + 3 * c->view->w, c->y); +	XMoveWindow(dpy, c->win, c->x + 3 * getview(c)->w, c->y);  	c->isbanned = True;  } @@ -367,17 +359,17 @@ buttonpress(XEvent *e) {  		if(CLEANMASK(ev->state) != MODKEY)  			return;  		if(ev->button == Button1) { -			restack(c->view); +			restack(getview(c));  			movemouse(c);  		}  		else if(ev->button == Button2) { -			if((floating != c->view->layout->arrange) && c->isfloating) +			if((floating != getview(c)->layout->arrange) && c->isfloating)  				togglefloating(NULL);  			else  				zoom(NULL);  		}  		else if(ev->button == Button3 && !c->isfixed) { -			restack(c->view); +			restack(getview(c));  			resizemouse(c);  		}  	} @@ -466,7 +458,7 @@ configurerequest(XEvent *e) {  	XWindowChanges wc;  	if((c = getclient(ev->window))) { -		View *v = c->view; +		View *v = getview(c);  		if(ev->value_mask & CWBorderWidth)  			c->border = ev->border_width;  		if(c->isfixed || c->isfloating || (floating == v->layout->arrange)) { @@ -504,6 +496,16 @@ configurerequest(XEvent *e) {  	XSync(dpy, False);  } +Bool +conflicts(Client *c, unsigned int tidx) { +	unsigned int i; + +	for(i = 0; i < LENGTH(tags); i++) +		if(c->tags[i] && vtags[i] != vtags[tidx]) +			return True; /* conflict */ +	return False; +} +  void  destroynotify(XEvent *e) {  	Client *c; @@ -538,7 +540,7 @@ drawbar(View *v) {  	Client *c;  	dc.x = 0; -	for(c = stack; c && (!isvisible(c) || c->view != v); c = c->snext); +	for(c = stack; c && (!isvisible(c) || getview(c) != v); c = c->snext);  	for(i = 0; i < LENGTH(tags); i++) {  		if(&views[vtags[i]] != v)  			continue; @@ -681,6 +683,16 @@ expose(XEvent *e) {  		drawbar(v);  } +unsigned int +firstag(View *v) { +	unsigned int i; + +	for(i = 0; i < LENGTH(tags); i++) +		if(vtags[i] == v->id) +			return i; +	return 0; /* safe fallback */ +} +  void  floating(View *v) { /* default floating layout */  	Client *c; @@ -695,13 +707,12 @@ void  focus(Client *c) {  	View *v = selview;  	if(c) -		selview = c->view; -	else -		selview = viewat(); +		selview = getview(c);  	if(selview != v)  		drawbar(v);  	if(!c || (c && !isvisible(c))) -		for(c = stack; c && (!isvisible(c) || c->view != selview); c = c->snext); +		/* TODO: isvisible might take getview(c) as constraint? */ +		for(c = stack; c && (!isvisible(c) || getview(c) != selview); c = c->snext);  	if(sel && sel != c) {  		grabbuttons(sel, False);  		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]); @@ -715,7 +726,7 @@ focus(Client *c) {  	if(c) {  		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);  		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); -		selview = c->view; +		selview = getview(c);  	}  	else  		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); @@ -741,7 +752,7 @@ focusnext(const char *arg) {  		for(c = clients; c && !isvisible(c); c = c->next);  	if(c) {  		focus(c); -		restack(c->view); +		restack(getview(c));  	}  } @@ -758,7 +769,7 @@ focusprev(const char *arg) {  	}  	if(c) {  		focus(c); -		restack(c->view); +		restack(getview(c));  	}  } @@ -781,6 +792,16 @@ getcolor(const char *colstr) {  }  View * +getview(Client *c) { +	unsigned int i; + +	for(i = 0; i < LENGTH(tags); i++) +		if(c->tags[i]) +			return &views[vtags[i]]; +	return NULL; +} + +View *  getviewbar(Window barwin) {  	unsigned int i; @@ -905,7 +926,7 @@ idxoftag(const char *t) {  	unsigned int i;  	for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++); -	return (i < LENGTH(tags)) ? i : 0; +	return (i < LENGTH(tags)) ? i : firstag(selview);  }  void @@ -1045,7 +1066,7 @@ manage(Window w, XWindowAttributes *wa) {  	applyrules(c); -	v = c->view; +	v = getview(c);  	c->x = wa->x + v->x;  	c->y = wa->y + v->y; @@ -1124,7 +1145,7 @@ movemouse(Client *c) {  	ocx = nx = c->x;  	ocy = ny = c->y; -	v = c->view; +	v = getview(c);  	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,  			None, cursor[CurMove], CurrentTime) != GrabSuccess)  		return; @@ -1163,7 +1184,7 @@ movemouse(Client *c) {  Client *  nexttiled(Client *c, View *v) { -	for(; c && (c->isfloating || c->view != v || !isvisible(c)); c = c->next); +	for(; c && (c->isfloating || getview(c) != v || !isvisible(c)); c = c->next);  	return c;  } @@ -1188,7 +1209,7 @@ propertynotify(XEvent *e) {  			break;  		case XA_WM_HINTS:  			updatewmhints(c); -			drawbar(c->view); +			drawbar(getview(c));  			break;  		}  		if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { @@ -1221,7 +1242,7 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {  	View *v;  	XWindowChanges wc; -	v = c->view; +	v = getview(c);  	if(sizehints) {  		/* set minimum possible */  		if (w < 1) @@ -1292,7 +1313,7 @@ resizemouse(Client *c) {  	ocx = c->x;  	ocy = c->y; -	v = c->view; +	v = getview(c);  	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,  			None, cursor[CurResize], CurrentTime) != GrabSuccess)  		return; @@ -1560,14 +1581,11 @@ nviews = 2; /* aim Xinerama */  	for(i = 0; i < nviews; i++) {  		/* init geometry */  		v = &views[i]; +		v->id = i; -		/* select first tag in each view */ -		for(j = 0; j < LENGTH(tags); j++) -			if(vtags[j] == i) { -				seltags[j] = prevtags[j] = True;  -				break; -			} - +		/* select first tag of view */ +		j = firstag(v); +		seltags[j] = prevtags[j] = True;   		if(info) { @@ -1661,8 +1679,10 @@ tag(const char *arg) {  	if(!sel)  		return;  	for(i = 0; i < LENGTH(tags); i++) -		sel->tags[i] = (NULL == arg); -	sel->tags[idxoftag(arg)] = True; +		sel->tags[i] = (NULL == arg) && (vtags[i] == getview(sel)->id); +	i = idxoftag(arg); +	if(!conflicts(sel, i)) +		sel->tags[idxoftag(arg)] = True;  	arrange();  } @@ -1753,6 +1773,8 @@ toggletag(const char *arg) {  	if(!sel)  		return;  	i = idxoftag(arg); +	if(conflicts(sel, i)) +		return;  	sel->tags[i] = !sel->tags[i];  	for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++);  	if(j == LENGTH(tags)) @@ -1908,13 +1930,30 @@ updatewmhints(Client *c) {  void  view(const char *arg) { -	unsigned int i; +	unsigned int i, j;  	Bool tmp[LENGTH(tags)]; -	for(i = 0; i < LENGTH(tags); i++) -		tmp[i] = (NULL == arg); -	tmp[idxoftag(arg)] = True; - +	memcpy(tmp, seltags, TAGSZ); +	if(arg == NULL) { +		for(i = 0; i < LENGTH(tags); i++) +			tmp[i] = (vtags[i] == selview->id); +	} +	else { +		i = idxoftag(arg); +		for(j = 0; j < LENGTH(tags); j++) +			if(selview->id == vtags[i]) { +				/* view tag of selview */ +				if(selview->id == vtags[j]) +					tmp[j] = False; +			} +			else { +				/* only touch the view the focus should go */ +				if(vtags[j] == vtags[i]) +					tmp[j] = False; +			} +		selview = &views[vtags[i]]; +		tmp[i] = True; +	}  	if(memcmp(seltags, tmp, TAGSZ) != 0) {  		memcpy(prevtags, seltags, TAGSZ);  		memcpy(seltags, tmp, TAGSZ); @@ -1985,8 +2024,8 @@ zoom(const char *arg) {  	if(!sel || !dozoom || sel->isfloating)  		return; -	if(c == nexttiled(clients, c->view)) -		if(!(c = nexttiled(c->next, c->view))) +	if(c == nexttiled(clients, getview(c))) +		if(!(c = nexttiled(c->next, getview(c))))  			return;  	detach(c);  	attach(c); | 
