client.c
changeset 73 c2ddb9dbbd10
parent 71 7681ef838201
child 74 5370ef170cc9
equal deleted inserted replaced
72:d0eb0bb63c40 73:c2ddb9dbbd10
     9 #include <X11/Xatom.h>
     9 #include <X11/Xatom.h>
    10 #include <X11/Xutil.h>
    10 #include <X11/Xutil.h>
    11 
    11 
    12 #include "dwm.h"
    12 #include "dwm.h"
    13 
    13 
    14 void (*arrange)(Arg *) = tiling;
       
    15 
       
    16 static Rule rule[] = {
    14 static Rule rule[] = {
    17 	/* class			instance	tags						floating */
    15 	/* class			instance	tags						floating */
    18 	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
    16 	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
    19 };
    17 };
    20 
    18 
    21 static Client *
    19 Client *
    22 next(Client *c)
    20 next(Client *c)
    23 {
    21 {
    24 	for(; c && !c->tags[tsel]; c = c->next);
    22 	for(; c && !c->tags[tsel]; c = c->next);
    25 	return c;
    23 	return c;
    26 }
    24 }
    27 
    25 
    28 void
    26 void
    29 zoom(Arg *arg)
       
    30 {
       
    31 	Client **l, *c;
       
    32 
       
    33 	if(!sel)
       
    34 		return;
       
    35 
       
    36 	if(sel == next(clients) && sel->next)  {
       
    37 		if((c = next(sel->next)))
       
    38 			sel = c;
       
    39 	}
       
    40 
       
    41 	for(l = &clients; *l && *l != sel; l = &(*l)->next);
       
    42 	*l = sel->next;
       
    43 
       
    44 	sel->next = clients; /* pop */
       
    45 	clients = sel;
       
    46 	arrange(NULL);
       
    47 	focus(sel);
       
    48 }
       
    49 
       
    50 void
       
    51 max(Arg *arg)
       
    52 {
       
    53 	if(!sel)
       
    54 		return;
       
    55 	sel->x = sx;
       
    56 	sel->y = sy + bh;
       
    57 	sel->w = sw - 2 * sel->border;
       
    58 	sel->h = sh - 2 * sel->border - bh;
       
    59 	craise(sel);
       
    60 	resize(sel, False);
       
    61 }
       
    62 
       
    63 void
       
    64 view(Arg *arg)
       
    65 {
       
    66 	Client *c;
       
    67 
       
    68 	tsel = arg->i;
       
    69 	arrange(NULL);
       
    70 
       
    71 	for(c = clients; c; c = next(c->next))
       
    72 		draw_client(c);
       
    73 	draw_bar();
       
    74 }
       
    75 
       
    76 void
       
    77 tappend(Arg *arg)
       
    78 {
       
    79 	if(!sel)
       
    80 		return;
       
    81 
       
    82 	sel->tags[arg->i] = tags[arg->i];
       
    83 	arrange(NULL);
       
    84 }
       
    85 
       
    86 void
       
    87 ttrunc(Arg *arg)
       
    88 {
       
    89 	int i;
       
    90 	if(!sel)
       
    91 		return;
       
    92 
       
    93 	for(i = 0; i < TLast; i++)
       
    94 		sel->tags[i] = NULL;
       
    95 	tappend(arg);
       
    96 }
       
    97 
       
    98 static void
       
    99 ban_client(Client *c)
    27 ban_client(Client *c)
   100 {
    28 {
   101 	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
    29 	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
   102 	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
    30 	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
   103 }
       
   104 
       
   105 void
       
   106 floating(Arg *arg)
       
   107 {
       
   108 	Client *c;
       
   109 
       
   110 	arrange = floating;
       
   111 	for(c = clients; c; c = c->next) {
       
   112 		if(c->tags[tsel])
       
   113 			resize(c, True);
       
   114 		else
       
   115 			ban_client(c);
       
   116 	}
       
   117 	if(sel && !sel->tags[tsel]) {
       
   118 		if((sel = next(clients))) {
       
   119 			craise(sel);
       
   120 			focus(sel);
       
   121 		}
       
   122 	}
       
   123 	draw_bar();
       
   124 }
       
   125 
       
   126 void
       
   127 tiling(Arg *arg)
       
   128 {
       
   129 	Client *c;
       
   130 	int n, i, w, h;
       
   131 
       
   132 	w = sw - mw;
       
   133 	arrange = tiling;
       
   134 	for(n = 0, c = clients; c; c = c->next)
       
   135 		if(c->tags[tsel] && !c->floating)
       
   136 			n++;
       
   137 
       
   138 	if(n > 1)
       
   139 		h = (sh - bh) / (n - 1);
       
   140 	else
       
   141 		h = sh - bh;
       
   142 
       
   143 	for(i = 0, c = clients; c; c = c->next) {
       
   144 		if(c->tags[tsel]) {
       
   145 			if(c->floating) {
       
   146 				craise(c);
       
   147 				resize(c, True);
       
   148 				continue;
       
   149 			}
       
   150 			if(n == 1) {
       
   151 				c->x = sx;
       
   152 				c->y = sy + bh;
       
   153 				c->w = sw - 2 * c->border;
       
   154 				c->h = sh - 2 * c->border - bh;
       
   155 			}
       
   156 			else if(i == 0) {
       
   157 				c->x = sx;
       
   158 				c->y = sy + bh;
       
   159 				c->w = mw - 2 * c->border;
       
   160 				c->h = sh - 2 * c->border - bh;
       
   161 			}
       
   162 			else {
       
   163 				c->x = sx + mw;
       
   164 				c->y = sy + (i - 1) * h + bh;
       
   165 				c->w = w - 2 * c->border;
       
   166 				c->h = h - 2 * c->border;
       
   167 			}
       
   168 			resize(c, False);
       
   169 			i++;
       
   170 		}
       
   171 		else
       
   172 			ban_client(c);
       
   173 	}
       
   174 	if(!sel || (sel && !sel->tags[tsel])) {
       
   175 		if((sel = next(clients))) {
       
   176 			craise(sel);
       
   177 			focus(sel);
       
   178 		}
       
   179 	}
       
   180 	draw_bar();
       
   181 }
       
   182 
       
   183 void
       
   184 prevc(Arg *arg)
       
   185 {
       
   186 	Client *c;
       
   187 
       
   188 	if(!sel)
       
   189 		return;
       
   190 
       
   191 	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
       
   192 		craise(c);
       
   193 		focus(c);
       
   194 	}
       
   195 }
       
   196 
       
   197 void
       
   198 nextc(Arg *arg)
       
   199 {
       
   200 	Client *c;
       
   201    
       
   202 	if(!sel)
       
   203 		return;
       
   204 
       
   205 	if(!(c = next(sel->next)))
       
   206 		c = next(clients);
       
   207 	if(c) {
       
   208 		craise(c);
       
   209 		c->revert = sel;
       
   210 		focus(c);
       
   211 	}
       
   212 }
       
   213 
       
   214 void
       
   215 ckill(Arg *arg)
       
   216 {
       
   217 	if(!sel)
       
   218 		return;
       
   219 	if(sel->proto & WM_PROTOCOL_DELWIN)
       
   220 		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
       
   221 	else
       
   222 		XKillClient(dpy, sel->win);
       
   223 }
    31 }
   224 
    32 
   225 static void
    33 static void
   226 resize_title(Client *c)
    34 resize_title(Client *c)
   227 {
    35 {
   228 	int i;
    36 	int i;
   229 
    37 
   230 	c->tw = 0;
    38 	c->tw = 0;
   231 	for(i = 0; i < TLast; i++)
    39 	for(i = 0; i < TLast; i++)
   232 		if(c->tags[i])
    40 		if(c->tags[i])
   233 			c->tw += textw(c->tags[i]) + dc.font.height;
    41 			c->tw += textw(c->tags[i]);
   234 	c->tw += textw(c->name) + dc.font.height;
    42 	c->tw += textw(c->name);
   235 	if(c->tw > c->w)
    43 	if(c->tw > c->w)
   236 		c->tw = c->w + 2;
    44 		c->tw = c->w + 2;
   237 	c->tx = c->x + c->w - c->tw + 2;
    45 	c->tx = c->x + c->w - c->tw + 2;
   238 	c->ty = c->y;
    46 	c->ty = c->y;
   239 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
    47 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
   582 	for(c = clients; c; c = c->next)
   390 	for(c = clients; c; c = c->next)
   583 		if(c->win == w)
   391 		if(c->win == w)
   584 			return c;
   392 			return c;
   585 	return NULL;
   393 	return NULL;
   586 }
   394 }
   587 
       
   588 void
       
   589 draw_client(Client *c)
       
   590 {
       
   591 	int i;
       
   592 	if(c == sel) {
       
   593 		draw_bar();
       
   594 		XUnmapWindow(dpy, c->title);
       
   595 		XSetWindowBorder(dpy, c->win, dc.fg);
       
   596 		return;
       
   597 	}
       
   598 
       
   599 	XSetWindowBorder(dpy, c->win, dc.bg);
       
   600 	XMapWindow(dpy, c->title);
       
   601 
       
   602 	dc.x = dc.y = 0;
       
   603 
       
   604 	dc.w = 0;
       
   605 	for(i = 0; i < TLast; i++) {
       
   606 		if(c->tags[i]) {
       
   607 			dc.x += dc.w;
       
   608 			dc.w = textw(c->tags[i]) + dc.font.height;
       
   609 			drawtext(c->tags[i], False, True);
       
   610 		}
       
   611 	}
       
   612 	dc.x += dc.w;
       
   613 	dc.w = textw(c->name) + dc.font.height;
       
   614 	drawtext(c->name, False, True);
       
   615 	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
       
   616 			0, 0, c->tw, c->th, 0, 0);
       
   617 	XFlush(dpy);
       
   618 }