dwm-flextile-20210722-138b405.diff (14514B)
1 From cb3d26193fafd0b06217c3bf2d65a6eac74b4941 Mon Sep 17 00:00:00 2001 2 From: Max Schillinger <maxschillinger@web.de> 3 Date: Thu, 22 Jul 2021 23:19:36 +0200 4 Subject: [PATCH] flextile layout for dwm commit 138b405 5 6 --- 7 config.def.h | 17 +++++- 8 dwm.c | 123 +++++++++++++++++++------------------- 9 flextile.h | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ 10 3 files changed, 238 insertions(+), 65 deletions(-) 11 create mode 100644 flextile.h 12 13 diff --git a/config.def.h b/config.def.h 14 index a2ac963..1330db2 100644 15 --- a/config.def.h 16 +++ b/config.def.h 17 @@ -21,6 +21,9 @@ static const char *colors[][3] = { 18 /* tagging */ 19 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 20 21 +/* include(s) depending on the tags array */ 22 +#include "flextile.h" 23 + 24 static const Rule rules[] = { 25 /* xprop(1): 26 * WM_CLASS(STRING) = instance, class 27 @@ -33,8 +36,12 @@ static const Rule rules[] = { 28 29 /* layout(s) */ 30 static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ 31 -static const int nmaster = 1; /* number of clients in master area */ 32 static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ 33 +static const int layoutaxis[] = { 34 + 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ 35 + 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ 36 + 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ 37 +}; 38 static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ 39 40 static const Layout layouts[] = { 41 @@ -67,8 +74,8 @@ static Key keys[] = { 42 { MODKEY, XK_b, togglebar, {0} }, 43 { MODKEY, XK_j, focusstack, {.i = +1 } }, 44 { MODKEY, XK_k, focusstack, {.i = -1 } }, 45 - { MODKEY, XK_i, incnmaster, {.i = +1 } }, 46 - { MODKEY, XK_d, incnmaster, {.i = -1 } }, 47 + { MODKEY, XK_i, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ 48 + { MODKEY, XK_d, shiftmastersplit, {.i = -1} }, /* reduce the number of tiled clients in the master area */ 49 { MODKEY, XK_h, setmfact, {.f = -0.05} }, 50 { MODKEY, XK_l, setmfact, {.f = +0.05} }, 51 { MODKEY, XK_Return, zoom, {0} }, 52 @@ -95,6 +102,10 @@ static Key keys[] = { 53 TAGKEYS( XK_8, 7) 54 TAGKEYS( XK_9, 8) 55 { MODKEY|ShiftMask, XK_q, quit, {0} }, 56 + { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0} }, /* 0 = layout axis */ 57 + { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1} }, /* 1 = master axis */ 58 + { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2} }, /* 2 = stack axis */ 59 + { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, 60 }; 61 62 /* button definitions */ 63 diff --git a/dwm.c b/dwm.c 64 index 5e4d494..1f1487a 100644 65 --- a/dwm.c 66 +++ b/dwm.c 67 @@ -111,27 +111,6 @@ typedef struct { 68 void (*arrange)(Monitor *); 69 } Layout; 70 71 -struct Monitor { 72 - char ltsymbol[16]; 73 - float mfact; 74 - int nmaster; 75 - int num; 76 - int by; /* bar geometry */ 77 - int mx, my, mw, mh; /* screen size */ 78 - int wx, wy, ww, wh; /* window area */ 79 - unsigned int seltags; 80 - unsigned int sellt; 81 - unsigned int tagset[2]; 82 - int showbar; 83 - int topbar; 84 - Client *clients; 85 - Client *sel; 86 - Client *stack; 87 - Monitor *next; 88 - Window barwin; 89 - const Layout *lt[2]; 90 -}; 91 - 92 typedef struct { 93 const char *class; 94 const char *instance; 95 @@ -175,7 +154,6 @@ static long getstate(Window w); 96 static int gettextprop(Window w, Atom atom, char *text, unsigned int size); 97 static void grabbuttons(Client *c, int focused); 98 static void grabkeys(void); 99 -static void incnmaster(const Arg *arg); 100 static void keypress(XEvent *e); 101 static void killclient(const Arg *arg); 102 static void manage(Window w, XWindowAttributes *wa); 103 @@ -631,17 +609,32 @@ configurerequest(XEvent *e) 104 Monitor * 105 createmon(void) 106 { 107 + unsigned int i; 108 Monitor *m; 109 110 m = ecalloc(1, sizeof(Monitor)); 111 m->tagset[0] = m->tagset[1] = 1; 112 m->mfact = mfact; 113 - m->nmaster = nmaster; 114 m->showbar = showbar; 115 m->topbar = topbar; 116 m->lt[0] = &layouts[0]; 117 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 118 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 119 + m->ltaxis[0] = layoutaxis[0]; 120 + m->ltaxis[1] = layoutaxis[1]; 121 + m->ltaxis[2] = layoutaxis[2]; 122 + m->msplit = 1; 123 + /* init tags, bars, layouts, axes, msplits and mfacts */ 124 + m->curtag = m->prevtag = 1; 125 + for(i = 0; i < LENGTH(tags) + 1; i++){ 126 + m->showbars[i] = m->showbar; 127 + m->lts[i] = &layouts[0]; 128 + m->mfacts[i] = m->mfact; 129 + m->ltaxes[i][0] = m->ltaxis[0]; 130 + m->ltaxes[i][1] = m->ltaxis[1]; 131 + m->ltaxes[i][2] = m->ltaxis[2]; 132 + m->msplits[i] = m->msplit; 133 + } 134 return m; 135 } 136 137 @@ -964,13 +957,6 @@ grabkeys(void) 138 } 139 } 140 141 -void 142 -incnmaster(const Arg *arg) 143 -{ 144 - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 145 - arrange(selmon); 146 -} 147 - 148 #ifdef XINERAMA 149 static int 150 isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) 151 @@ -1504,7 +1490,7 @@ setlayout(const Arg *arg) 152 if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 153 selmon->sellt ^= 1; 154 if (arg && arg->v) 155 - selmon->lt[selmon->sellt] = (Layout *)arg->v; 156 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; 157 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 158 if (selmon->sel) 159 arrange(selmon); 160 @@ -1523,7 +1509,7 @@ setmfact(const Arg *arg) 161 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 162 if (f < 0.05 || f > 0.95) 163 return; 164 - selmon->mfact = f; 165 + selmon->mfact = selmon->mfacts[selmon->curtag] = f; 166 arrange(selmon); 167 } 168 169 @@ -1671,38 +1657,10 @@ tagmon(const Arg *arg) 170 sendmon(selmon->sel, dirtomon(arg->i)); 171 } 172 173 -void 174 -tile(Monitor *m) 175 -{ 176 - unsigned int i, n, h, mw, my, ty; 177 - Client *c; 178 - 179 - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 180 - if (n == 0) 181 - return; 182 - 183 - if (n > m->nmaster) 184 - mw = m->nmaster ? m->ww * m->mfact : 0; 185 - else 186 - mw = m->ww; 187 - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 188 - if (i < m->nmaster) { 189 - h = (m->wh - my) / (MIN(n, m->nmaster) - i); 190 - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); 191 - if (my + HEIGHT(c) < m->wh) 192 - my += HEIGHT(c); 193 - } else { 194 - h = (m->wh - ty) / (n - i); 195 - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); 196 - if (ty + HEIGHT(c) < m->wh) 197 - ty += HEIGHT(c); 198 - } 199 -} 200 - 201 void 202 togglebar(const Arg *arg) 203 { 204 - selmon->showbar = !selmon->showbar; 205 + selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; 206 updatebarpos(selmon); 207 XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 208 arrange(selmon); 209 @@ -1726,12 +1684,31 @@ void 210 toggletag(const Arg *arg) 211 { 212 unsigned int newtags; 213 + unsigned int i; 214 215 if (!selmon->sel) 216 return; 217 newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 218 if (newtags) { 219 selmon->sel->tags = newtags; 220 + if(newtags == ~0) { 221 + selmon->prevtag = selmon->curtag; 222 + selmon->curtag = 0; 223 + } 224 + if(!(newtags & 1 << (selmon->curtag - 1))) { 225 + selmon->prevtag = selmon->curtag; 226 + for (i=0; !(newtags & 1 << i); i++); 227 + selmon->curtag = i + 1; 228 + } 229 + selmon->sel->tags = newtags; 230 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; 231 + selmon->mfact = selmon->mfacts[selmon->curtag]; 232 + if (selmon->showbar != selmon->showbars[selmon->curtag]) 233 + togglebar(NULL); 234 + selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; 235 + selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; 236 + selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; 237 + selmon->msplit = selmon->msplits[selmon->curtag]; 238 focus(NULL); 239 arrange(selmon); 240 } 241 @@ -2038,11 +2015,33 @@ updatewmhints(Client *c) 242 void 243 view(const Arg *arg) 244 { 245 + unsigned int i; 246 + 247 if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 248 return; 249 selmon->seltags ^= 1; /* toggle sel tagset */ 250 - if (arg->ui & TAGMASK) 251 + if (arg->ui & TAGMASK) { 252 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 253 + selmon->prevtag = selmon->curtag; 254 + if(arg->ui == ~0) 255 + selmon->curtag = 0; 256 + else { 257 + for (i=0; !(arg->ui & 1 << i); i++); 258 + selmon->curtag = i + 1; 259 + } 260 + } else { 261 + selmon->prevtag = selmon->curtag ^ selmon->prevtag; 262 + selmon->curtag ^= selmon->prevtag; 263 + selmon->prevtag = selmon->curtag ^ selmon->prevtag; 264 + } 265 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; 266 + selmon->mfact = selmon->mfacts[selmon->curtag]; 267 + if(selmon->showbar != selmon->showbars[selmon->curtag]) 268 + togglebar(NULL); 269 + selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; 270 + selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; 271 + selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; 272 + selmon->msplit = selmon->msplits[selmon->curtag]; 273 focus(NULL); 274 arrange(selmon); 275 } 276 diff --git a/flextile.h b/flextile.h 277 new file mode 100644 278 index 0000000..edab893 279 --- /dev/null 280 +++ b/flextile.h 281 @@ -0,0 +1,163 @@ 282 +/* See LICENSE file for copyright and license details. */ 283 +/* © 2010 joten <joten@freenet.de> */ 284 + 285 +struct Monitor { 286 + char ltsymbol[16]; 287 + float mfact; 288 + double mfacts[LENGTH(tags) + 1]; 289 + int ltaxis[3]; 290 + int ltaxes[LENGTH(tags) + 1][3]; 291 + int num; 292 + int curtag; 293 + int prevtag; 294 + int by; /* bar geometry */ 295 + int mx, my, mw, mh; /* screen size */ 296 + int wx, wy, ww, wh; /* window area */ 297 + unsigned int msplit; 298 + unsigned int msplits[LENGTH(tags) + 1]; 299 + unsigned int seltags; 300 + unsigned int sellt; 301 + unsigned int tagset[2]; 302 + int showbar; 303 + int showbars[LENGTH(tags) + 1]; 304 + int topbar; 305 + Client *clients; 306 + Client *sel; 307 + Client *stack; 308 + Monitor *next; 309 + Window barwin; 310 + const Layout *lt[2]; 311 + const Layout *lts[LENGTH(tags) + 1]; 312 +}; 313 + 314 +/* function declarations */ 315 +static void mirrorlayout(const Arg *arg); 316 +static void rotatelayoutaxis(const Arg *arg); 317 +static void shiftmastersplit(const Arg *arg); 318 + 319 +void 320 +mirrorlayout(const Arg *arg) 321 +{ 322 + if(!selmon->lt[selmon->sellt]->arrange) 323 + return; 324 + selmon->ltaxis[0] *= -1; 325 + selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0]; 326 + arrange(selmon); 327 +} 328 + 329 +void 330 +rotatelayoutaxis(const Arg *arg) 331 +{ 332 + if(!selmon->lt[selmon->sellt]->arrange) 333 + return; 334 + if(arg->i == 0) { 335 + if(selmon->ltaxis[0] > 0) 336 + selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 2 ? 1 : selmon->ltaxis[0] + 1; 337 + else 338 + selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -2 ? -1 : selmon->ltaxis[0] - 1; 339 + } else 340 + selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 3 ? 1 : selmon->ltaxis[arg->i] + 1; 341 + selmon->ltaxes[selmon->curtag][arg->i] = selmon->ltaxis[arg->i]; 342 + arrange(selmon); 343 +} 344 + 345 +void 346 +shiftmastersplit(const Arg *arg) 347 +{ 348 + unsigned int n; 349 + Client *c; 350 + 351 + for(n = 0, c = nexttiled(selmon->clients); c; c = nexttiled(c->next), n++); 352 + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->msplit + arg->i < 1 || selmon->msplit + arg->i > n) 353 + return; 354 + selmon->msplit += arg->i; 355 + selmon->msplits[selmon->curtag] = selmon->msplit; 356 + arrange(selmon); 357 +} 358 + 359 +void 360 +tile(Monitor *m) 361 +{ 362 + char sym1 = 61, sym2 = 93, sym3 = 61, sym; 363 + int x1 = m->wx, y1 = m->wy, h1 = m->wh, w1 = m->ww, X1 = x1 + w1, Y1 = y1 + h1; 364 + int x2 = m->wx, y2 = m->wy, h2 = m->wh, w2 = m->ww, X2 = x2 + w2, Y2 = y2 + h2; 365 + unsigned int i, n, n1, n2; 366 + Client *c; 367 + 368 + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 369 + if(m->msplit > n) 370 + m->msplit = (n == 0) ? 1 : n; 371 + /* layout symbol */ 372 + if(abs(m->ltaxis[0]) == m->ltaxis[1]) /* explicitly: ((abs(m->ltaxis[0]) == 1 && m->ltaxis[1] == 1) || (abs(m->ltaxis[0]) == 2 && m->ltaxis[1] == 2)) */ 373 + sym1 = 124; 374 + if(abs(m->ltaxis[0]) == m->ltaxis[2]) 375 + sym3 = 124; 376 + if(m->ltaxis[1] == 3) 377 + sym1 = (n == 0) ? 0 : m->msplit; 378 + if(m->ltaxis[2] == 3) 379 + sym3 = (n == 0) ? 0 : n - m->msplit; 380 + if(m->ltaxis[0] < 0) { 381 + sym = sym1; 382 + sym1 = sym3; 383 + sym2 = 91; 384 + sym3 = sym; 385 + } 386 + if(m->msplit == 1) { 387 + if(m->ltaxis[0] > 0) 388 + sym1 = 91; 389 + else 390 + sym3 = 93; 391 + } 392 + if(m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[2] == 3) 393 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3); 394 + else if((m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] > 0) || (m->ltaxis[2] == 3 && m->ltaxis[0] < 0)) 395 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3); 396 + else if((m->ltaxis[2] == 3 && m->ltaxis[0] > 0) || (m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] < 0)) 397 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, sym3); 398 + else 399 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); 400 + if(n == 0) 401 + return; 402 + /* master and stack area */ 403 + if(abs(m->ltaxis[0]) == 1 && n > m->msplit) { 404 + w1 *= m->mfact; 405 + w2 -= w1; 406 + x1 += (m->ltaxis[0] < 0) ? w2 : 0; 407 + x2 += (m->ltaxis[0] < 0) ? 0 : w1; 408 + X1 = x1 + w1; 409 + X2 = x2 + w2; 410 + } else if(abs(m->ltaxis[0]) == 2 && n > m->msplit) { 411 + h1 *= m->mfact; 412 + h2 -= h1; 413 + y1 += (m->ltaxis[0] < 0) ? h2 : 0; 414 + y2 += (m->ltaxis[0] < 0) ? 0 : h1; 415 + Y1 = y1 + h1; 416 + Y2 = y2 + h2; 417 + } 418 + /* master */ 419 + n1 = (m->ltaxis[1] != 1 || w1 / m->msplit < bh) ? 1 : m->msplit; 420 + n2 = (m->ltaxis[1] != 2 || h1 / m->msplit < bh) ? 1 : m->msplit; 421 + for(i = 0, c = nexttiled(m->clients); i < m->msplit; c = nexttiled(c->next), i++) { 422 + resize(c, x1, y1, 423 + (m->ltaxis[1] == 1 && i + 1 == m->msplit) ? X1 - x1 - 2 * c->bw : w1 / n1 - 2 * c->bw, 424 + (m->ltaxis[1] == 2 && i + 1 == m->msplit) ? Y1 - y1 - 2 * c->bw : h1 / n2 - 2 * c->bw, False); 425 + if(n1 > 1) 426 + x1 = c->x + WIDTH(c); 427 + if(n2 > 1) 428 + y1 = c->y + HEIGHT(c); 429 + } 430 + /* stack */ 431 + if(n > m->msplit) { 432 + n1 = (m->ltaxis[2] != 1 || w2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; 433 + n2 = (m->ltaxis[2] != 2 || h2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; 434 + for(i = 0; c; c = nexttiled(c->next), i++) { 435 + resize(c, x2, y2, 436 + (m->ltaxis[2] == 1 && i + 1 == n - m->msplit) ? X2 - x2 - 2 * c->bw : w2 / n1 - 2 * c->bw, 437 + (m->ltaxis[2] == 2 && i + 1 == n - m->msplit) ? Y2 - y2 - 2 * c->bw : h2 / n2 - 2 * c->bw, False); 438 + if(n1 > 1) 439 + x2 = c->x + WIDTH(c); 440 + if(n2 > 1) 441 + y2 = c->y + HEIGHT(c); 442 + } 443 + } 444 +} 445 -- 446 2.25.1 447