cleaned up settags-handling
This commit is contained in:
		
							parent
							
								
									7d156dee1e
								
							
						
					
					
						commit
						50be6c8b67
					
				
							
								
								
									
										45
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								client.c
									
									
									
									
									
								
							| @ -7,6 +7,8 @@ | |||||||
| 
 | 
 | ||||||
| /* static */ | /* static */ | ||||||
| 
 | 
 | ||||||
|  | static char config[128]; | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| attachstack(Client *c) { | attachstack(Client *c) { | ||||||
| 	c->snext = stack; | 	c->snext = stack; | ||||||
| @ -179,8 +181,31 @@ killclient(const char *arg) { | |||||||
| 		XKillClient(dpy, sel->win); | 		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 | void | ||||||
| manage(Window w, XWindowAttributes *wa) { | manage(Window w, XWindowAttributes *wa) { | ||||||
|  | 	unsigned int i; | ||||||
| 	Client *c, *t = NULL; | 	Client *c, *t = NULL; | ||||||
| 	Window trans; | 	Window trans; | ||||||
| 	Status rettrans; | 	Status rettrans; | ||||||
| @ -221,9 +246,14 @@ manage(Window w, XWindowAttributes *wa) { | |||||||
| 	updatetitle(c); | 	updatetitle(c); | ||||||
| 	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) | 	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) | ||||||
| 		for(t = clients; t && t->win != trans; t = t->next); | 		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) | 	if(!c->isfloating) | ||||||
| 		c->isfloating = (rettrans == Success) || c->isfixed; | 		c->isfloating = (rettrans == Success) || c->isfixed; | ||||||
|  | 	saveconfig(c); | ||||||
| 	attach(c); | 	attach(c); | ||||||
| 	attachstack(c); | 	attachstack(c); | ||||||
| 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */ | 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */ | ||||||
| @ -294,6 +324,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 | void | ||||||
| unban(Client *c) { | unban(Client *c) { | ||||||
| 	if(!c->isbanned) | 	if(!c->isbanned) | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								dwm.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								dwm.h
									
									
									
									
									
								
							| @ -96,9 +96,11 @@ void configure(Client *c);		/* send synthetic configure event */ | |||||||
| void detach(Client *c);			/* detaches c from global client list */ | void detach(Client *c);			/* detaches c from global client list */ | ||||||
| void focus(Client *c);			/* focus c if visible && !NULL, or focus top visible */ | void focus(Client *c);			/* focus c if visible && !NULL, or focus top visible */ | ||||||
| void killclient(const char *arg);	/* kill sel  nicely */ | 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 manage(Window w, XWindowAttributes *wa);	/* manage new client */ | ||||||
| void resize(Client *c, int x, int y, | void resize(Client *c, int x, int y, | ||||||
| 		int w, int h, Bool sizehints);	/* resize with given coordinates c*/ | 		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 unban(Client *c);			/* unbans c */ | ||||||
| void unmanage(Client *c, long state);	/* unmanage c */ | void unmanage(Client *c, long state);	/* unmanage c */ | ||||||
| void updatesizehints(Client *c);	/* update the size hint variables of 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 */ | int xerror(Display *dsply, XErrorEvent *ee);	/* dwm's X error handler */ | ||||||
| 
 | 
 | ||||||
| /* tag.c */ | /* tag.c */ | ||||||
|  | void applyrules(Client *c);		/* applies rules to c */ | ||||||
| void compileregs(void);			/* initialize regexps of rules defined in config.h */ | void compileregs(void);			/* initialize regexps of rules defined in config.h */ | ||||||
| Bool isvisible(Client *c);		/* returns True if client is visible */ | 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 tag(const char *arg);		/* tags sel with arg's index */ | ||||||
| void togglefloating(const char *arg);	/* toggles sel between floating/tiled state */ | void togglefloating(const char *arg);	/* toggles sel between floating/tiled state */ | ||||||
| void toggletag(const char *arg);	/* toggles sel tags with arg's index */ | void toggletag(const char *arg);	/* toggles sel tags with arg's index */ | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								layout.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								layout.c
									
									
									
									
									
								
							| @ -10,7 +10,7 @@ typedef struct { | |||||||
| } Layout; | } Layout; | ||||||
| 
 | 
 | ||||||
| unsigned int blw = 0; | unsigned int blw = 0; | ||||||
| static unsigned int sellayout = 0; /* default */ | static unsigned int ltidx = 0; /* default */ | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| floating(void) { /* default floating layout */ | floating(void) { /* default floating layout */ | ||||||
| @ -36,7 +36,7 @@ arrange(void) { | |||||||
| 			unban(c); | 			unban(c); | ||||||
| 		else | 		else | ||||||
| 			ban(c); | 			ban(c); | ||||||
| 	layouts[sellayout].arrange(); | 	layouts[ltidx].arrange(); | ||||||
| 	focus(NULL); | 	focus(NULL); | ||||||
| 	restack(); | 	restack(); | ||||||
| } | } | ||||||
| @ -76,25 +76,25 @@ focusprev(const char *arg) { | |||||||
| const char * | const char * | ||||||
| getsymbol(void) | getsymbol(void) | ||||||
| { | { | ||||||
| 	return layouts[sellayout].symbol; | 	return layouts[ltidx].symbol; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Bool | Bool | ||||||
| isfloating(void) { | isfloating(void) { | ||||||
| 	return layouts[sellayout].arrange == floating; | 	return layouts[ltidx].arrange == floating; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Bool | Bool | ||||||
| isarrange(void (*func)()) | isarrange(void (*func)()) | ||||||
| { | { | ||||||
| 	return func == layouts[sellayout].arrange; | 	return func == layouts[ltidx].arrange; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| initlayouts(void) { | initlayouts(void) { | ||||||
| 	unsigned int i, w; | 	unsigned int i, w; | ||||||
| 
 | 
 | ||||||
| 	/* TODO deserialize sellayout if present */ | 	/* TODO deserialize ltidx if present */ | ||||||
| 	nlayouts = sizeof layouts / sizeof layouts[0]; | 	nlayouts = sizeof layouts / sizeof layouts[0]; | ||||||
| 	for(blw = i = 0; i < nlayouts; i++) { | 	for(blw = i = 0; i < nlayouts; i++) { | ||||||
| 		w = textw(layouts[i].symbol); | 		w = textw(layouts[i].symbol); | ||||||
| @ -143,14 +143,14 @@ setlayout(const char *arg) { | |||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	if(!arg) { | 	if(!arg) { | ||||||
| 		if(++sellayout == nlayouts) | 		if(++ltidx == nlayouts) | ||||||
| 			sellayout = 0;; | 			ltidx = 0;; | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		i = atoi(arg); | 		i = atoi(arg); | ||||||
| 		if(i < 0 || i >= nlayouts) | 		if(i < 0 || i >= nlayouts) | ||||||
| 			return; | 			return; | ||||||
| 		sellayout = i; | 		ltidx = i; | ||||||
| 	} | 	} | ||||||
| 	if(sel) | 	if(sel) | ||||||
| 		arrange(); | 		arrange(); | ||||||
|  | |||||||
							
								
								
									
										104
									
								
								tag.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								tag.c
									
									
									
									
									
								
							| @ -27,19 +27,6 @@ static Regs *regs = NULL; | |||||||
| static unsigned int nrules = 0; | static unsigned int nrules = 0; | ||||||
| static char prop[512]; | 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 | static unsigned int | ||||||
| idxoftag(const char *tag) { | idxoftag(const char *tag) { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| @ -52,6 +39,37 @@ idxoftag(const char *tag) { | |||||||
| 
 | 
 | ||||||
| /* extern */ | /* 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 | void | ||||||
| compileregs(void) { | compileregs(void) { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| @ -89,60 +107,6 @@ isvisible(Client *c) { | |||||||
| 	return False; | 	return False; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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 | void | ||||||
| tag(const char *arg) { | tag(const char *arg) { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
| @ -154,7 +118,7 @@ tag(const char *arg) { | |||||||
| 	i = idxoftag(arg); | 	i = idxoftag(arg); | ||||||
| 	if(i >= 0 && i < ntags) | 	if(i >= 0 && i < ntags) | ||||||
| 		sel->tags[i] = True; | 		sel->tags[i] = True; | ||||||
| 	persistconfig(sel); | 	saveconfig(sel); | ||||||
| 	arrange(); | 	arrange(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -165,7 +129,7 @@ togglefloating(const char *arg) { | |||||||
| 	sel->isfloating = !sel->isfloating; | 	sel->isfloating = !sel->isfloating; | ||||||
| 	if(sel->isfloating) { | 	if(sel->isfloating) { | ||||||
| 		resize(sel, sel->x, sel->y, sel->w, sel->h, True); | 		resize(sel, sel->x, sel->y, sel->w, sel->h, True); | ||||||
| 		persistconfig(sel); | 		saveconfig(sel); | ||||||
| 	} | 	} | ||||||
| 	arrange(); | 	arrange(); | ||||||
| } | } | ||||||
| @ -181,7 +145,7 @@ toggletag(const char *arg) { | |||||||
| 	for(j = 0; j < ntags && !sel->tags[j]; j++); | 	for(j = 0; j < ntags && !sel->tags[j]; j++); | ||||||
| 	if(j == ntags) | 	if(j == ntags) | ||||||
| 		sel->tags[i] = True; | 		sel->tags[i] = True; | ||||||
| 	persistconfig(sel); | 	saveconfig(sel); | ||||||
| 	arrange(); | 	arrange(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user