implemented tagging a client
This commit is contained in:
		
							parent
							
								
									b72588746f
								
							
						
					
					
						commit
						c47da143bd
					
				
							
								
								
									
										170
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								client.c
									
									
									
									
									
								
							| @ -11,44 +11,76 @@ | ||||
| 
 | ||||
| #include "dwm.h" | ||||
| 
 | ||||
| static void (*arrange)(void *) = floating; | ||||
| static void (*arrange)(Arg *) = floating; | ||||
| 
 | ||||
| static Client * | ||||
| next(Client *c) | ||||
| { | ||||
| 	for(c = c->next; c && !c->tags[tsel]; c = c->next); | ||||
| 	return c; | ||||
| } | ||||
| 
 | ||||
| static Client * | ||||
| prev(Client *c) | ||||
| { | ||||
| 	for(c = c->prev; c && !c->tags[tsel]; c = c->prev); | ||||
| 	return c; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| max(void *aux) | ||||
| max(Arg *arg) | ||||
| { | ||||
| 	if(!stack) | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 	stack->x = sx; | ||||
| 	stack->y = sy; | ||||
| 	stack->w = sw - 2 * stack->border; | ||||
| 	stack->h = sh - 2 * stack->border; | ||||
| 	craise(stack); | ||||
| 	resize(stack); | ||||
| 	csel->x = sx; | ||||
| 	csel->y = sy; | ||||
| 	csel->w = sw - 2 * csel->border; | ||||
| 	csel->h = sh - 2 * csel->border; | ||||
| 	craise(csel); | ||||
| 	resize(csel); | ||||
| 	discard_events(EnterWindowMask); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| floating(void *aux) | ||||
| tag(Arg *arg) | ||||
| { | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(arg->i == tsel) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(csel->tags[arg->i]) | ||||
| 		csel->tags[arg->i] = NULL; /* toggle tag */ | ||||
| 	else | ||||
| 		csel->tags[arg->i] = tags[arg->i]; | ||||
| 	arrange(NULL); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| floating(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
| 
 | ||||
| 	arrange = floating; | ||||
| 	for(c = stack; c; c = c->snext) | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 	for(c = csel; c; c = next(c)) | ||||
| 		resize(c); | ||||
| 	discard_events(EnterWindowMask); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| tiling(void *aux) | ||||
| tiling(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
| 	int n, cols, rows, gw, gh, i, j; | ||||
|     float rt, fd; | ||||
| 
 | ||||
| 	arrange = tiling; | ||||
| 	if(!clients) | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 	for(n = 0, c = clients; c; c = c->next, n++); | ||||
| 	for(n = 0, c = csel; c; c = next(c), n++); | ||||
| 	rt = sqrt(n); | ||||
| 	if(modff(rt, &fd) < 0.5) | ||||
| 		rows = floor(rt); | ||||
| @ -62,7 +94,7 @@ tiling(void *aux) | ||||
| 	gw = (sw - 2)  / cols; | ||||
| 	gh = (sh - 2) / rows; | ||||
| 
 | ||||
| 	for(i = j = 0, c = clients; c; c = c->next) { | ||||
| 	for(i = j = 0, c = csel; c; c = next(c)) { | ||||
| 		c->x = i * gw; | ||||
| 		c->y = j * gh; | ||||
| 		c->w = gw; | ||||
| @ -77,28 +109,44 @@ tiling(void *aux) | ||||
| } | ||||
| 
 | ||||
| void | ||||
| sel(void *aux) | ||||
| prevc(Arg *arg) | ||||
| { | ||||
| 	const char *arg = aux; | ||||
| 	Client *c = NULL; | ||||
| 	Client *c; | ||||
| 
 | ||||
| 	if(!arg || !stack) | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 	if(!strncmp(arg, "next", 5)) | ||||
| 		c = stack->snext ? stack->snext : stack; | ||||
| 	else if(!strncmp(arg, "prev", 5)) | ||||
| 		for(c = stack; c && c->snext; c = c->snext); | ||||
| 	if(!c) | ||||
| 		c = stack; | ||||
| 	craise(c); | ||||
| 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | ||||
| 	focus(c); | ||||
| 
 | ||||
| 	if(!(c = prev(csel))) | ||||
| 		c = prev(cend); | ||||
| 	if(c) { | ||||
| 		craise(c); | ||||
| 		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ckill(void *aux) | ||||
| nextc(Arg *arg) | ||||
| { | ||||
| 	Client *c = stack; | ||||
| 	Client *c; | ||||
|     | ||||
| 	if(!csel) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(!(c = next(csel))) | ||||
| 		c = next(cstart); | ||||
| 
 | ||||
| 	if(c) { | ||||
| 		craise(c); | ||||
| 		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ckill(Arg *arg) | ||||
| { | ||||
| 	Client *c = csel; | ||||
| 
 | ||||
| 	if(!c) | ||||
| 		return; | ||||
| @ -208,19 +256,12 @@ lower(Client *c) | ||||
| void | ||||
| focus(Client *c) | ||||
| { | ||||
| 	Client **l, *old; | ||||
| 
 | ||||
| 	old = stack; | ||||
| 	for(l = &stack; *l && *l != c; l = &(*l)->snext); | ||||
| 	if(*l) | ||||
| 		*l = c->snext; | ||||
| 	c->snext = stack; | ||||
| 	stack = c; | ||||
| 	if(old && old != c) { | ||||
| 		XSetWindowBorder(dpy, old->win, dc.bg); | ||||
| 		XMapWindow(dpy, old->title); | ||||
| 		draw_client(old); | ||||
| 	if(csel && csel != c) { | ||||
| 		XSetWindowBorder(dpy, csel->win, dc.bg); | ||||
| 		XMapWindow(dpy, csel->title); | ||||
| 		draw_client(csel); | ||||
| 	} | ||||
| 	csel = c; | ||||
| 	XUnmapWindow(dpy, c->title); | ||||
| 	XSetWindowBorder(dpy, c->win, dc.fg); | ||||
| 	draw_client(c); | ||||
| @ -232,7 +273,7 @@ focus(Client *c) | ||||
| void | ||||
| manage(Window w, XWindowAttributes *wa) | ||||
| { | ||||
| 	Client *c, **l; | ||||
| 	Client *c; | ||||
| 	XSetWindowAttributes twa; | ||||
| 
 | ||||
| 	c = emallocz(sizeof(Client)); | ||||
| @ -258,9 +299,15 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | ||||
| 
 | ||||
| 	update_name(c); | ||||
| 	for(l=&clients; *l; l=&(*l)->next); | ||||
| 	c->next = *l; /* *l == nil */ | ||||
| 	*l = c; | ||||
| 
 | ||||
| 	if(!cstart) | ||||
| 		cstart = cend = c; | ||||
| 	else { | ||||
| 		cend->next = c; | ||||
| 		c->prev = cend; | ||||
| 		cend = c; | ||||
| 	} | ||||
| 
 | ||||
| 	XSetWindowBorderWidth(dpy, c->win, 1); | ||||
| 	XMapRaised(dpy, c->win); | ||||
| 	XMapRaised(dpy, c->title); | ||||
| @ -373,33 +420,42 @@ dummy_error_handler(Display *dsply, XErrorEvent *err) | ||||
| void | ||||
| unmanage(Client *c) | ||||
| { | ||||
| 	Client **l; | ||||
| 
 | ||||
| 	XGrabServer(dpy); | ||||
| 	XSetErrorHandler(dummy_error_handler); | ||||
| 
 | ||||
| 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | ||||
| 	XDestroyWindow(dpy, c->title); | ||||
| 
 | ||||
| 	for(l=&clients; *l && *l != c; l=&(*l)->next); | ||||
| 	*l = c->next; | ||||
| 	for(l=&stack; *l && *l != c; l=&(*l)->snext); | ||||
| 	*l = c->snext; | ||||
| 	if(c->prev) { | ||||
| 		c->prev->next = c->next; | ||||
| 		if(csel == c) | ||||
| 			csel = c->prev; | ||||
| 	} | ||||
| 	if(c->next) { | ||||
| 		c->next->prev = c->prev; | ||||
| 		if(csel == c) | ||||
| 			csel = c->next; | ||||
| 	} | ||||
| 	if(cstart == c) | ||||
| 		cstart = c->next; | ||||
| 	if(cend == c) | ||||
| 		cend = c->prev; | ||||
| 
 | ||||
| 	free(c); | ||||
| 
 | ||||
| 	XFlush(dpy); | ||||
| 	XSetErrorHandler(error_handler); | ||||
| 	XUngrabServer(dpy); | ||||
| 	arrange(NULL); | ||||
| 	if(stack) | ||||
| 		focus(stack); | ||||
| 	if(csel) | ||||
| 		focus(csel); | ||||
| } | ||||
| 
 | ||||
| Client * | ||||
| gettitle(Window w) | ||||
| { | ||||
| 	Client *c; | ||||
| 	for(c = clients; c; c = c->next) | ||||
| 	for(c = cstart; c; c = c->next) | ||||
| 		if(c->title == w) | ||||
| 			return c; | ||||
| 	return NULL; | ||||
| @ -409,7 +465,7 @@ Client * | ||||
| getclient(Window w) | ||||
| { | ||||
| 	Client *c; | ||||
| 	for(c = clients; c; c = c->next) | ||||
| 	for(c = cstart; c; c = c->next) | ||||
| 		if(c->win == w) | ||||
| 			return c; | ||||
| 	return NULL; | ||||
| @ -419,7 +475,7 @@ void | ||||
| draw_client(Client *c) | ||||
| { | ||||
| 	int i; | ||||
| 	if(c == stack) | ||||
| 	if(c == csel) | ||||
| 		return; | ||||
| 
 | ||||
| 	dc.x = dc.y = 0; | ||||
|  | ||||
							
								
								
									
										27
									
								
								dev.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								dev.c
									
									
									
									
									
								
							| @ -20,16 +20,21 @@ const char *browse[] = { "firefox", NULL }; | ||||
| const char *xlock[] = { "xlock", NULL }; | ||||
| 
 | ||||
| static Key key[] = { | ||||
| 	{ Mod1Mask, XK_Return, (void (*)(void *))spawn, term }, | ||||
| 	{ Mod1Mask, XK_w, (void (*)(void *))spawn, browse }, | ||||
| 	{ Mod1Mask, XK_l, (void (*)(void *))spawn, xlock }, | ||||
| 	{ Mod1Mask, XK_k, sel, "prev" },  | ||||
| 	{ Mod1Mask, XK_j, sel, "next" },  | ||||
| 	{ Mod1Mask, XK_t, tiling, NULL },  | ||||
| 	{ Mod1Mask, XK_f, floating, NULL },  | ||||
| 	{ Mod1Mask, XK_m, max, NULL },  | ||||
| 	{ Mod1Mask | ShiftMask, XK_c, ckill, NULL },  | ||||
| 	{ Mod1Mask | ShiftMask, XK_q, quit, NULL }, | ||||
| 	{ Mod1Mask, XK_Return, spawn, { .argv = term } }, | ||||
| 	{ Mod1Mask, XK_w, spawn, { .argv = browse } }, | ||||
| 	{ Mod1Mask, XK_l, spawn, { .argv = xlock } }, | ||||
| 	{ Mod1Mask, XK_k, prevc, { 0 } }, | ||||
| 	{ Mod1Mask, XK_j, nextc, { 0 } },  | ||||
| 	{ Mod1Mask, XK_t, tiling, { 0 } },  | ||||
| 	{ Mod1Mask, XK_f, floating, { 0 } },  | ||||
| 	{ Mod1Mask, XK_m, max, { 0 } },  | ||||
| 	{ Mod1Mask, XK_0, tag, { .i = Tscratch } },  | ||||
| 	{ Mod1Mask, XK_1, tag, { .i = Tdev } },  | ||||
| 	{ Mod1Mask, XK_2, tag, { .i = Tirc } },  | ||||
| 	{ Mod1Mask, XK_3, tag, { .i = Twww } },  | ||||
| 	{ Mod1Mask, XK_4, tag, { .i = Twork } },  | ||||
| 	{ Mod1Mask | ShiftMask, XK_c, ckill, { 0 } },  | ||||
| 	{ Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, | ||||
| }; | ||||
| 
 | ||||
| /********** CUSTOMIZE **********/ | ||||
| @ -60,7 +65,7 @@ keypress(XEvent *e) | ||||
| 	for(i = 0; i < len; i++) | ||||
| 		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | ||||
| 			if(key[i].func) | ||||
| 				key[i].func(key[i].aux); | ||||
| 				key[i].func(&key[i].arg); | ||||
| 			return; | ||||
| 		} | ||||
| } | ||||
|  | ||||
							
								
								
									
										30
									
								
								dwm.h
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								dwm.h
									
									
									
									
									
								
							| @ -22,6 +22,12 @@ typedef struct DC DC; | ||||
| typedef struct Client Client; | ||||
| typedef struct Fnt Fnt; | ||||
| typedef struct Key Key; | ||||
| typedef union Arg Arg; | ||||
| 
 | ||||
| union Arg { | ||||
| 	const char **argv; | ||||
| 	int i; | ||||
| }; | ||||
| 
 | ||||
| /* atoms */ | ||||
| enum { WMProtocols, WMDelete, WMLast }; | ||||
| @ -62,14 +68,14 @@ struct Client { | ||||
| 	Window trans; | ||||
| 	Window title; | ||||
| 	Client *next; | ||||
| 	Client *snext; | ||||
| 	Client *prev; | ||||
| }; | ||||
| 
 | ||||
| struct Key { | ||||
| 	unsigned long mod; | ||||
| 	KeySym keysym; | ||||
| 	void (*func)(void *aux); | ||||
| 	void *aux; | ||||
| 	void (*func)(Arg *arg); | ||||
| 	Arg arg; | ||||
| }; | ||||
| 
 | ||||
| extern Display *dpy; | ||||
| @ -83,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th; | ||||
| extern char stext[1024], *tags[TLast]; | ||||
| 
 | ||||
| extern DC dc; | ||||
| extern Client *clients, *stack; | ||||
| extern Client *cstart, *cend, *csel; | ||||
| 
 | ||||
| /* client.c */ | ||||
| extern void manage(Window w, XWindowAttributes *wa); | ||||
| @ -97,11 +103,13 @@ extern void update_size(Client *c); | ||||
| extern Client *gettitle(Window w); | ||||
| extern void craise(Client *c); | ||||
| extern void lower(Client *c); | ||||
| extern void ckill(void *aux); | ||||
| extern void sel(void *aux); | ||||
| extern void max(void *aux); | ||||
| extern void floating(void *aux); | ||||
| extern void tiling(void *aux); | ||||
| extern void ckill(Arg *arg); | ||||
| extern void nextc(Arg *arg); | ||||
| extern void prevc(Arg *arg); | ||||
| extern void max(Arg *arg); | ||||
| extern void floating(Arg *arg); | ||||
| extern void tiling(Arg *arg); | ||||
| void tag(Arg *arg); | ||||
| extern void gravitate(Client *c, Bool invert); | ||||
| 
 | ||||
| /* draw.c */ | ||||
| @ -125,7 +133,7 @@ extern void mmove(Client *c); | ||||
| extern int error_handler(Display *dsply, XErrorEvent *e); | ||||
| extern void send_message(Window w, Atom a, long value); | ||||
| extern int win_proto(Window w); | ||||
| extern void quit(void *aux); | ||||
| extern void quit(Arg *arg); | ||||
| 
 | ||||
| /* util.c */ | ||||
| extern void error(const char *errstr, ...); | ||||
| @ -133,5 +141,5 @@ extern void *emallocz(unsigned int size); | ||||
| extern void *emalloc(unsigned int size); | ||||
| extern void *erealloc(void *ptr, unsigned int size); | ||||
| extern char *estrdup(const char *str); | ||||
| extern void spawn(char *argv[]); | ||||
| extern void spawn(Arg *arg); | ||||
| extern void swap(void **p1, void **p2); | ||||
|  | ||||
							
								
								
									
										11
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								main.c
									
									
									
									
									
								
							| @ -38,8 +38,9 @@ int tsel = Tdev; /* default tag */ | ||||
| int screen, sx, sy, sw, sh, th; | ||||
| 
 | ||||
| DC dc = {0}; | ||||
| Client *clients = NULL; | ||||
| Client *stack = NULL; | ||||
| Client *cstart = NULL; | ||||
| Client *cend = NULL; | ||||
| Client *csel = NULL; | ||||
| 
 | ||||
| static Bool other_wm_running; | ||||
| static const char version[] = | ||||
| @ -168,13 +169,13 @@ startup_error_handler(Display *dpy, XErrorEvent *error) | ||||
| static void | ||||
| cleanup() | ||||
| { | ||||
| 	while(clients) | ||||
| 		unmanage(clients); | ||||
| 	while(csel) | ||||
| 		unmanage(csel); | ||||
| 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| quit(void *aux) | ||||
| quit(Arg *arg) | ||||
| { | ||||
| 	running = False; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anselm R. Garbe
						Anselm R. Garbe