nmaster-4.7.c - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
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