annotate layout.c @ 16:cb5813c117e2

merge heads
author paulo
date Mon, 09 Apr 2018 20:13:53 -0600
parents 162accc5d36d
children
rev   line source
paulo@0 1 /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
paulo@0 2 * See LICENSE file for license details.
paulo@0 3 */
paulo@0 4 #include "dwm.h"
paulo@0 5
paulo@0 6 unsigned int master = MASTER;
paulo@0 7 unsigned int nmaster = NMASTER;
paulo@0 8 unsigned int blw = 0;
paulo@0 9 Layout *lt = NULL;
paulo@0 10
paulo@0 11 /* static */
paulo@0 12
paulo@0 13 static unsigned int nlayouts = 0;
paulo@0 14
paulo@0 15 static void
paulo@0 16 spiral(void) {
paulo@0 17 unsigned int i, n, nx, ny, nw, nh;
paulo@0 18 Client *c;
paulo@0 19
paulo@0 20 nx = wax;
paulo@0 21 ny = way + wah;
paulo@0 22 nw = waw;
paulo@0 23 nh = wah;
paulo@0 24 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 25 n++;
paulo@0 26 for(i = 0, c = clients; c; c = c->next)
paulo@0 27 if(isvisible(c)) {
paulo@0 28 if(c->isbanned)
paulo@0 29 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 30 c->isbanned = False;
paulo@0 31 if(c->isversatile)
paulo@0 32 continue;
paulo@0 33 c->ismax = False;
paulo@0 34 if((i % 2 && nh / 2 > 2 * c->border)
paulo@0 35 || (!(i % 2) && nw / 2 > 2 * c->border))
paulo@0 36 {
paulo@0 37 if(i < n - 1) {
paulo@0 38 if(i % 2)
paulo@0 39 nh /= 2;
paulo@0 40 else
paulo@0 41 nw /= 2;
paulo@0 42 if((i % 4) == 2)
paulo@0 43 nx += nw;
paulo@0 44 else if((i % 4) == 3)
paulo@0 45 ny += nh;
paulo@0 46 }
paulo@0 47 if((i % 4) == 0)
paulo@0 48 ny -= nh;
paulo@0 49 else if((i % 4) == 1)
paulo@0 50 nx += nw;
paulo@0 51 else if((i % 4) == 2)
paulo@0 52 ny += nh;
paulo@0 53 else
paulo@0 54 nx -= nw;
paulo@0 55 i++;
paulo@0 56 }
paulo@0 57 resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, False);
paulo@0 58 }
paulo@0 59 else {
paulo@0 60 c->isbanned = True;
paulo@0 61 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 62 }
paulo@0 63 if(!sel || !isvisible(sel)) {
paulo@0 64 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 65 focus(c);
paulo@0 66 }
paulo@0 67 restack();
paulo@0 68 }
paulo@0 69
paulo@0 70 static void
paulo@15 71 dwindle_m(void) {
paulo@15 72 unsigned int i, j, n, nx, ny, nw, nh, mn, mr, mx, mw;
paulo@15 73 unsigned int m = 2;
paulo@15 74 //unsigned int m = nmaster;
paulo@15 75 Client *c;
paulo@15 76
paulo@15 77 nx = wax;
paulo@15 78 //ny = way + wah;
paulo@15 79 ny = 0;
paulo@15 80 nw = waw;
paulo@15 81 nh = wah;
paulo@15 82 mx = nx;
paulo@15 83 mw = nw / m;
paulo@15 84 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@15 85 n++;
paulo@15 86 mn = n / m;
paulo@15 87 mr = n % m;
paulo@15 88 for(i = 0, j = 0, c = clients; c; c = c->next)
paulo@15 89 if(isvisible(c)) {
paulo@15 90 if(c->isbanned)
paulo@15 91 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@15 92 c->isbanned = False;
paulo@15 93 if(c->isversatile)
paulo@15 94 continue;
paulo@15 95 c->ismax = False;
paulo@15 96 if((i % 2 && nh / 2 > 2 * c->border)
paulo@15 97 || (!(i % 2) && nw / 2 > 2 * c->border))
paulo@15 98 {
paulo@15 99 if((j % m) == 0) {
paulo@15 100 if(i < mn - (mr > 0 ? 0 : 1)) {
paulo@15 101 if(i % 2)
paulo@15 102 nh /= 2;
paulo@15 103 else {
paulo@15 104 nw /= 2;
paulo@15 105 mw = nw / m;
paulo@15 106 }
paulo@15 107 }
paulo@15 108 else if(mr)
paulo@15 109 mw = nw / mr;
paulo@15 110 if((i % 4) == 0)
paulo@15 111 //ny -= nh;
paulo@15 112 ny += (i == 0 ? way : nh);
paulo@15 113 else if((i % 4) == 1)
paulo@15 114 nx += nw;
paulo@15 115 else if((i % 4) == 2)
paulo@15 116 ny += nh;
paulo@15 117 else
paulo@15 118 //nx -= nw;
paulo@15 119 nx += nw;
paulo@15 120 i++;
paulo@15 121 }
paulo@15 122 mx = nx + (j % m) * mw;
paulo@15 123 j++;
paulo@15 124 }
paulo@15 125 resize(c, mx, ny, mw - 2 * c->border, nh - 2 * c->border, False);
paulo@15 126 }
paulo@15 127 else {
paulo@15 128 c->isbanned = True;
paulo@15 129 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@15 130 }
paulo@15 131 if(!sel || !isvisible(sel)) {
paulo@15 132 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@15 133 focus(c);
paulo@15 134 }
paulo@15 135 restack();
paulo@15 136 }
paulo@15 137
paulo@15 138 static void
paulo@0 139 spiral_h(void) {
paulo@0 140 unsigned int i, n, nx, ny, nw, nh;
paulo@0 141 Client *c;
paulo@0 142
paulo@0 143 nx = wax + waw;
paulo@0 144 ny = way;
paulo@0 145 nw = waw;
paulo@0 146 nh = wah;
paulo@0 147 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 148 n++;
paulo@0 149 for(i = 0, c = clients; c; c = c->next)
paulo@0 150 if(isvisible(c)) {
paulo@0 151 if(c->isbanned)
paulo@0 152 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 153 c->isbanned = False;
paulo@0 154 if(c->isversatile)
paulo@0 155 continue;
paulo@0 156 c->ismax = False;
paulo@0 157 if((i % 2 && nw / 2 > 2 * c->border)
paulo@0 158 || (!(i % 2) && nh / 2 > 2 * c->border))
paulo@0 159 {
paulo@0 160 if(i < n - 1) {
paulo@0 161 if(i % 2)
paulo@0 162 nw /= 2;
paulo@0 163 else
paulo@0 164 nh /= 2;
paulo@0 165 if((i % 4) == 2)
paulo@0 166 ny += nh;
paulo@0 167 else if((i % 4) == 3)
paulo@0 168 nx += nw;
paulo@0 169 }
paulo@0 170 if((i % 4) == 0)
paulo@0 171 nx -= nw;
paulo@0 172 else if((i % 4) == 1)
paulo@0 173 ny += nh;
paulo@0 174 else if((i % 4) == 2)
paulo@0 175 nx += nw;
paulo@0 176 else
paulo@0 177 ny -= nh;
paulo@0 178 i++;
paulo@0 179 }
paulo@0 180 resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, False);
paulo@0 181 }
paulo@0 182 else {
paulo@0 183 c->isbanned = True;
paulo@0 184 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 185 }
paulo@0 186 if(!sel || !isvisible(sel)) {
paulo@0 187 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 188 focus(c);
paulo@0 189 }
paulo@0 190 restack();
paulo@0 191 }
paulo@0 192
paulo@0 193 static void
paulo@0 194 monocle(void) {
paulo@0 195 Client *c;
paulo@0 196
paulo@0 197 for(c = clients; c; c = c->next)
paulo@0 198 if(isvisible(c) && c->isbanned) {
paulo@0 199 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 200 c->isbanned = False;
paulo@0 201 }
paulo@0 202 else if(!isvisible(c)) {
paulo@0 203 c->isbanned = True;
paulo@0 204 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 205 }
paulo@0 206
paulo@0 207 for(c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 208 resize(c, wax, way, waw - 2*c->border, wah - 2*c->border, False);
paulo@0 209
paulo@0 210 restack();
paulo@0 211 }
paulo@0 212
paulo@0 213 static void
paulo@0 214 bstack(void) {
paulo@0 215 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
paulo@0 216 Client *c;
paulo@0 217
paulo@0 218 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 219 n++;
paulo@0 220 /* window geoms */
paulo@0 221 mh = (n > nmaster) ? (wah * master) / 1000 : wah;
paulo@0 222 mw = (n > nmaster) ? waw / nmaster : waw / (n > 0 ? n : 1);
paulo@0 223 th = wah - mh;
paulo@0 224 tw = (n > nmaster) ? waw / (n - nmaster) : 0;
paulo@0 225
paulo@0 226 for(i = 0, c = clients; c; c = c->next)
paulo@0 227 if(isvisible(c)) {
paulo@0 228 if(c->isbanned)
paulo@0 229 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 230 c->isbanned = False;
paulo@0 231 if(c->isversatile)
paulo@0 232 continue;
paulo@0 233 c->ismax = False;
paulo@0 234 nx = wax;
paulo@0 235 ny = way;
paulo@0 236 if(i < nmaster) {
paulo@0 237 nx += i * mw;
paulo@0 238 nw = mw - 2 * BORDERPX;
paulo@0 239 nh = mh - 2 * BORDERPX;
paulo@0 240 }
paulo@0 241 else { /* tile window */
paulo@0 242 ny += mh;
paulo@0 243 nh = th - 2 * BORDERPX;
paulo@0 244 if(tw > 2 * BORDERPX) {
paulo@0 245 nx += (i - nmaster) * tw;
paulo@0 246 nw = tw - 2 * BORDERPX;
paulo@0 247 }
paulo@0 248 else /* fallback if th <= 2 * BORDERPX */
paulo@0 249 nw = waw - 2 * BORDERPX;
paulo@0 250 }
paulo@0 251 resize(c, nx, ny, nw, nh, False);
paulo@0 252 i++;
paulo@0 253 }
paulo@0 254 else {
paulo@0 255 c->isbanned = True;
paulo@0 256 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 257 }
paulo@0 258 if(!sel || !isvisible(sel)) {
paulo@0 259 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 260 focus(c);
paulo@0 261 }
paulo@0 262 restack();
paulo@0 263 }
paulo@0 264
paulo@0 265 static void
paulo@0 266 grid(void) {
paulo@5 267 unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch;
paulo@0 268 Client *c;
paulo@0 269
paulo@0 270 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 271 n++;
paulo@5 272 if(n == 0)
paulo@5 273 return;
paulo@0 274
paulo@5 275 /* grid dimensions */
paulo@5 276 for(cols = 0; cols <= n/2; cols++)
paulo@5 277 if(cols*cols >= n)
paulo@0 278 break;
paulo@5 279 if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
paulo@5 280 cols = 2;
paulo@5 281 rows = n/cols;
paulo@0 282
paulo@5 283 /* window geometries */
paulo@5 284 cw = cols ? waw / cols : waw;
paulo@5 285 cn = 0; /* current column number */
paulo@5 286 rn = 0; /* current row number */
paulo@0 287 for(i = 0, c = clients; c; c = c->next)
paulo@0 288 if(isvisible(c)) {
paulo@5 289 if(i/rows + 1 > cols - n%cols)
paulo@5 290 rows = n/cols + 1;
paulo@5 291 ch = rows ? wah / rows : wah;
paulo@5 292 cx = cn*cw;
paulo@5 293 cy = (TOPBAR ? dc.h : 0) + rn*ch;
paulo@5 294 resize(c, cx, cy, cw - 2 * BORDERPX, ch - 2 * BORDERPX, False);
paulo@5 295 rn++;
paulo@5 296 if(rn >= rows) {
paulo@5 297 rn = 0;
paulo@5 298 cn++;
paulo@5 299 }
paulo@0 300 i++;
paulo@0 301 }
paulo@0 302 else {
paulo@0 303 c->isbanned = True;
paulo@0 304 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 305 }
paulo@5 306
paulo@0 307 if(!sel || !isvisible(sel)) {
paulo@0 308 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 309 focus(c);
paulo@0 310 }
paulo@0 311 restack();
paulo@0 312 }
paulo@0 313
paulo@0 314 static void
paulo@0 315 tile(void) {
paulo@0 316 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
paulo@0 317 Client *c;
paulo@0 318
paulo@0 319 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
paulo@0 320 n++;
paulo@0 321 /* window geoms */
paulo@0 322 mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
paulo@0 323 mw = (n > nmaster) ? (waw * master) / 1000 : waw;
paulo@0 324 th = (n > nmaster) ? wah / (n - nmaster) : 0;
paulo@0 325 tw = waw - mw;
paulo@0 326
paulo@0 327 for(i = 0, c = clients; c; c = c->next)
paulo@0 328 if(isvisible(c)) {
paulo@0 329 if(c->isbanned)
paulo@0 330 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 331 c->isbanned = False;
paulo@0 332 if(c->isversatile)
paulo@0 333 continue;
paulo@0 334 c->ismax = False;
paulo@0 335 nx = wax;
paulo@0 336 ny = way;
paulo@0 337 if(i < nmaster) {
paulo@0 338 ny += i * mh;
paulo@0 339 nw = mw - 2 * BORDERPX;
paulo@0 340 nh = mh - 2 * BORDERPX;
paulo@0 341 }
paulo@0 342 else { /* tile window */
paulo@0 343 nx += mw;
paulo@0 344 nw = tw - 2 * BORDERPX;
paulo@0 345 if(th > 2 * BORDERPX) {
paulo@0 346 ny += (i - nmaster) * th;
paulo@0 347 nh = th - 2 * BORDERPX;
paulo@0 348 }
paulo@0 349 else /* fallback if th <= 2 * BORDERPX */
paulo@0 350 nh = wah - 2 * BORDERPX;
paulo@0 351 }
paulo@0 352 resize(c, nx, ny, nw, nh, False);
paulo@0 353 i++;
paulo@0 354 }
paulo@0 355 else {
paulo@0 356 c->isbanned = True;
paulo@0 357 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 358 }
paulo@0 359 if(!sel || !isvisible(sel)) {
paulo@0 360 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 361 focus(c);
paulo@0 362 }
paulo@0 363 restack();
paulo@0 364 }
paulo@0 365
paulo@0 366 LAYOUTS
paulo@0 367
paulo@0 368 /* extern */
paulo@0 369
paulo@0 370 void
paulo@0 371 focusnext(Arg *arg) {
paulo@0 372 Client *c;
paulo@0 373
paulo@0 374 if(!sel)
paulo@0 375 return;
paulo@0 376 for(c = sel->next; c && !isvisible(c); c = c->next);
paulo@0 377 if(!c)
paulo@0 378 for(c = clients; c && !isvisible(c); c = c->next);
paulo@0 379 if(c) {
paulo@0 380 focus(c);
paulo@0 381 restack();
paulo@0 382 }
paulo@0 383 }
paulo@0 384
paulo@0 385 void
paulo@0 386 focusprev(Arg *arg) {
paulo@0 387 Client *c;
paulo@0 388
paulo@0 389 if(!sel)
paulo@0 390 return;
paulo@0 391 for(c = sel->prev; c && !isvisible(c); c = c->prev);
paulo@0 392 if(!c) {
paulo@0 393 for(c = clients; c && c->next; c = c->next);
paulo@0 394 for(; c && !isvisible(c); c = c->prev);
paulo@0 395 }
paulo@0 396 if(c) {
paulo@0 397 focus(c);
paulo@0 398 restack();
paulo@0 399 }
paulo@0 400 }
paulo@0 401
paulo@0 402 void
paulo@0 403 incnmaster(Arg *arg) {
paulo@0 404 //if((lt->arrange != tile) || (nmaster + arg->i < 1)
paulo@0 405 //|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
paulo@0 406 // return;
paulo@0 407 if(nmaster + arg->i < 1 && nmaster + arg->i <= MAX_TASKS)
paulo@0 408 return;
paulo@0 409 nmaster += arg->i;
paulo@0 410 if(sel)
paulo@0 411 lt->arrange();
paulo@0 412 else
paulo@0 413 drawstatus();
paulo@0 414 }
paulo@0 415
paulo@0 416 void
paulo@0 417 initlayouts(void) {
paulo@0 418 unsigned int i, w;
paulo@0 419
paulo@0 420 lt = &layout[0];
paulo@0 421 nlayouts = sizeof layout / sizeof layout[0];
paulo@0 422 for(blw = i = 0; i < nlayouts; i++) {
paulo@0 423 w = textw(layout[i].symbol);
paulo@0 424 if(w > blw)
paulo@0 425 blw = w;
paulo@0 426 }
paulo@0 427 }
paulo@0 428
paulo@0 429 Client *
paulo@0 430 nexttiled(Client *c) {
paulo@0 431 for(; c && (c->isversatile || !isvisible(c)); c = c->next);
paulo@0 432 return c;
paulo@0 433 }
paulo@0 434
paulo@0 435 void
paulo@0 436 resizemaster(Arg *arg) {
paulo@0 437 //if(lt->arrange != tile)
paulo@0 438 // return;
paulo@0 439 if(arg->i == 0)
paulo@0 440 master = MASTER;
paulo@0 441 else {
paulo@0 442 //if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
paulo@0 443 //|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
paulo@0 444 // return;
paulo@0 445 master += arg->i;
paulo@0 446 }
paulo@0 447 lt->arrange();
paulo@0 448 }
paulo@0 449
paulo@0 450 void
paulo@0 451 restack(void) {
paulo@0 452 Client *c;
paulo@0 453 XEvent ev;
paulo@0 454
paulo@0 455 drawstatus();
paulo@0 456 if(!sel)
paulo@0 457 return;
paulo@0 458 if(sel->isversatile || lt->arrange == versatile)
paulo@0 459 XRaiseWindow(dpy, sel->win);
paulo@0 460 if(lt->arrange != versatile) {
paulo@0 461 if(!sel->isversatile)
paulo@0 462 XLowerWindow(dpy, sel->win);
paulo@0 463 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
paulo@0 464 if(c == sel)
paulo@0 465 continue;
paulo@0 466 XLowerWindow(dpy, c->win);
paulo@0 467 }
paulo@0 468 }
paulo@0 469 XSync(dpy, False);
paulo@0 470 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
paulo@0 471 }
paulo@0 472
paulo@0 473 void
paulo@0 474 setlayout(Arg *arg) {
paulo@1 475 int i;
paulo@0 476
paulo@1 477 if(arg->i < 0) {
paulo@0 478 for(i = 0; i < nlayouts && lt != &layout[i]; i++);
paulo@1 479 if(arg->i == -1)
paulo@1 480 lt = &layout[(i + 1) % nlayouts];
paulo@1 481 else if(arg->i == -2)
paulo@1 482 lt = &layout[(i - 1) >= 0 ? i - 1 : nlayouts - 1];
paulo@0 483 }
paulo@0 484 else {
paulo@0 485 if(arg->i < 0 || arg->i >= nlayouts)
paulo@0 486 return;
paulo@0 487 lt = &layout[arg->i];
paulo@0 488 }
paulo@0 489 if(sel)
paulo@0 490 lt->arrange();
paulo@0 491 else
paulo@0 492 drawstatus();
paulo@0 493 }
paulo@0 494
paulo@0 495 void
paulo@0 496 versatile(void) {
paulo@0 497 Client *c;
paulo@0 498
paulo@0 499 for(c = clients; c; c = c->next) {
paulo@0 500 if(isvisible(c)) {
paulo@0 501 if(c->isbanned)
paulo@0 502 XMoveWindow(dpy, c->win, c->x, c->y);
paulo@0 503 c->isbanned = False;
paulo@0 504 resize(c, c->x, c->y, c->w, c->h, True);
paulo@0 505 }
paulo@0 506 else {
paulo@0 507 c->isbanned = True;
paulo@0 508 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
paulo@0 509 }
paulo@0 510 }
paulo@0 511 if(!sel || !isvisible(sel)) {
paulo@0 512 for(c = stack; c && !isvisible(c); c = c->snext);
paulo@0 513 focus(c);
paulo@0 514 }
paulo@0 515 restack();
paulo@0 516 }