view.c
changeset 327 96d09fd98e89
child 333 827f8f6c9e97
equal deleted inserted replaced
326:73efaa15a635 327:96d09fd98e89
       
     1 /*
       
     2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
       
     3  * See LICENSE file for license details.
       
     4  */
       
     5 #include "dwm.h"
       
     6 
       
     7 /* extern */
       
     8 
       
     9 void (*arrange)(Arg *) = DEFMODE;
       
    10 
       
    11 void
       
    12 dofloat(Arg *arg)
       
    13 {
       
    14 	Client *c;
       
    15 
       
    16 	for(c = clients; c; c = c->next) {
       
    17 		c->ismax = False;
       
    18 		if(isvisible(c)) {
       
    19 			resize(c, True, TopLeft);
       
    20 		}
       
    21 		else
       
    22 			ban(c);
       
    23 	}
       
    24 	if(!sel || !isvisible(sel))
       
    25 		sel = getnext(clients);
       
    26 	if(sel)
       
    27 		focus(sel);
       
    28 	else
       
    29 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
       
    30 	restack();
       
    31 }
       
    32 
       
    33 void
       
    34 dotile(Arg *arg)
       
    35 {
       
    36 	int h, i, n, w;
       
    37 	Client *c;
       
    38 
       
    39 	w = sw - mw;
       
    40 	for(n = 0, c = clients; c; c = c->next)
       
    41 		if(isvisible(c) && !c->isfloat)
       
    42 			n++;
       
    43 
       
    44 	if(n > 1)
       
    45 		h = (sh - bh) / (n - 1);
       
    46 	else
       
    47 		h = sh - bh;
       
    48 
       
    49 	for(i = 0, c = clients; c; c = c->next) {
       
    50 		c->ismax = False;
       
    51 		if(isvisible(c)) {
       
    52 			if(c->isfloat) {
       
    53 				resize(c, True, TopLeft);
       
    54 				continue;
       
    55 			}
       
    56 			if(n == 1) {
       
    57 				c->x = sx;
       
    58 				c->y = sy + bh;
       
    59 				c->w = sw - 2;
       
    60 				c->h = sh - 2 - bh;
       
    61 			}
       
    62 			else if(i == 0) {
       
    63 				c->x = sx;
       
    64 				c->y = sy + bh;
       
    65 				c->w = mw - 2;
       
    66 				c->h = sh - 2 - bh;
       
    67 			}
       
    68 			else if(h > bh) {
       
    69 				c->x = sx + mw;
       
    70 				c->y = sy + (i - 1) * h + bh;
       
    71 				c->w = w - 2;
       
    72 				if(i + 1 == n)
       
    73 					c->h = sh - c->y - 2;
       
    74 				else
       
    75 					c->h = h - 2;
       
    76 			}
       
    77 			else { /* fallback if h < bh */
       
    78 				c->x = sx + mw;
       
    79 				c->y = sy + bh;
       
    80 				c->w = w - 2;
       
    81 				c->h = sh - 2 - bh;
       
    82 			}
       
    83 			resize(c, False, TopLeft);
       
    84 			i++;
       
    85 		}
       
    86 		else
       
    87 			ban(c);
       
    88 	}
       
    89 	if(!sel || !isvisible(sel))
       
    90 		sel = getnext(clients);
       
    91 	if(sel)
       
    92 		focus(sel);
       
    93 	else
       
    94 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
       
    95 	restack();
       
    96 }
       
    97 
       
    98 void
       
    99 focusnext(Arg *arg)
       
   100 {
       
   101 	Client *c;
       
   102    
       
   103 	if(!sel)
       
   104 		return;
       
   105 
       
   106 	if(!(c = getnext(sel->next)))
       
   107 		c = getnext(clients);
       
   108 	if(c) {
       
   109 		focus(c);
       
   110 		restack();
       
   111 	}
       
   112 }
       
   113 
       
   114 void
       
   115 focusprev(Arg *arg)
       
   116 {
       
   117 	Client *c;
       
   118 
       
   119 	if(!sel)
       
   120 		return;
       
   121 
       
   122 	if(!(c = getprev(sel->prev))) {
       
   123 		for(c = clients; c && c->next; c = c->next);
       
   124 		c = getprev(c);
       
   125 	}
       
   126 	if(c) {
       
   127 		focus(c);
       
   128 		restack();
       
   129 	}
       
   130 }
       
   131 
       
   132 Bool
       
   133 isvisible(Client *c)
       
   134 {
       
   135 	unsigned int i;
       
   136 
       
   137 	for(i = 0; i < ntags; i++)
       
   138 		if(c->tags[i] && seltag[i])
       
   139 			return True;
       
   140 	return False;
       
   141 }
       
   142 
       
   143 void
       
   144 restack()
       
   145 {
       
   146 	static unsigned int nwins = 0;
       
   147 	static Window *wins = NULL;
       
   148 	unsigned int f, fi, m, mi, n;
       
   149 	Client *c;
       
   150 	XEvent ev;
       
   151 
       
   152 	for(f = 0, m = 0, c = clients; c; c = c->next)
       
   153 		if(isvisible(c)) {
       
   154 			if(c->isfloat || arrange == dofloat)
       
   155 				f++;
       
   156 			else
       
   157 				m++;
       
   158 		}
       
   159 	if(!(n = 2 * (f + m))) {
       
   160 		drawstatus();
       
   161 		return;
       
   162 	}
       
   163 	if(nwins < n) {
       
   164 		nwins = n;
       
   165 		wins = erealloc(wins, nwins * sizeof(Window));
       
   166 	}
       
   167 
       
   168 	fi = 0;
       
   169 	mi = 2 * f;
       
   170 	if(sel->isfloat || arrange == dofloat) {
       
   171 		wins[fi++] = sel->title;
       
   172 		wins[fi++] = sel->win;
       
   173 	}
       
   174 	else {
       
   175 		wins[mi++] = sel->title;
       
   176 		wins[mi++] = sel->win;
       
   177 	}
       
   178 	for(c = clients; c; c = c->next)
       
   179 		if(isvisible(c) && c != sel) {
       
   180 			if(c->isfloat || arrange == dofloat) {
       
   181 				wins[fi++] = c->title;
       
   182 				wins[fi++] = c->win;
       
   183 			}
       
   184 			else {
       
   185 				wins[mi++] = c->title;
       
   186 				wins[mi++] = c->win;
       
   187 			}
       
   188 		}
       
   189 	XRestackWindows(dpy, wins, n);
       
   190 	drawall();
       
   191 	XSync(dpy, False);
       
   192 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
       
   193 }
       
   194 
       
   195 void
       
   196 togglemode(Arg *arg)
       
   197 {
       
   198 	arrange = arrange == dofloat ? dotile : dofloat;
       
   199 	if(sel)
       
   200 		arrange(NULL);
       
   201 	else
       
   202 		drawstatus();
       
   203 }
       
   204 
       
   205 void
       
   206 toggleview(Arg *arg)
       
   207 {
       
   208 	unsigned int i;
       
   209 
       
   210 	seltag[arg->i] = !seltag[arg->i];
       
   211 	for(i = 0; i < ntags && !seltag[i]; i++);
       
   212 	if(i == ntags)
       
   213 		seltag[arg->i] = True; /* cannot toggle last view */
       
   214 	arrange(NULL);
       
   215 }
       
   216 
       
   217 void
       
   218 view(Arg *arg)
       
   219 {
       
   220 	unsigned int i;
       
   221 
       
   222 	for(i = 0; i < ntags; i++)
       
   223 		seltag[i] = False;
       
   224 	seltag[arg->i] = True;
       
   225 	arrange(NULL);
       
   226 }
       
   227 
       
   228 void
       
   229 zoom(Arg *arg)
       
   230 {
       
   231 	Client *c;
       
   232 
       
   233 	if(!sel || (arrange != dotile) || sel->isfloat || sel->ismax)
       
   234 		return;
       
   235 
       
   236 	if(sel == getnext(clients))  {
       
   237 		if((c = getnext(sel->next)))
       
   238 			sel = c;
       
   239 		else
       
   240 			return;
       
   241 	}
       
   242 
       
   243 	/* pop */
       
   244 	sel->prev->next = sel->next;
       
   245 	if(sel->next)
       
   246 		sel->next->prev = sel->prev;
       
   247 	sel->prev = NULL;
       
   248 	clients->prev = sel;
       
   249 	sel->next = clients;
       
   250 	clients = sel;
       
   251 	focus(sel);
       
   252 	arrange(NULL);
       
   253 }