diff options
| -rw-r--r-- | client.c | 45 | ||||
| -rw-r--r-- | dwm.h | 4 | ||||
| -rw-r--r-- | layout.c | 18 | ||||
| -rw-r--r-- | tag.c | 104 | 
4 files changed, 90 insertions, 81 deletions
| @@ -7,6 +7,8 @@  /* static */ +static char config[128]; +  static void  attachstack(Client *c) {  	c->snext = stack; @@ -179,8 +181,31 @@ killclient(const char *arg) {  		XKillClient(dpy, sel->win);  } +Bool +loadconfig(Client *c) { +	unsigned int i; +	Bool result = False; +	XTextProperty name; + +	/* check if window has set a property */ +	name.nitems = 0; +	XGetTextProperty(dpy, c->win, &name, dwmconfig); +	if(name.nitems && name.encoding == XA_STRING) { +		strncpy(config, (char *)name.value, sizeof config - 1); +		config[sizeof config - 1] = '\0'; +		XFree(name.value); +		for(i = 0; i < ntags && i < sizeof config - 1 && config[i] != '\0'; i++) +			if((c->tags[i] = config[i] == '1')) +				result = True; +		if(i < sizeof config - 1 && config[i] != '\0') +			c->isfloating = config[i] == '1'; +	} +	return result; +} +  void  manage(Window w, XWindowAttributes *wa) { +	unsigned int i;  	Client *c, *t = NULL;  	Window trans;  	Status rettrans; @@ -221,9 +246,14 @@ manage(Window w, XWindowAttributes *wa) {  	updatetitle(c);  	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))  		for(t = clients; t && t->win != trans; t = t->next); -	settags(c, t); +	if(t) +		for(i = 0; i < ntags; i++) +			c->tags[i] = t->tags[i]; +	if(!loadconfig(c)) +		applyrules(c);  	if(!c->isfloating)  		c->isfloating = (rettrans == Success) || c->isfixed; +	saveconfig(c);  	attach(c);  	attachstack(c);  	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */ @@ -295,6 +325,19 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {  }  void +saveconfig(Client *c) { +	unsigned int i; + +	for(i = 0; i < ntags && i < sizeof config - 1; i++) +		config[i] = c->tags[i] ? '1' : '0'; +	if(i < sizeof config - 1) +		config[i++] = c->isfloating ? '1' : '0'; +	config[i] = '\0'; +	XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8, +			PropModeReplace, (unsigned char *)config, i); +} + +void  unban(Client *c) {  	if(!c->isbanned)  		return; @@ -96,9 +96,11 @@ void configure(Client *c);		/* send synthetic configure event */  void detach(Client *c);			/* detaches c from global client list */  void focus(Client *c);			/* focus c if visible && !NULL, or focus top visible */  void killclient(const char *arg);	/* kill sel  nicely */ +Bool loadconfig(Client *c);		/* loads client properties */  void manage(Window w, XWindowAttributes *wa);	/* manage new client */  void resize(Client *c, int x, int y,  		int w, int h, Bool sizehints);	/* resize with given coordinates c*/ +void saveconfig(Client *c);		/* saves client properties */  void unban(Client *c);			/* unbans c */  void unmanage(Client *c, long state);	/* unmanage c */  void updatesizehints(Client *c);	/* update the size hint variables of c */ @@ -132,9 +134,9 @@ void quit(const char *arg);		/* quit dwm nicely */  int xerror(Display *dsply, XErrorEvent *ee);	/* dwm's X error handler */  /* tag.c */ +void applyrules(Client *c);		/* applies rules to c */  void compileregs(void);			/* initialize regexps of rules defined in config.h */  Bool isvisible(Client *c);		/* returns True if client is visible */ -void settags(Client *c, Client *trans);	/* sets tags of c */  void tag(const char *arg);		/* tags sel with arg's index */  void togglefloating(const char *arg);	/* toggles sel between floating/tiled state */  void toggletag(const char *arg);	/* toggles sel tags with arg's index */ @@ -10,7 +10,7 @@ typedef struct {  } Layout;  unsigned int blw = 0; -static unsigned int sellayout = 0; /* default */ +static unsigned int ltidx = 0; /* default */  static void  floating(void) { /* default floating layout */ @@ -36,7 +36,7 @@ arrange(void) {  			unban(c);  		else  			ban(c); -	layouts[sellayout].arrange(); +	layouts[ltidx].arrange();  	focus(NULL);  	restack();  } @@ -76,25 +76,25 @@ focusprev(const char *arg) {  const char *  getsymbol(void)  { -	return layouts[sellayout].symbol; +	return layouts[ltidx].symbol;  }  Bool  isfloating(void) { -	return layouts[sellayout].arrange == floating; +	return layouts[ltidx].arrange == floating;  }  Bool  isarrange(void (*func)())  { -	return func == layouts[sellayout].arrange; +	return func == layouts[ltidx].arrange;  }  void  initlayouts(void) {  	unsigned int i, w; -	/* TODO deserialize sellayout if present */ +	/* TODO deserialize ltidx if present */  	nlayouts = sizeof layouts / sizeof layouts[0];  	for(blw = i = 0; i < nlayouts; i++) {  		w = textw(layouts[i].symbol); @@ -143,14 +143,14 @@ setlayout(const char *arg) {  	int i;  	if(!arg) { -		if(++sellayout == nlayouts) -			sellayout = 0;; +		if(++ltidx == nlayouts) +			ltidx = 0;;  	}  	else {  		i = atoi(arg);  		if(i < 0 || i >= nlayouts)  			return; -		sellayout = i; +		ltidx = i;  	}  	if(sel)  		arrange(); @@ -27,19 +27,6 @@ static Regs *regs = NULL;  static unsigned int nrules = 0;  static char prop[512]; -static void -persistconfig(Client *c) { -	unsigned int i; - -	for(i = 0; i < ntags && i < sizeof prop - 1; i++) -		prop[i] = c->tags[i] ? '1' : '0'; -	if(i < sizeof prop - 1) -		prop[i++] = c->isfloating ? '1' : '0'; -	prop[i] = '\0'; -	XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8, -			PropModeReplace, (unsigned char *)prop, i); -} -  static unsigned int  idxoftag(const char *tag) {  	unsigned int i; @@ -53,6 +40,37 @@ idxoftag(const char *tag) {  /* extern */  void +applyrules(Client *c) { +	unsigned int i, j; +	regmatch_t tmp; +	Bool matched = False; +	XClassHint ch = { 0 }; + +	/* rule matching */ +	XGetClassHint(dpy, c->win, &ch); +	snprintf(prop, sizeof prop, "%s:%s:%s", +			ch.res_class ? ch.res_class : "", +			ch.res_name ? ch.res_name : "", c->name); +	for(i = 0; i < nrules; i++) +		if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) { +			c->isfloating = rules[i].isfloating; +			for(j = 0; regs[i].tagregex && j < ntags; j++) { +				if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { +					matched = True; +					c->tags[j] = True; +				} +			} +		} +	if(ch.res_class) +		XFree(ch.res_class); +	if(ch.res_name) +		XFree(ch.res_name); +	if(!matched) +		for(i = 0; i < ntags; i++) +			c->tags[i] = seltags[i]; +} + +void  compileregs(void) {  	unsigned int i;  	regex_t *reg; @@ -90,60 +108,6 @@ isvisible(Client *c) {  }  void -settags(Client *c, Client *trans) { -	unsigned int i, j; -	regmatch_t tmp; -	Bool matched = trans != NULL; -	XClassHint ch = { 0 }; -	XTextProperty name; - -	if(matched) { -		for(i = 0; i < ntags; i++) -			c->tags[i] = trans->tags[i]; -	} -	else { -		/* check if window has set a property */ -		name.nitems = 0; -		XGetTextProperty(dpy, c->win, &name, dwmconfig); -		if(name.nitems && name.encoding == XA_STRING) { -			strncpy(prop, (char *)name.value, sizeof prop - 1); -			prop[sizeof prop - 1] = '\0'; -			XFree(name.value); -			for(i = 0; i < ntags && i < sizeof prop - 1 && prop[i] != '\0'; i++) -				if((c->tags[i] = prop[i] == '1')) -					matched = True; -			if(i < sizeof prop - 1 && prop[i] != '\0') -				c->isfloating = prop[i] == '1'; -		} -	} -	if(!matched) { -		/* rule matching */ -		XGetClassHint(dpy, c->win, &ch); -		snprintf(prop, sizeof prop, "%s:%s:%s", -				ch.res_class ? ch.res_class : "", -				ch.res_name ? ch.res_name : "", c->name); -		for(i = 0; i < nrules; i++) -			if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) { -				c->isfloating = rules[i].isfloating; -				for(j = 0; regs[i].tagregex && j < ntags; j++) { -					if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { -						matched = True; -						c->tags[j] = True; -					} -				} -			} -		if(ch.res_class) -			XFree(ch.res_class); -		if(ch.res_name) -			XFree(ch.res_name); -	} -	if(!matched) -		for(i = 0; i < ntags; i++) -			c->tags[i] = seltags[i]; -	persistconfig(c); -} - -void  tag(const char *arg) {  	unsigned int i; @@ -154,7 +118,7 @@ tag(const char *arg) {  	i = idxoftag(arg);  	if(i >= 0 && i < ntags)  		sel->tags[i] = True; -	persistconfig(sel); +	saveconfig(sel);  	arrange();  } @@ -165,7 +129,7 @@ togglefloating(const char *arg) {  	sel->isfloating = !sel->isfloating;  	if(sel->isfloating) {  		resize(sel, sel->x, sel->y, sel->w, sel->h, True); -		persistconfig(sel); +		saveconfig(sel);  	}  	arrange();  } @@ -181,7 +145,7 @@ toggletag(const char *arg) {  	for(j = 0; j < ntags && !sel->tags[j]; j++);  	if(j == ntags)  		sel->tags[i] = True; -	persistconfig(sel); +	saveconfig(sel);  	arrange();  } | 
