aewl

annotate view.c @ 678:4dcbbfe9d137

allowing nmaster=0 (I think that's a straight idea)
author Anselm R. Garbe <arg@suckless.org>
date Thu, 11 Jan 2007 13:43:38 +0100
parents 1438e35b622e
children 76b58d21ea98
rev   line source
arg@644 1 /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
arg@327 2 * See LICENSE file for license details.
arg@327 3 */
arg@327 4 #include "dwm.h"
arg@674 5 #include <stdio.h>
arg@327 6
arg@380 7 /* static */
arg@380 8
arg@382 9 static Client *
arg@480 10 nexttiled(Client *c) {
arg@480 11 for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
arg@480 12 return c;
arg@480 13 }
arg@480 14
arg@442 15 static void
arg@532 16 togglemax(Client *c) {
arg@481 17 XEvent ev;
arg@548 18
arg@549 19 if(c->isfixed)
arg@548 20 return;
arg@532 21
arg@480 22 if((c->ismax = !c->ismax)) {
arg@565 23 c->rx = c->x; c->x = wax;
arg@565 24 c->ry = c->y; c->y = way;
arg@565 25 c->rw = c->w; c->w = waw - 2 * BORDERPX;
arg@565 26 c->rh = c->h; c->h = wah - 2 * BORDERPX;
arg@480 27 }
arg@480 28 else {
arg@480 29 c->x = c->rx;
arg@480 30 c->y = c->ry;
arg@481 31 c->w = c->rw;
arg@481 32 c->h = c->rh;
arg@480 33 }
arg@480 34 resize(c, True, TopLeft);
arg@480 35 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
arg@430 36 }
arg@430 37
arg@327 38 /* extern */
arg@327 39
arg@533 40 void (*arrange)(void) = DEFMODE;
arg@327 41
arg@327 42 void
arg@461 43 detach(Client *c) {
arg@378 44 if(c->prev)
arg@378 45 c->prev->next = c->next;
arg@378 46 if(c->next)
arg@378 47 c->next->prev = c->prev;
arg@378 48 if(c == clients)
arg@378 49 clients = c->next;
arg@378 50 c->next = c->prev = NULL;
arg@378 51 }
arg@378 52
arg@378 53 void
arg@533 54 dofloat(void) {
arg@402 55 Client *c;
arg@400 56
arg@327 57 for(c = clients; c; c = c->next) {
arg@327 58 if(isvisible(c)) {
arg@327 59 resize(c, True, TopLeft);
arg@327 60 }
arg@327 61 else
arg@327 62 ban(c);
arg@327 63 }
arg@446 64 if(!sel || !isvisible(sel)) {
arg@450 65 for(c = stack; c && !isvisible(c); c = c->snext);
arg@450 66 focus(c);
arg@446 67 }
arg@327 68 restack();
arg@327 69 }
arg@327 70
arg@327 71 void
arg@533 72 dotile(void) {
arg@650 73 unsigned int i, n, mw, mh, tw, th;
arg@402 74 Client *c;
arg@400 75
arg@488 76 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
arg@488 77 n++;
arg@678 78
arg@650 79 /* window geoms */
arg@678 80 if(nmaster > 0) {
arg@678 81 mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
arg@678 82 mw = (n > nmaster) ? (waw * master) / 1000 : waw;
arg@678 83 }
arg@678 84 else
arg@678 85 mh = mw = 0;
arg@678 86 th = (n > nmaster) ? wah / (n - nmaster) : 0;
arg@650 87 tw = waw - mw;
arg@327 88
arg@535 89 for(i = 0, c = clients; c; c = c->next)
arg@327 90 if(isvisible(c)) {
arg@327 91 if(c->isfloat) {
arg@327 92 resize(c, True, TopLeft);
arg@327 93 continue;
arg@327 94 }
arg@488 95 c->ismax = False;
arg@565 96 c->x = wax;
arg@565 97 c->y = way;
arg@678 98 if((nmaster > 0) && (i < nmaster)) {
arg@650 99 c->y += i * mh;
arg@650 100 c->w = mw - 2 * BORDERPX;
arg@650 101 c->h = mh - 2 * BORDERPX;
arg@507 102 }
arg@523 103 else { /* tile window */
arg@650 104 c->x += mw;
arg@650 105 c->w = tw - 2 * BORDERPX;
arg@523 106 if(th > bh) {
arg@650 107 c->y += (i - nmaster) * th;
arg@565 108 c->h = th - 2 * BORDERPX;
arg@507 109 }
arg@531 110 else /* fallback if th < bh */
arg@565 111 c->h = wah - 2 * BORDERPX;
arg@327 112 }
arg@327 113 resize(c, False, TopLeft);
arg@535 114 i++;
arg@327 115 }
arg@327 116 else
arg@327 117 ban(c);
arg@532 118
arg@446 119 if(!sel || !isvisible(sel)) {
arg@450 120 for(c = stack; c && !isvisible(c); c = c->snext);
arg@450 121 focus(c);
arg@446 122 }
arg@327 123 restack();
arg@327 124 }
arg@327 125
arg@327 126 void
arg@461 127 focusnext(Arg *arg) {
arg@327 128 Client *c;
arg@327 129
arg@327 130 if(!sel)
arg@327 131 return;
arg@327 132 if(!(c = getnext(sel->next)))
arg@327 133 c = getnext(clients);
arg@327 134 if(c) {
arg@327 135 focus(c);
arg@327 136 restack();
arg@327 137 }
arg@327 138 }
arg@327 139
arg@327 140 void
arg@461 141 focusprev(Arg *arg) {
arg@327 142 Client *c;
arg@327 143
arg@327 144 if(!sel)
arg@327 145 return;
arg@327 146 if(!(c = getprev(sel->prev))) {
arg@327 147 for(c = clients; c && c->next; c = c->next);
arg@327 148 c = getprev(c);
arg@327 149 }
arg@327 150 if(c) {
arg@327 151 focus(c);
arg@327 152 restack();
arg@327 153 }
arg@327 154 }
arg@327 155
arg@650 156 void
arg@650 157 incnmaster(Arg *arg) {
arg@678 158 if((arrange == dofloat)
arg@678 159 || ((int)nmaster + arg->i < 0)
arg@678 160 || (((int)nmaster + arg->i > 0) && (wah / (nmaster + arg->i) < bh)))
arg@650 161 return;
arg@650 162 nmaster += arg->i;
arg@675 163 updatemodetext();
arg@674 164 if(sel)
arg@674 165 arrange();
arg@674 166 else
arg@674 167 drawstatus();
arg@650 168 }
arg@650 169
arg@420 170 Bool
arg@461 171 isvisible(Client *c) {
arg@420 172 unsigned int i;
arg@420 173
arg@420 174 for(i = 0; i < ntags; i++)
arg@420 175 if(c->tags[i] && seltag[i])
arg@420 176 return True;
arg@420 177 return False;
arg@420 178 }
arg@420 179
arg@415 180 void
arg@559 181 resizemaster(Arg *arg) {
arg@561 182 if(arg->i == 0)
arg@561 183 master = MASTER;
arg@561 184 else {
arg@561 185 if(master + arg->i > 950 || master + arg->i < 50)
arg@561 186 return;
arg@561 187 master += arg->i;
arg@561 188 }
arg@533 189 arrange();
arg@415 190 }
arg@415 191
arg@327 192 void
arg@487 193 restack(void) {
arg@327 194 Client *c;
arg@327 195 XEvent ev;
arg@481 196
arg@437 197 if(!sel) {
arg@437 198 drawstatus();
arg@436 199 return;
arg@437 200 }
arg@436 201 if(sel->isfloat || arrange == dofloat) {
arg@436 202 XRaiseWindow(dpy, sel->win);
arg@436 203 XRaiseWindow(dpy, sel->twin);
arg@436 204 }
arg@512 205 if(arrange != dofloat) {
arg@512 206 if(!sel->isfloat) {
arg@512 207 XLowerWindow(dpy, sel->twin);
arg@512 208 XLowerWindow(dpy, sel->win);
arg@512 209 }
arg@436 210 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
arg@512 211 if(c == sel)
arg@512 212 continue;
arg@436 213 XLowerWindow(dpy, c->twin);
arg@436 214 XLowerWindow(dpy, c->win);
arg@327 215 }
arg@512 216 }
arg@327 217 drawall();
arg@327 218 XSync(dpy, False);
arg@327 219 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
arg@327 220 }
arg@327 221
arg@327 222 void
arg@584 223 togglefloat(Arg *arg) {
arg@591 224 if (!sel || arrange == dofloat)
arg@584 225 return;
arg@584 226 sel->isfloat = !sel->isfloat;
arg@584 227 arrange();
arg@584 228 }
arg@584 229
arg@584 230 void
arg@461 231 togglemode(Arg *arg) {
arg@333 232 arrange = (arrange == dofloat) ? dotile : dofloat;
arg@675 233 updatemodetext();
arg@327 234 if(sel)
arg@533 235 arrange();
arg@327 236 else
arg@327 237 drawstatus();
arg@327 238 }
arg@327 239
arg@327 240 void
arg@461 241 toggleview(Arg *arg) {
arg@327 242 unsigned int i;
arg@327 243
arg@327 244 seltag[arg->i] = !seltag[arg->i];
arg@327 245 for(i = 0; i < ntags && !seltag[i]; i++);
arg@327 246 if(i == ntags)
arg@327 247 seltag[arg->i] = True; /* cannot toggle last view */
arg@533 248 arrange();
arg@327 249 }
arg@327 250
arg@327 251 void
arg@675 252 updatemodetext() {
arg@675 253 snprintf(mtext, sizeof mtext, arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, nmaster);
arg@675 254 bmw = textw(mtext);
arg@675 255 }
arg@675 256
arg@675 257 void
arg@461 258 view(Arg *arg) {
arg@327 259 unsigned int i;
arg@327 260
arg@327 261 for(i = 0; i < ntags; i++)
arg@594 262 seltag[i] = (arg->i == -1) ? True : False;
arg@611 263 if(arg->i >= 0 && arg->i < ntags)
arg@611 264 seltag[arg->i] = True;
arg@533 265 arrange();
arg@327 266 }
arg@327 267
arg@327 268 void
arg@461 269 zoom(Arg *arg) {
arg@651 270 unsigned int n;
arg@423 271 Client *c;
arg@473 272
arg@473 273 if(!sel)
arg@473 274 return;
arg@473 275 if(sel->isfloat || (arrange == dofloat)) {
arg@480 276 togglemax(sel);
arg@473 277 return;
arg@473 278 }
arg@650 279 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
arg@650 280 n++;
arg@654 281
arg@662 282 if((c = sel) == nexttiled(clients))
arg@662 283 if(!(c = nexttiled(c->next)))
arg@662 284 return;
arg@662 285 detach(c);
arg@662 286 if(clients)
arg@662 287 clients->prev = c;
arg@662 288 c->next = clients;
arg@662 289 clients = c;
arg@662 290 focus(c);
arg@662 291 arrange();
arg@327 292 }