|
0
|
1 /* Key binding functions */ |
|
|
2 static void defaultgaps(const Arg *arg); |
|
|
3 static void incrgaps(const Arg *arg); |
|
|
4 static void incrigaps(const Arg *arg); |
|
|
5 static void incrogaps(const Arg *arg); |
|
|
6 static void incrohgaps(const Arg *arg); |
|
|
7 static void incrovgaps(const Arg *arg); |
|
|
8 static void incrihgaps(const Arg *arg); |
|
|
9 static void incrivgaps(const Arg *arg); |
|
|
10 static void togglegaps(const Arg *arg); |
|
|
11 /* Layouts (delete the ones you do not need) */ |
|
|
12 static void bstack(Monitor *m); |
|
|
13 static void bstackhoriz(Monitor *m); |
|
|
14 static void centeredmaster(Monitor *m); |
|
|
15 static void centeredfloatingmaster(Monitor *m); |
|
|
16 static void deck(Monitor *m); |
|
|
17 static void dwindle(Monitor *m); |
|
|
18 static void fibonacci(Monitor *m, int s); |
|
|
19 static void grid(Monitor *m); |
|
|
20 static void nrowgrid(Monitor *m); |
|
|
21 static void spiral(Monitor *m); |
|
|
22 static void tile(Monitor *m); |
|
|
23 /* Internals */ |
|
|
24 static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); |
|
|
25 static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); |
|
|
26 static void setgaps(int oh, int ov, int ih, int iv); |
|
|
27 |
|
|
28 /* Settings */ |
|
|
29 #if !PERTAG_PATCH |
|
|
30 static int enablegaps = 1; |
|
|
31 #endif // PERTAG_PATCH |
|
|
32 |
|
|
33 void |
|
|
34 setgaps(int oh, int ov, int ih, int iv) |
|
|
35 { |
|
|
36 if (oh < 0) oh = 0; |
|
|
37 if (ov < 0) ov = 0; |
|
|
38 if (ih < 0) ih = 0; |
|
|
39 if (iv < 0) iv = 0; |
|
|
40 |
|
|
41 selmon->gappoh = oh; |
|
|
42 selmon->gappov = ov; |
|
|
43 selmon->gappih = ih; |
|
|
44 selmon->gappiv = iv; |
|
|
45 arrange(selmon); |
|
|
46 } |
|
|
47 |
|
|
48 void |
|
|
49 togglegaps(const Arg *arg) |
|
|
50 { |
|
|
51 #if PERTAG_PATCH |
|
|
52 selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; |
|
|
53 #else |
|
|
54 enablegaps = !enablegaps; |
|
|
55 #endif // PERTAG_PATCH |
|
|
56 arrange(NULL); |
|
|
57 } |
|
|
58 |
|
|
59 void |
|
|
60 defaultgaps(const Arg *arg) |
|
|
61 { |
|
|
62 setgaps(gappoh, gappov, gappih, gappiv); |
|
|
63 } |
|
|
64 |
|
|
65 void |
|
|
66 incrgaps(const Arg *arg) |
|
|
67 { |
|
|
68 setgaps( |
|
|
69 selmon->gappoh + arg->i, |
|
|
70 selmon->gappov + arg->i, |
|
|
71 selmon->gappih + arg->i, |
|
|
72 selmon->gappiv + arg->i |
|
|
73 ); |
|
|
74 } |
|
|
75 |
|
|
76 void |
|
|
77 incrigaps(const Arg *arg) |
|
|
78 { |
|
|
79 setgaps( |
|
|
80 selmon->gappoh, |
|
|
81 selmon->gappov, |
|
|
82 selmon->gappih + arg->i, |
|
|
83 selmon->gappiv + arg->i |
|
|
84 ); |
|
|
85 } |
|
|
86 |
|
|
87 void |
|
|
88 incrogaps(const Arg *arg) |
|
|
89 { |
|
|
90 setgaps( |
|
|
91 selmon->gappoh + arg->i, |
|
|
92 selmon->gappov + arg->i, |
|
|
93 selmon->gappih, |
|
|
94 selmon->gappiv |
|
|
95 ); |
|
|
96 } |
|
|
97 |
|
|
98 void |
|
|
99 incrohgaps(const Arg *arg) |
|
|
100 { |
|
|
101 setgaps( |
|
|
102 selmon->gappoh + arg->i, |
|
|
103 selmon->gappov, |
|
|
104 selmon->gappih, |
|
|
105 selmon->gappiv |
|
|
106 ); |
|
|
107 } |
|
|
108 |
|
|
109 void |
|
|
110 incrovgaps(const Arg *arg) |
|
|
111 { |
|
|
112 setgaps( |
|
|
113 selmon->gappoh, |
|
|
114 selmon->gappov + arg->i, |
|
|
115 selmon->gappih, |
|
|
116 selmon->gappiv |
|
|
117 ); |
|
|
118 } |
|
|
119 |
|
|
120 void |
|
|
121 incrihgaps(const Arg *arg) |
|
|
122 { |
|
|
123 setgaps( |
|
|
124 selmon->gappoh, |
|
|
125 selmon->gappov, |
|
|
126 selmon->gappih + arg->i, |
|
|
127 selmon->gappiv |
|
|
128 ); |
|
|
129 } |
|
|
130 |
|
|
131 void |
|
|
132 incrivgaps(const Arg *arg) |
|
|
133 { |
|
|
134 setgaps( |
|
|
135 selmon->gappoh, |
|
|
136 selmon->gappov, |
|
|
137 selmon->gappih, |
|
|
138 selmon->gappiv + arg->i |
|
|
139 ); |
|
|
140 } |
|
|
141 |
|
|
142 void |
|
|
143 getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) |
|
|
144 { |
|
|
145 unsigned int n, oe, ie; |
|
|
146 #if PERTAG_PATCH |
|
|
147 oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; |
|
|
148 #else |
|
|
149 oe = ie = enablegaps; |
|
|
150 #endif // PERTAG_PATCH |
|
|
151 Client *c; |
|
|
152 |
|
|
153 for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); |
|
|
154 if (smartgaps && n == 1) { |
|
|
155 oe = 0; // outer gaps disabled when only one client |
|
|
156 } |
|
|
157 |
|
|
158 *oh = m->gappoh*oe; // outer horizontal gap |
|
|
159 *ov = m->gappov*oe; // outer vertical gap |
|
|
160 *ih = m->gappih*ie; // inner horizontal gap |
|
|
161 *iv = m->gappiv*ie; // inner vertical gap |
|
|
162 *nc = n; // number of clients |
|
|
163 } |
|
|
164 |
|
|
165 void |
|
|
166 getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) |
|
|
167 { |
|
|
168 unsigned int n; |
|
|
169 float mfacts = 0, sfacts = 0; |
|
|
170 int mtotal = 0, stotal = 0; |
|
|
171 Client *c; |
|
|
172 |
|
|
173 for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) |
|
|
174 if (n < m->nmaster) |
|
|
175 mfacts += c->cfact; |
|
|
176 else |
|
|
177 sfacts += c->cfact; |
|
|
178 |
|
|
179 for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) |
|
|
180 if (n < m->nmaster) |
|
|
181 mtotal += msize * (c->cfact / mfacts); |
|
|
182 else |
|
|
183 stotal += ssize * (c->cfact / sfacts); |
|
|
184 |
|
|
185 *mf = mfacts; // total factor of master area |
|
|
186 *sf = sfacts; // total factor of stack area |
|
|
187 *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split |
|
|
188 *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split |
|
|
189 } |
|
|
190 |
|
|
191 /*** |
|
|
192 * Layouts |
|
|
193 */ |
|
|
194 |
|
|
195 /* |
|
|
196 * Bottomstack layout + gaps |
|
|
197 * https://dwm.suckless.org/patches/bottomstack/ |
|
|
198 */ |
|
|
199 static void |
|
|
200 bstack(Monitor *m) |
|
|
201 { |
|
|
202 unsigned int i, n; |
|
|
203 int oh, ov, ih, iv; |
|
|
204 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
205 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
206 float mfacts, sfacts; |
|
|
207 int mrest, srest; |
|
|
208 Client *c; |
|
|
209 |
|
|
210 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
211 if (n == 0) |
|
|
212 return; |
|
|
213 |
|
|
214 sx = mx = m->wx + ov; |
|
|
215 sy = my = m->wy + oh; |
|
|
216 sh = mh = m->wh - 2*oh; |
|
|
217 mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); |
|
|
218 sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); |
|
|
219 |
|
|
220 if (m->nmaster && n > m->nmaster) { |
|
|
221 sh = (mh - ih) * (1 - m->mfact); |
|
|
222 mh = mh - ih - sh; |
|
|
223 sx = mx; |
|
|
224 sy = my + mh + ih; |
|
|
225 } |
|
|
226 |
|
|
227 getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); |
|
|
228 |
|
|
229 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { |
|
|
230 if (i < m->nmaster) { |
|
|
231 resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); |
|
|
232 mx += WIDTH(c) + iv; |
|
|
233 } else { |
|
|
234 resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); |
|
|
235 sx += WIDTH(c) + iv; |
|
|
236 } |
|
|
237 } |
|
|
238 } |
|
|
239 |
|
|
240 static void |
|
|
241 bstackhoriz(Monitor *m) |
|
|
242 { |
|
|
243 unsigned int i, n; |
|
|
244 int oh, ov, ih, iv; |
|
|
245 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
246 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
247 float mfacts, sfacts; |
|
|
248 int mrest, srest; |
|
|
249 Client *c; |
|
|
250 |
|
|
251 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
252 if (n == 0) |
|
|
253 return; |
|
|
254 |
|
|
255 sx = mx = m->wx + ov; |
|
|
256 sy = my = m->wy + oh; |
|
|
257 mh = m->wh - 2*oh; |
|
|
258 sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); |
|
|
259 mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); |
|
|
260 sw = m->ww - 2*ov; |
|
|
261 |
|
|
262 if (m->nmaster && n > m->nmaster) { |
|
|
263 sh = (mh - ih) * (1 - m->mfact); |
|
|
264 mh = mh - ih - sh; |
|
|
265 sy = my + mh + ih; |
|
|
266 sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); |
|
|
267 } |
|
|
268 |
|
|
269 getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); |
|
|
270 |
|
|
271 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { |
|
|
272 if (i < m->nmaster) { |
|
|
273 resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); |
|
|
274 mx += WIDTH(c) + iv; |
|
|
275 } else { |
|
|
276 resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); |
|
|
277 sy += HEIGHT(c) + ih; |
|
|
278 } |
|
|
279 } |
|
|
280 } |
|
|
281 |
|
|
282 /* |
|
|
283 * Centred master layout + gaps |
|
|
284 * https://dwm.suckless.org/patches/centeredmaster/ |
|
|
285 */ |
|
|
286 void |
|
|
287 centeredmaster(Monitor *m) |
|
|
288 { |
|
|
289 unsigned int i, n; |
|
|
290 int oh, ov, ih, iv; |
|
|
291 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
292 int lx = 0, ly = 0, lw = 0, lh = 0; |
|
|
293 int rx = 0, ry = 0, rw = 0, rh = 0; |
|
|
294 float mfacts = 0, lfacts = 0, rfacts = 0; |
|
|
295 int mtotal = 0, ltotal = 0, rtotal = 0; |
|
|
296 int mrest = 0, lrest = 0, rrest = 0; |
|
|
297 Client *c; |
|
|
298 |
|
|
299 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
300 if (n == 0) |
|
|
301 return; |
|
|
302 |
|
|
303 /* initialize areas */ |
|
|
304 mx = m->wx + ov; |
|
|
305 my = m->wy + oh; |
|
|
306 mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); |
|
|
307 mw = m->ww - 2*ov; |
|
|
308 lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); |
|
|
309 rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); |
|
|
310 |
|
|
311 if (m->nmaster && n > m->nmaster) { |
|
|
312 /* go mfact box in the center if more than nmaster clients */ |
|
|
313 if (n - m->nmaster > 1) { |
|
|
314 /* ||<-S->|<---M--->|<-S->|| */ |
|
|
315 mw = (m->ww - 2*ov - 2*iv) * m->mfact; |
|
|
316 lw = (m->ww - mw - 2*ov - 2*iv) / 2; |
|
|
317 rw = (m->ww - mw - 2*ov - 2*iv) - lw; |
|
|
318 mx += lw + iv; |
|
|
319 } else { |
|
|
320 /* ||<---M--->|<-S->|| */ |
|
|
321 mw = (mw - iv) * m->mfact; |
|
|
322 lw = 0; |
|
|
323 rw = m->ww - mw - iv - 2*ov; |
|
|
324 } |
|
|
325 lx = m->wx + ov; |
|
|
326 ly = m->wy + oh; |
|
|
327 rx = mx + mw + iv; |
|
|
328 ry = m->wy + oh; |
|
|
329 } |
|
|
330 |
|
|
331 /* calculate facts */ |
|
|
332 for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { |
|
|
333 if (!m->nmaster || n < m->nmaster) |
|
|
334 mfacts += c->cfact; |
|
|
335 else if ((n - m->nmaster) % 2) |
|
|
336 lfacts += c->cfact; // total factor of left hand stack area |
|
|
337 else |
|
|
338 rfacts += c->cfact; // total factor of right hand stack area |
|
|
339 } |
|
|
340 |
|
|
341 for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) |
|
|
342 if (!m->nmaster || n < m->nmaster) |
|
|
343 mtotal += mh * (c->cfact / mfacts); |
|
|
344 else if ((n - m->nmaster) % 2) |
|
|
345 ltotal += lh * (c->cfact / lfacts); |
|
|
346 else |
|
|
347 rtotal += rh * (c->cfact / rfacts); |
|
|
348 |
|
|
349 mrest = mh - mtotal; |
|
|
350 lrest = lh - ltotal; |
|
|
351 rrest = rh - rtotal; |
|
|
352 |
|
|
353 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { |
|
|
354 if (!m->nmaster || i < m->nmaster) { |
|
|
355 /* nmaster clients are stacked vertically, in the center of the screen */ |
|
|
356 resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); |
|
|
357 my += HEIGHT(c) + ih; |
|
|
358 } else { |
|
|
359 /* stack clients are stacked vertically */ |
|
|
360 if ((i - m->nmaster) % 2 ) { |
|
|
361 resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); |
|
|
362 ly += HEIGHT(c) + ih; |
|
|
363 } else { |
|
|
364 resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); |
|
|
365 ry += HEIGHT(c) + ih; |
|
|
366 } |
|
|
367 } |
|
|
368 } |
|
|
369 } |
|
|
370 |
|
|
371 void |
|
|
372 centeredfloatingmaster(Monitor *m) |
|
|
373 { |
|
|
374 unsigned int i, n; |
|
|
375 float mfacts, sfacts; |
|
|
376 float mivf = 1.0; // master inner vertical gap factor |
|
|
377 int oh, ov, ih, iv, mrest, srest; |
|
|
378 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
379 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
380 Client *c; |
|
|
381 |
|
|
382 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
383 if (n == 0) |
|
|
384 return; |
|
|
385 |
|
|
386 sx = mx = m->wx + ov; |
|
|
387 sy = my = m->wy + oh; |
|
|
388 sh = mh = m->wh - 2*oh; |
|
|
389 mw = m->ww - 2*ov - iv*(n - 1); |
|
|
390 sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); |
|
|
391 |
|
|
392 if (m->nmaster && n > m->nmaster) { |
|
|
393 mivf = 0.8; |
|
|
394 /* go mfact box in the center if more than nmaster clients */ |
|
|
395 if (m->ww > m->wh) { |
|
|
396 mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); |
|
|
397 mh = m->wh * 0.9; |
|
|
398 } else { |
|
|
399 mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); |
|
|
400 mh = m->wh * m->mfact; |
|
|
401 } |
|
|
402 mx = m->wx + (m->ww - mw) / 2; |
|
|
403 my = m->wy + (m->wh - mh - 2*oh) / 2; |
|
|
404 |
|
|
405 sx = m->wx + ov; |
|
|
406 sy = m->wy + oh; |
|
|
407 sh = m->wh - 2*oh; |
|
|
408 } |
|
|
409 |
|
|
410 getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); |
|
|
411 |
|
|
412 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
413 if (i < m->nmaster) { |
|
|
414 /* nmaster clients are stacked horizontally, in the center of the screen */ |
|
|
415 resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); |
|
|
416 mx += WIDTH(c) + iv*mivf; |
|
|
417 } else { |
|
|
418 /* stack clients are stacked horizontally */ |
|
|
419 resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); |
|
|
420 sx += WIDTH(c) + iv; |
|
|
421 } |
|
|
422 } |
|
|
423 |
|
|
424 /* |
|
|
425 * Deck layout + gaps |
|
|
426 * https://dwm.suckless.org/patches/deck/ |
|
|
427 */ |
|
|
428 void |
|
|
429 deck(Monitor *m) |
|
|
430 { |
|
|
431 unsigned int i, n; |
|
|
432 int oh, ov, ih, iv; |
|
|
433 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
434 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
435 float mfacts, sfacts; |
|
|
436 int mrest, srest; |
|
|
437 Client *c; |
|
|
438 |
|
|
439 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
440 if (n == 0) |
|
|
441 return; |
|
|
442 |
|
|
443 sx = mx = m->wx + ov; |
|
|
444 sy = my = m->wy + oh; |
|
|
445 sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); |
|
|
446 sw = mw = m->ww - 2*ov; |
|
|
447 |
|
|
448 if (m->nmaster && n > m->nmaster) { |
|
|
449 sw = (mw - iv) * (1 - m->mfact); |
|
|
450 mw = mw - iv - sw; |
|
|
451 sx = mx + mw + iv; |
|
|
452 sh = m->wh - 2*oh; |
|
|
453 } |
|
|
454 |
|
|
455 getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); |
|
|
456 |
|
|
457 if (n - m->nmaster > 0) /* override layout symbol */ |
|
|
458 snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); |
|
|
459 |
|
|
460 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
461 if (i < m->nmaster) { |
|
|
462 resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); |
|
|
463 my += HEIGHT(c) + ih; |
|
|
464 } else { |
|
|
465 resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); |
|
|
466 } |
|
|
467 } |
|
|
468 |
|
|
469 /* |
|
|
470 * Fibonacci layout + gaps |
|
|
471 * https://dwm.suckless.org/patches/fibonacci/ |
|
|
472 */ |
|
|
473 void |
|
|
474 fibonacci(Monitor *m, int s) |
|
|
475 { |
|
|
476 unsigned int i, n; |
|
|
477 int nx, ny, nw, nh; |
|
|
478 int oh, ov, ih, iv; |
|
|
479 int nv, hrest = 0, wrest = 0, r = 1; |
|
|
480 Client *c; |
|
|
481 |
|
|
482 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
483 if (n == 0) |
|
|
484 return; |
|
|
485 |
|
|
486 nx = m->wx + ov; |
|
|
487 ny = m->wy + oh; |
|
|
488 nw = m->ww - 2*ov; |
|
|
489 nh = m->wh - 2*oh; |
|
|
490 |
|
|
491 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { |
|
|
492 if (r) { |
|
|
493 if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) |
|
|
494 || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { |
|
|
495 r = 0; |
|
|
496 } |
|
|
497 if (r && i < n - 1) { |
|
|
498 if (i % 2) { |
|
|
499 nv = (nh - ih) / 2; |
|
|
500 hrest = nh - 2*nv - ih; |
|
|
501 nh = nv; |
|
|
502 } else { |
|
|
503 nv = (nw - iv) / 2; |
|
|
504 wrest = nw - 2*nv - iv; |
|
|
505 nw = nv; |
|
|
506 } |
|
|
507 |
|
|
508 if ((i % 4) == 2 && !s) |
|
|
509 nx += nw + iv; |
|
|
510 else if ((i % 4) == 3 && !s) |
|
|
511 ny += nh + ih; |
|
|
512 } |
|
|
513 |
|
|
514 if ((i % 4) == 0) { |
|
|
515 if (s) { |
|
|
516 ny += nh + ih; |
|
|
517 nh += hrest; |
|
|
518 } |
|
|
519 else { |
|
|
520 nh -= hrest; |
|
|
521 ny -= nh + ih; |
|
|
522 } |
|
|
523 } |
|
|
524 else if ((i % 4) == 1) { |
|
|
525 nx += nw + iv; |
|
|
526 nw += wrest; |
|
|
527 } |
|
|
528 else if ((i % 4) == 2) { |
|
|
529 ny += nh + ih; |
|
|
530 nh += hrest; |
|
|
531 if (i < n - 1) |
|
|
532 nw += wrest; |
|
|
533 } |
|
|
534 else if ((i % 4) == 3) { |
|
|
535 if (s) { |
|
|
536 nx += nw + iv; |
|
|
537 nw -= wrest; |
|
|
538 } else { |
|
|
539 nw -= wrest; |
|
|
540 nx -= nw + iv; |
|
|
541 nh += hrest; |
|
|
542 } |
|
|
543 } |
|
|
544 if (i == 0) { |
|
|
545 if (n != 1) { |
|
|
546 nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); |
|
|
547 wrest = 0; |
|
|
548 } |
|
|
549 ny = m->wy + oh; |
|
|
550 } |
|
|
551 else if (i == 1) |
|
|
552 nw = m->ww - nw - iv - 2*ov; |
|
|
553 i++; |
|
|
554 } |
|
|
555 |
|
|
556 resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); |
|
|
557 } |
|
|
558 } |
|
|
559 |
|
|
560 void |
|
|
561 dwindle(Monitor *m) |
|
|
562 { |
|
|
563 fibonacci(m, 1); |
|
|
564 } |
|
|
565 |
|
|
566 void |
|
|
567 spiral(Monitor *m) |
|
|
568 { |
|
|
569 fibonacci(m, 0); |
|
|
570 } |
|
|
571 |
|
|
572 /* |
|
|
573 * Gappless grid layout + gaps (ironically) |
|
|
574 * https://dwm.suckless.org/patches/gaplessgrid/ |
|
|
575 */ |
|
|
576 void |
|
|
577 gaplessgrid(Monitor *m) |
|
|
578 { |
|
|
579 unsigned int i, n; |
|
|
580 int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters |
|
|
581 int oh, ov, ih, iv; |
|
|
582 Client *c; |
|
|
583 |
|
|
584 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
585 if (n == 0) |
|
|
586 return; |
|
|
587 |
|
|
588 /* grid dimensions */ |
|
|
589 for (cols = 0; cols <= n/2; cols++) |
|
|
590 if (cols*cols >= n) |
|
|
591 break; |
|
|
592 if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ |
|
|
593 cols = 2; |
|
|
594 rows = n/cols; |
|
|
595 cn = rn = 0; // reset column no, row no, client count |
|
|
596 |
|
|
597 ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; |
|
|
598 cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; |
|
|
599 rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; |
|
|
600 crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; |
|
|
601 x = m->wx + ov; |
|
|
602 y = m->wy + oh; |
|
|
603 |
|
|
604 for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { |
|
|
605 if (i/rows + 1 > cols - n%cols) { |
|
|
606 rows = n/cols + 1; |
|
|
607 ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; |
|
|
608 rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; |
|
|
609 } |
|
|
610 resize(c, |
|
|
611 x, |
|
|
612 y + rn*(ch + ih) + MIN(rn, rrest), |
|
|
613 cw + (cn < crest ? 1 : 0) - 2*c->bw, |
|
|
614 ch + (rn < rrest ? 1 : 0) - 2*c->bw, |
|
|
615 0); |
|
|
616 rn++; |
|
|
617 if (rn >= rows) { |
|
|
618 rn = 0; |
|
|
619 x += cw + ih + (cn < crest ? 1 : 0); |
|
|
620 cn++; |
|
|
621 } |
|
|
622 } |
|
|
623 } |
|
|
624 |
|
|
625 /* |
|
|
626 * Gridmode layout + gaps |
|
|
627 * https://dwm.suckless.org/patches/gridmode/ |
|
|
628 */ |
|
|
629 void |
|
|
630 grid(Monitor *m) |
|
|
631 { |
|
|
632 unsigned int i, n; |
|
|
633 int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; |
|
|
634 int oh, ov, ih, iv; |
|
|
635 Client *c; |
|
|
636 |
|
|
637 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
638 |
|
|
639 /* grid dimensions */ |
|
|
640 for (rows = 0; rows <= n/2; rows++) |
|
|
641 if (rows*rows >= n) |
|
|
642 break; |
|
|
643 cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; |
|
|
644 |
|
|
645 /* window geoms (cell height/width) */ |
|
|
646 ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); |
|
|
647 cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); |
|
|
648 chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; |
|
|
649 cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; |
|
|
650 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { |
|
|
651 cc = i / rows; |
|
|
652 cr = i % rows; |
|
|
653 cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); |
|
|
654 cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); |
|
|
655 resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); |
|
|
656 } |
|
|
657 } |
|
|
658 |
|
|
659 /* |
|
|
660 * Horizontal grid layout + gaps |
|
|
661 * https://dwm.suckless.org/patches/horizgrid/ |
|
|
662 */ |
|
|
663 void |
|
|
664 horizgrid(Monitor *m) { |
|
|
665 Client *c; |
|
|
666 unsigned int n, i; |
|
|
667 int oh, ov, ih, iv; |
|
|
668 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
669 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
670 int ntop, nbottom = 1; |
|
|
671 float mfacts = 0, sfacts = 0; |
|
|
672 int mrest, srest, mtotal = 0, stotal = 0; |
|
|
673 |
|
|
674 /* Count windows */ |
|
|
675 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
676 if (n == 0) |
|
|
677 return; |
|
|
678 |
|
|
679 if (n <= 2) |
|
|
680 ntop = n; |
|
|
681 else { |
|
|
682 ntop = n / 2; |
|
|
683 nbottom = n - ntop; |
|
|
684 } |
|
|
685 sx = mx = m->wx + ov; |
|
|
686 sy = my = m->wy + oh; |
|
|
687 sh = mh = m->wh - 2*oh; |
|
|
688 sw = mw = m->ww - 2*ov; |
|
|
689 |
|
|
690 if (n > ntop) { |
|
|
691 sh = (mh - ih) / 2; |
|
|
692 mh = mh - ih - sh; |
|
|
693 sy = my + mh + ih; |
|
|
694 mw = m->ww - 2*ov - iv * (ntop - 1); |
|
|
695 sw = m->ww - 2*ov - iv * (nbottom - 1); |
|
|
696 } |
|
|
697 |
|
|
698 /* calculate facts */ |
|
|
699 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
700 if (i < ntop) |
|
|
701 mfacts += c->cfact; |
|
|
702 else |
|
|
703 sfacts += c->cfact; |
|
|
704 |
|
|
705 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
706 if (i < ntop) |
|
|
707 mtotal += mh * (c->cfact / mfacts); |
|
|
708 else |
|
|
709 stotal += sw * (c->cfact / sfacts); |
|
|
710 |
|
|
711 mrest = mh - mtotal; |
|
|
712 srest = sw - stotal; |
|
|
713 |
|
|
714 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
715 if (i < ntop) { |
|
|
716 resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); |
|
|
717 mx += WIDTH(c) + iv; |
|
|
718 } else { |
|
|
719 resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); |
|
|
720 sx += WIDTH(c) + iv; |
|
|
721 } |
|
|
722 } |
|
|
723 |
|
|
724 /* |
|
|
725 * nrowgrid layout + gaps |
|
|
726 * https://dwm.suckless.org/patches/nrowgrid/ |
|
|
727 */ |
|
|
728 void |
|
|
729 nrowgrid(Monitor *m) |
|
|
730 { |
|
|
731 unsigned int n; |
|
|
732 int ri = 0, ci = 0; /* counters */ |
|
|
733 int oh, ov, ih, iv; /* vanitygap settings */ |
|
|
734 unsigned int cx, cy, cw, ch; /* client geometry */ |
|
|
735 unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ |
|
|
736 unsigned int cols, rows = m->nmaster + 1; |
|
|
737 Client *c; |
|
|
738 |
|
|
739 /* count clients */ |
|
|
740 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
741 |
|
|
742 /* nothing to do here */ |
|
|
743 if (n == 0) |
|
|
744 return; |
|
|
745 |
|
|
746 /* force 2 clients to always split vertically */ |
|
|
747 if (FORCE_VSPLIT && n == 2) |
|
|
748 rows = 1; |
|
|
749 |
|
|
750 /* never allow empty rows */ |
|
|
751 if (n < rows) |
|
|
752 rows = n; |
|
|
753 |
|
|
754 /* define first row */ |
|
|
755 cols = n / rows; |
|
|
756 uc = cols; |
|
|
757 cy = m->wy + oh; |
|
|
758 ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; |
|
|
759 uh = ch; |
|
|
760 |
|
|
761 for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) { |
|
|
762 if (ci == cols) { |
|
|
763 uw = 0; |
|
|
764 ci = 0; |
|
|
765 ri++; |
|
|
766 |
|
|
767 /* next row */ |
|
|
768 cols = (n - uc) / (rows - ri); |
|
|
769 uc += cols; |
|
|
770 cy = m->wy + oh + uh + ih; |
|
|
771 uh += ch + ih; |
|
|
772 } |
|
|
773 |
|
|
774 cx = m->wx + ov + uw; |
|
|
775 cw = (m->ww - 2*ov - uw) / (cols - ci); |
|
|
776 uw += cw + iv; |
|
|
777 |
|
|
778 resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); |
|
|
779 } |
|
|
780 } |
|
|
781 |
|
|
782 /* |
|
|
783 * Default tile layout + gaps |
|
|
784 */ |
|
|
785 static void |
|
|
786 tile(Monitor *m) |
|
|
787 { |
|
|
788 unsigned int i, n; |
|
|
789 int oh, ov, ih, iv; |
|
|
790 int mx = 0, my = 0, mh = 0, mw = 0; |
|
|
791 int sx = 0, sy = 0, sh = 0, sw = 0; |
|
|
792 float mfacts, sfacts; |
|
|
793 int mrest, srest; |
|
|
794 Client *c; |
|
|
795 |
|
|
796 getgaps(m, &oh, &ov, &ih, &iv, &n); |
|
|
797 if (n == 0) |
|
|
798 return; |
|
|
799 |
|
|
800 sx = mx = m->wx + ov; |
|
|
801 sy = my = m->wy + oh; |
|
|
802 mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); |
|
|
803 sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); |
|
|
804 sw = mw = m->ww - 2*ov; |
|
|
805 |
|
|
806 if (m->nmaster && n > m->nmaster) { |
|
|
807 sw = (mw - iv) * (1 - m->mfact); |
|
|
808 mw = mw - iv - sw; |
|
|
809 sx = mx + mw + iv; |
|
|
810 } |
|
|
811 |
|
|
812 getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); |
|
|
813 |
|
|
814 for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) |
|
|
815 if (i < m->nmaster) { |
|
|
816 resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); |
|
|
817 my += HEIGHT(c) + ih; |
|
|
818 } else { |
|
|
819 resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); |
|
|
820 sy += HEIGHT(c) + ih; |
|
|
821 } |
|
|
822 } |