nmaster-4.7.c (10211B)
1 #if 0 2 3 TITLE 4 ----- 5 descrp: ntile/tilecols layouts with clientspertag for dwm-4.7 6 author: pancake <youterm.com> 7 update: 2007-12-01 8 9 10 CONFIGURATION 11 ------------- 12 You should modify your config.h to include "nmaster.c" AFTER setting 13 the NMASTER, NCOLS, NROWS, BORDERPX, and RESIZEHINTS macro definitions 14 and BEFORE the layouts definition. 15 16 A sample configuration with ntile will be: 17 18 #define NMASTER 1 19 #define NCOLS 1 20 #define NROWS 1 21 #define CPTH 32 22 #include "nmaster-4.7.c" 23 24 Layout layouts[] = { 25 { "-|=" , ntile }, 26 // ... 27 }; 28 29 // keys 30 { MODKEY|ShiftMask , XK_j , setnmaster , "+1" } , \ 31 { MODKEY|ShiftMask , XK_k , setnmaster , "-1" } , \ 32 { MODKEY , XK_q , clientspertag ,"^1" } , \ 33 { MODKEY , XK_w , clientspertag , "2" } , \ 34 { MODKEY , XK_e , clientspertag , "3" } , \ 35 { MODKEY , XK_n , setcpth , "+32" } , \ 36 { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \ 37 38 39 clientspertag: 40 41 both of them features the new cpt patch (clients per tag) which enables 42 to define the maximum number of clients you want to focus, the rest are 43 stacked at the bottom of the screen. This area has CPTH height and this 44 value can be changed on the fly using the setcpth function. 45 46 +------+----+ 47 | | | Valid values are: 48 | |----| -1 - show all clients 49 | | | 0 - show all clients in the bottom stack area 50 +---+--^+---+ >0 - show N clients 51 +---+---+---+ 52 53 #define CPTH 32 // num of pixels of the height of the stacked cpt area 54 55 { MODKEY , XK_q , clientspertag ,"^1" } , \ 56 { MODKEY , XK_w , clientspertag , "2" } , \ 57 { MODKEY , XK_e , clientspertag , "3" } , \ 58 { MODKEY , XK_r , clientspertag , "4" } , \ 59 { MODKEY , XK_t , clientspertag , "5" } , \ 60 61 { MODKEY , XK_n , setcpth , "+32" } , \ 62 { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \ 63 64 65 This source adds two new layouts: 66 67 ntile: 68 69 +-----+--+ 70 |_____|--| 71 | |--| 72 +-----+--+ 73 74 #define NMASTER 1 75 76 { "-|=" , ntile } , \ 77 78 { MODKEY|ShiftMask , XK_j , setnmaster , "+1" } , \ 79 { MODKEY|ShiftMask , XK_k , setnmaster , "-1" } , \ 80 81 82 tilecols: 83 84 +--+--+--+ 85 |__| |__| 86 | | | | 87 +--+--+--+ 88 89 #define NCOLS 2 90 #define NROWS 1 91 92 { "E|]" , tilecols } , \ 93 94 { MODKEY|ShiftMask , XK_j , setnrows , "+1" } , \ 95 { MODKEY|ShiftMask , XK_k , setnrows , "-1" } , \ 96 { MODKEY|ShiftMask , XK_h , setncols , "+1" } , \ 97 { MODKEY|ShiftMask , XK_l , setncols , "-1" } , 98 99 #endif 100 101 102 /* height for bottom stacked clients */ 103 #ifndef CPTH 104 #define CPTH 32 105 #endif 106 /* initial value for clients per tag */ 107 #ifndef CPT 108 #define CPT -1 109 #endif 110 111 void 112 maxzoom(const char *arg) { 113 if (sel->isfloating) 114 togglemax(NULL); 115 else 116 zoom(NULL); 117 } 118 119 int cpt = CPT; 120 int Cpth = CPTH; 121 122 void 123 clientspertag(const char *arg) { 124 if (*arg=='+' || *arg=='-') { 125 cpt += atoi(arg); 126 } else if (arg[0]=='^') { 127 if (cpt==-1) cpt = atoi(arg+1); 128 else cpt = -1; 129 } else cpt = atoi(arg); 130 arrange(); 131 } 132 133 void 134 setcpth(const char *arg) { 135 int i; 136 137 if(!arg) 138 Cpth = CPTH; 139 else { 140 Cpth += atoi(arg); 141 if (Cpth-CPTH<=0) 142 Cpth = CPTH; 143 if (Cpth+CPTH>=wah) 144 Cpth = wah - CPTH; 145 } 146 if(sel) 147 arrange(); 148 } 149 150 #ifdef NMASTER 151 int nmaster = NMASTER; 152 153 void 154 ntile(void) { 155 unsigned int i, n, t, nx, ny, nw, nh, mw, mh, th; 156 int cptn = 0, cpth = 0; 157 Client *c; 158 159 domwfact = dozoom = True; 160 161 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { 162 //if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; } 163 n++; 164 } 165 t = n; 166 if (cpt!=-1&&n>cpt) { 167 n = cpt; 168 cpth = Cpth; 169 wah -= cpth; 170 } 171 /* window geoms */ 172 mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; 173 mw = (n <= nmaster) ? waw : mwfact * waw; 174 th = (n > nmaster) ? wah / (n - nmaster) : 0; 175 if(n > nmaster && th < bh) 176 th = wah; 177 178 nx = wax; 179 ny = way; 180 181 for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { 182 if (cpt!=-1 && i>=cpt) { 183 nw = waw/(t-n) - c->border*2; 184 nx = (nw+c->border*2)*cptn; 185 cptn++; 186 ny = wah + way; 187 nh = cpth-(c->border*2); 188 if (nh<c->border) nh = cpth; 189 resize(c, nx, ny, nw, nh, RESIZEHINTS); 190 continue; 191 } 192 c->ismax = False; 193 if(i < nmaster) { /* master */ 194 ny = way + i * mh; 195 nw = mw - 2 * c->border; 196 nh = mh; 197 if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ 198 nh = wah - mh * i; 199 nh -= 2 * c->border; 200 } 201 else { /* tile window */ 202 if(i == nmaster) { 203 ny = way; 204 nx += mw; 205 } 206 nw = waw - mw - 2 * c->border; 207 if(i + 1 == n) /* remainder */ 208 nh = (way + wah) - ny - 2 * c->border; 209 else 210 nh = th - 2 * c->border; 211 } 212 resize(c, nx, ny, nw, nh, RESIZEHINTS); 213 if(n > nmaster && th != wah) 214 ny += nh + 2 * c->border; 215 } 216 wah += cpth; 217 } 218 219 void 220 setnmaster(const char *arg) { 221 int i; 222 223 if(!arg) 224 nmaster = NMASTER; 225 else { 226 i = atoi(arg); 227 if((nmaster + i) < 1 || wah / (nmaster + i) <= 2 * BORDERPX) 228 return; 229 nmaster += i; 230 } 231 if(sel) 232 arrange(); 233 } 234 #endif 235 236 #ifdef NCOLS 237 #ifdef NROWS 238 unsigned int ncols = NCOLS; 239 unsigned int nrows = NROWS; 240 241 void 242 setncols(const char *arg) { 243 int i; 244 245 if(!arg) 246 i = NCOLS; 247 else if(arg[0] != '+' && arg[0] != '-') 248 i = atoi(arg); 249 else 250 i = ncols + atoi(arg); 251 252 if((i < 1) || (i >= 1 && waw / i <= 2 * BORDERPX)) 253 return; 254 ncols = i; 255 256 if(sel) 257 arrange(); 258 } 259 260 void 261 setnrows(const char *arg) { 262 int i; 263 264 if(!arg) 265 i = NROWS; 266 else if(arg[0] != '+' && arg[0] != '-') 267 i = atoi(arg); 268 else 269 i = nrows + atoi(arg); 270 271 if(i < 1 || wah <= 2 * BORDERPX * i) 272 return; 273 nrows = i; 274 275 if(sel) 276 arrange(); 277 } 278 279 void 280 tilecols(void) { 281 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, tw1, cols, rows, rows1, t; 282 int cpth = 0, cptn = 0; 283 Client *c; 284 285 domwfact = dozoom = True; 286 287 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { 288 // if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; } 289 n++; 290 } 291 292 /* calculate correct number of rows */ 293 if(ncols > 0 && n - nmaster > nrows * ncols) 294 rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 : 0); 295 else 296 rows = nrows; 297 298 t = n; 299 if (cpt!=-1&&n>cpt) { 300 n = cpt; 301 cpth = Cpth; 302 wah -= cpth; 303 } 304 305 /* window geoms */ 306 mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; 307 308 if (nmaster == 0) { 309 mh = mw = 0; 310 } 311 else if (n <= nmaster) { 312 mh = wah / (n > 0 ? n : 1); 313 mw = waw; 314 } 315 else { 316 mh = wah / nmaster; 317 mw = mwfact * waw; 318 } 319 320 if(rows == 0 || n <= nmaster + rows) { 321 rows1 = n > nmaster ? n - nmaster : 1; 322 tw = tw1 = waw - mw; 323 th = wah / rows1; 324 } 325 else { 326 rows1 = 1 + (n - nmaster - 1) % rows; 327 cols = (n - nmaster) / rows + ((n - nmaster) % rows ? 1 : 0); 328 tw = (waw - mw) / cols; 329 tw1 = waw - mw - (cols - 1) * tw; 330 th = wah / rows; 331 } 332 333 nx = wax; 334 ny = way; 335 336 for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { 337 #if 0 338 if (cpt!=-1 && i>=cpt) { 339 ban(c); 340 continue; 341 } 342 #endif 343 if (cpt!=-1 && i>=cpt) { 344 nw = waw/(t-n) - c->border*2; 345 nx = (nw+c->border*2)*cptn; 346 cptn++; 347 ny = wah + way; 348 nh = cpth-(c->border*2); 349 if (nh<c->border) nh = cpth; 350 resize(c, nx, ny, nw, nh, RESIZEHINTS); 351 continue; 352 } 353 c->ismax = False; 354 if(i < nmaster) { /* master column */ 355 ny = way + i * mh; 356 nw = mw - 2 * c->border; 357 nh = mh - 2 * c->border; 358 if(i == 0) 359 nh += wah - mh * (n < nmaster ? n : nmaster); 360 nh = mh; 361 if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ 362 nh = wah - mh * i; 363 nh -= 2 * c->border; 364 } 365 else if(i < nmaster + rows1) { /* first stack column */ 366 if(i == nmaster) { /* initialise */ 367 ny = way; 368 nx += mw; 369 nh = wah - 2*c->border - (rows1 - 1) * th; 370 } else 371 nh = th - 2 * c->border; 372 nw = tw1 - 2 * c->border; 373 } 374 else { /* successive stack columns - rows > 0 if we reach here */ 375 if((i - nmaster - rows1) % rows == 0) { /* reinitialise */ 376 ny = way; 377 nx += nw + 2 * c-> border; 378 nh = wah - 2*c->border - (rows - 1) * th; 379 } 380 else { 381 nh = th - 2 * c->border; 382 } 383 nw = tw - 2 * c->border; 384 } 385 resize(c, nx, ny, nw, nh, RESIZEHINTS); 386 ny += nh + 2 * c->border; 387 } 388 wah += cpth; 389 } 390 #endif 391 #endif 392 393 /* EXPERIMENTAL: 394 * 395 * Work in progress stuff 396 */ 397 #ifdef EXPERIMENTAL 398 void 399 swapclients(Client *c1, Client *c2) 400 { 401 Client *tmp; 402 403 if (c2 == NULL) { 404 c1->prev->next = NULL; 405 c1->next = clients; 406 clients = c1; 407 return; 408 } 409 410 tmp = c1->next; 411 c1->next = c2->next; 412 c2->next = (tmp == c2 ? c1 : tmp); 413 414 tmp = c2->prev; 415 c2->prev = c1->prev; 416 c1->prev = (tmp == c1 ? c2 : tmp ); 417 418 if(c1->next) 419 c1->next->prev = c1; 420 421 if(c1->prev) 422 c1->prev->next = c1; 423 424 if(c2->next) 425 c2->next->prev = c2; 426 427 if(c2->prev) 428 c2->prev->next = c2; 429 430 //if(clients == c1) 431 // clients = c2; 432 } 433 434 void 435 swap(const char *arg) { 436 int i; 437 438 if(sel) { 439 if (*arg=='+') 440 swapclients(sel, sel->next); 441 else 442 if (*arg=='-') 443 swapclients(sel, sel->prev); 444 arrange(); 445 } 446 } 447 #endif 448 449 #ifdef EXPERIMENTAL 450 void 451 dntile(void) { 452 unsigned int i, n, nx, ny, nw, nh, mw, mh, th, inc; 453 Client *c; 454 455 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) 456 n++; 457 if (cpt!=-1 && n>cpt) n = cpt; 458 459 /* dynamic nmaster */ 460 if (n<5) inc = 0; 461 else if (n<7) inc = 1; 462 else inc = 2; 463 nmaster+=inc; 464 465 /* window geoms */ 466 mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; 467 mw = (n <= nmaster) ? waw : mwfact * waw; 468 th = (n > nmaster) ? wah / (n - nmaster) : 0; 469 if(n > nmaster && th < bh) 470 th = wah; 471 472 nx = wax; 473 ny = way; 474 for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { 475 if (cpt!=-1 && i>=cpt) { 476 ban(c); 477 continue; 478 } 479 c->ismax = False; 480 if(i < nmaster) { /* master */ 481 ny = way + i * mh; 482 nw = mw - 2 * c->border; 483 nh = mh; 484 if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ 485 nh = wah - mh * i; 486 nh -= 2 * c->border; 487 } 488 else { /* tile window */ 489 if(i == nmaster) { 490 ny = way; 491 nx += mw; 492 } 493 nw = waw - mw - 2 * c->border; 494 if(i + 1 == n) /* remainder */ 495 nh = (way + wah) - ny - 2 * c->border; 496 else 497 nh = th - 2 * c->border; 498 } 499 resize(c, nx, ny, nw, nh, False); 500 if(n > nmaster && th != wah) 501 ny += nh + 2 * c->border; 502 } 503 nmaster -= inc; 504 } 505 #endif