diff --git a/README.md b/README.md index 42d22b9..72e9e35 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ For example to include the `alpha` patch then you would only need to flip this s #define ALPHA_PATCH 1 ``` -So if you have ever been curious about trying out dwm, but have been discouraged by manual patching, then this may be a good starting point to see what a "fully fledged" dwm can look like. Want to try out the `pertag` patch? Just flip a config and recompile. Once you have found out what works for you and what don't then you should be in a better position to choose patches should you want to start patching from scratch. +So if you have ever been curious about trying out dwm, but have been discouraged by manual patching, then this may be a good starting point to see what a "fully fledged" dwm can look like. Want to try out the `pertag` patch? Just flip a config and recompile. Once you have found out what works for you and what doesn't then you should be in a better position to choose patches should you want to start patching from scratch. Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on the dwm window manager, how to install it and how it works. @@ -13,6 +13,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2019-09-30 - Replaced flextile with flextile-deluxe, refactored monitor rules to support predetermined layouts per tag + 2019-09-15 - Added focusonclick, xrdb, viewontag, urgentborder and winview patches 2019-09-14 - Added setborderpx, selfrestart and push (no master variant), sticky and warp patches @@ -202,12 +204,13 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - [fibonacci](https://dwm.suckless.org/patches/fibonacci/) - fibonacci (dwindle and spiral) layouts - - [flextile](https://dwm.suckless.org/patches/flextile/) - - expanded flextile patch supporting: - - horizontal and vertical split - - centered horizontal and vertical split - - pertag, cfacts, rmaster, vanitygaps patches + - flextile-deluxe + - a re-envisioned, flexible and over-the-top version of the original [flextile](https://dwm.suckless.org/patches/flextile/) patch supporting + - multiple split layouts (horizontal, vertical, centered, floating, fixed) + - tile arrangement on a per split basis (stack horizontally, stack vertically, grids, fibonacci) + - pertag, cfacts, rmaster, vanitygaps compatibility - tile, deck, monocle, centeredmaster, bstack, bstackhoriz, gapplessgrid and more + - this gives you a lot of versatility in terms of layout - [gapplessgrid](https://dwm.suckless.org/patches/gaplessgrid/) - gappless grid layout diff --git a/config.def.h b/config.def.h index e264434..7ec5e3d 100644 --- a/config.def.h +++ b/config.def.h @@ -179,34 +179,53 @@ static const Rule rules[] = { }; #if MONITOR_RULES_PATCH +#if PERTAG_PATCH static const MonitorRule monrules[] = { - #if FLEXTILE_LAYOUT - /* monitor layout axis master stack */ - { 1, 0, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, GRID, }, // use a different layout for the second monitor - { -1, 0, SPLIT_VERTICAL, TOP_TO_BOTTOM, TOP_TO_BOTTOM, }, // default - #else - /* monitor layout */ - { 1, 2 }, // use a different layout for the second monitor - { -1, 0 }, // default - #endif // FLEXTILE_LAYOUT + /* monitor tag layout mfact */ + { 1, -1, 2, -1 }, // use a different layout for the second monitor + { -1, -1, 0, -1 }, // default }; -#elif FLEXTILE_LAYOUT -static const int layoutaxis[] = { - SPLIT_VERTICAL, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ - TOP_TO_BOTTOM, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle), 4 = grid */ - TOP_TO_BOTTOM, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle), 4 = grid */ +#else +static const MonitorRule monrules[] = { + /* monitor layout mfact */ + { 1, 2, -1 }, // use a different layout for the second monitor + { -1, 0, -1 }, // default }; +#endif // PERTAG_PATCH #endif // MONITOR_RULES_PATCH /* layout(s) */ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ static const int nmaster = 1; /* number of clients in master area */ +#if FLEXTILE_DELUXE_LAYOUT +static const int nstack = 0; /* number of clients in primary stack area */ +#endif // FLEXTILE_DELUXE_LAYOUT static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ #if NROWGRID_LAYOUT #define FORCE_VSPLIT 1 #endif +#if FLEXTILE_DELUXE_LAYOUT +static const Layout layouts[] = { + /* symbol arrange function, { nmaster, nstack, layout, master axis, stack axis, secondary stack axis } */ + { "[]=", flextile, { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, TOP_TO_BOTTOM, 0, NULL } }, // default tile layout + { "><>", NULL, {0} }, /* no layout function means floating behavior */ + { "[M]", flextile, { -1, -1, NO_SPLIT, MONOCLE, 0, 0, NULL } }, // monocle + { ">M>", flextile, { -1, -1, FLOATING_MASTER, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL } }, // floating master + { "[D]", flextile, { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, MONOCLE, 0, NULL } }, // deck + { "TTT", flextile, { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL } }, // bstack + { "===", flextile, { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL } }, // bstackhoriz + { "|M|", flextile, { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, monoclesymbols } }, // centeredmaster + { ":::", flextile, { -1, -1, NO_SPLIT, GAPPLESSGRID, 0, 0, NULL } }, // gappless grid + { "[\\]", flextile, { -1, -1, NO_SPLIT, DWINDLE, 0, 0, NULL } }, // fibonacci dwindle + { "(@)", flextile, { -1, -1, NO_SPLIT, SPIRAL, 0, 0, NULL } }, // fibonacci spiral + { "|||", flextile, { -1, -1, SPLIT_VERTICAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL } }, // columns (col) layout + #if CYCLELAYOUTS_PATCH + { NULL, NULL, {0} }, + #endif +}; +#else static const Layout layouts[] = { /* symbol arrange function */ #if TILE_LAYOUT @@ -237,9 +256,6 @@ static const Layout layouts[] = { #if FIBONACCI_DWINDLE_LAYOUT { "[\\]", dwindle }, #endif - #if FLEXTILE_LAYOUT - { "[]=", flextile }, - #endif #if GRIDMODE_LAYOUT { "HHH", grid }, #endif @@ -256,6 +272,7 @@ static const Layout layouts[] = { { NULL, NULL }, #endif }; +#endif // FLEXTILE_DELUXE_LAYOUT /* key definitions */ #define MODKEY Mod1Mask @@ -342,21 +359,13 @@ static Key keys[] = { { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - #if FLEXTILE_LAYOUT - { MODKEY, XK_w, setflexlayout, {.i = 293 } }, // centered master - { MODKEY, XK_e, setflexlayout, {.i = 273 } }, // bstackhoriz layout - { MODKEY, XK_r, setflexlayout, {.i = 272 } }, // bstack layout - { MODKEY, XK_v, setflexlayout, {.i = 261 } }, // default tile layout - { MODKEY, XK_g, setflexlayout, {.i = 263 } }, // tile + grid layout - { MODKEY|ControlMask, XK_w, setflexlayout, {.i = 7 } }, // grid - { MODKEY|ControlMask, XK_e, setflexlayout, {.i = 262 } }, // deck layout - { MODKEY|ControlMask, XK_r, setflexlayout, {.i = 6 } }, // monocle - { MODKEY|ControlMask, XK_g, setflexlayout, {.i = 257 } }, // columns (col) layout + #if FLEXTILE_DELUXE_LAYOUT { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0 } }, /* flextile, 0 = layout axis */ { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1 } }, /* flextile, 1 = master axis */ { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2 } }, /* flextile, 2 = stack axis */ + { MODKEY|ControlMask|Mod1Mask, XK_Tab, rotatelayoutaxis, {.i = 3 } }, /* flextile, 3 = secondary stack axis */ { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, /* flextile, flip master and stack areas */ - #endif // FLEXTILE_LAYOUT + #endif // FLEXTILE_DELUXE_LAYOUT { MODKEY, XK_space, setlayout, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, #if TOGGLEFULLSCREEN_PATCH diff --git a/dwm.c b/dwm.c index 093a9f8..f1d2ac7 100644 --- a/dwm.c +++ b/dwm.c @@ -162,9 +162,24 @@ typedef struct { const Arg arg; } Key; +#if FLEXTILE_DELUXE_LAYOUT +typedef struct { + int nmaster; + int nstack; + int layout; + int masteraxis; // master stack area + int stack1axis; // primary stack area + int stack2axis; // secondary stack area, e.g. centered master + void (*symbolfunc)(Monitor *, unsigned int); +} LayoutPreset; +#endif // FLEXTILE_DELUXE_LAYOUT + typedef struct { const char *symbol; void (*arrange)(Monitor *); + #if FLEXTILE_DELUXE_LAYOUT + LayoutPreset preset; + #endif // FLEXTILE_DELUXE_LAYOUT } Layout; #if PERTAG_PATCH @@ -173,9 +188,10 @@ typedef struct Pertag Pertag; struct Monitor { char ltsymbol[16]; float mfact; - #if FLEXTILE_LAYOUT - int ltaxis[3]; - #endif // FLEXTILE_LAYOUT + #if FLEXTILE_DELUXE_LAYOUT + int ltaxis[4]; + int nstack; + #endif // FLEXTILE_DELUXE_LAYOUT int nmaster; int num; int by; /* bar geometry */ @@ -234,12 +250,11 @@ typedef struct { #if MONITOR_RULES_PATCH typedef struct { int monitor; + #if PERTAG_PATCH + int tag; + #endif // PERTAG_PATCH int layout; - #if FLEXTILE_LAYOUT - int layoutaxis; - int masteraxis; - int stackaxis; - #endif + float mfact; } MonitorRule; #endif // MONITOR_RULES_PATCH @@ -456,6 +471,8 @@ applyrules(Client *c) if (newtagset) { c->mon->tagset[c->mon->seltags] = newtagset; + if (r->switchtag == 1) + pertagview(&((Arg) { .ui = newtagset })); arrange(c->mon); } } @@ -904,11 +921,11 @@ Monitor * createmon(void) { Monitor *m; - #if PERTAG_PATCH || MONITOR_RULES_PATCH + #if PERTAG_PATCH int i; - #endif // PERTAG_PATCH / MONITOR_RULES_PATCH + #endif // PERTAG_PATCH #if MONITOR_RULES_PATCH - int mc; + int mc, j; Monitor *mi; const MonitorRule *mr; #endif // MONITOR_RULES_PATCH @@ -917,6 +934,9 @@ createmon(void) m->tagset[0] = m->tagset[1] = 1; m->mfact = mfact; m->nmaster = nmaster; + #if FLEXTILE_DELUXE_LAYOUT + m->nstack = nstack; + #endif // FLEXTILE_DELUXE_LAYOUT m->showbar = showbar; m->topbar = topbar; #if SETBORDERPX_PATCH @@ -930,31 +950,32 @@ createmon(void) #endif // VANITYGAPS_PATCH #if MONITOR_RULES_PATCH for (mc = 0, mi = mons; mi; mi = mi->next, mc++); - for (i = 0; i < LENGTH(monrules); i++) { - mr = &monrules[i]; - if (mr->monitor == -1 || mr->monitor == mc) { + for (j = 0; j < LENGTH(monrules); j++) { + mr = &monrules[j]; + if ((mr->monitor == -1 || mr->monitor == mc) + #if PERTAG_PATCH + && (mr->tag == -1 || mr->tag == 0) + #endif // PERTAG_PATCH + ) { m->lt[0] = &layouts[mr->layout]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[mr->layout].symbol, sizeof m->ltsymbol); - #if FLEXTILE_LAYOUT - m->ltaxis[0] = mr->layoutaxis; - m->ltaxis[1] = mr->masteraxis; - m->ltaxis[2] = mr->stackaxis; - #endif // FLEXTILE_LAYOUT break; } } #else - #if FLEXTILE_LAYOUT - m->ltaxis[0] = layoutaxis[0]; - m->ltaxis[1] = layoutaxis[1]; - m->ltaxis[2] = layoutaxis[2]; - #endif // FLEXTILE_LAYOUT m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); #endif // MONITOR_RULES_PATCH + #if FLEXTILE_DELUXE_LAYOUT + m->ltaxis[LAYOUT] = m->lt[0]->preset.layout; + m->ltaxis[MASTER] = m->lt[0]->preset.masteraxis; + m->ltaxis[STACK] = m->lt[0]->preset.stack1axis; + m->ltaxis[STACK2] = m->lt[0]->preset.stack2axis; + #endif // FLEXTILE_DELUXE_LAYOUT + #if PERTAG_PATCH if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); @@ -963,20 +984,43 @@ createmon(void) /* init nmaster */ m->pertag->nmasters[i] = m->nmaster; + #if FLEXTILE_DELUXE_LAYOUT + m->pertag->nstacks[i] = m->nstack; + #endif // FLEXTILE_DELUXE_LAYOUT + /* init mfacts */ m->pertag->mfacts[i] = m->mfact; /* init layouts */ + #if MONITOR_RULES_PATCH + for (j = 0; j < LENGTH(monrules); j++) { + mr = &monrules[j]; + if ((mr->monitor == -1 || mr->monitor == mc) && (mr->tag == -1 || mr->tag == i)) { + m->pertag->ltidxs[i][0] = &layouts[mr->layout]; + m->pertag->ltidxs[i][1] = m->lt[0]; + if (mr->mfact != -1) + m->pertag->mfacts[i] = mr->mfact; + #if FLEXTILE_DELUXE_LAYOUT + m->pertag->ltaxis[i][LAYOUT] = m->pertag->ltidxs[i][0]->preset.layout; + m->pertag->ltaxis[i][MASTER] = m->pertag->ltidxs[i][0]->preset.masteraxis; + m->pertag->ltaxis[i][STACK] = m->pertag->ltidxs[i][0]->preset.stack1axis; + m->pertag->ltaxis[i][STACK2] = m->pertag->ltidxs[i][0]->preset.stack2axis; + #endif // FLEXTILE_DELUXE_LAYOUT + break; + } + } + #else m->pertag->ltidxs[i][0] = m->lt[0]; m->pertag->ltidxs[i][1] = m->lt[1]; - m->pertag->sellts[i] = m->sellt; - - #if FLEXTILE_LAYOUT + #if FLEXTILE_DELUXE_LAYOUT /* init flextile axes */ - m->pertag->ltaxes[i][0] = m->ltaxis[0]; - m->pertag->ltaxes[i][1] = m->ltaxis[1]; - m->pertag->ltaxes[i][2] = m->ltaxis[2]; - #endif // FLEXTILE_LAYOUT + m->pertag->ltaxis[i][LAYOUT] = m->ltaxis[LAYOUT]; + m->pertag->ltaxis[i][MASTER] = m->ltaxis[MASTER]; + m->pertag->ltaxis[i][STACK] = m->ltaxis[STACK]; + m->pertag->ltaxis[i][STACK2] = m->ltaxis[STACK2]; + #endif // FLEXTILE_DELUXE_LAYOUT + #endif // MONITOR_RULES_PATCH + m->pertag->sellts[i] = m->sellt; #if PERTAGBAR_PATCH /* init showbar */ @@ -2043,7 +2087,7 @@ restack(Monitor *m) XSync(dpy, False); while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); #if WARP_PATCH - if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2]) + if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2]) // <-- NB! hardcoded monocle warp(m->sel); #endif // WARP_PATCH } @@ -2237,6 +2281,25 @@ setlayout(const Arg *arg) #else selmon->lt[selmon->sellt] = (Layout *)arg->v; #endif // PERTAG_PATCH + + #if FLEXTILE_DELUXE_LAYOUT + if (selmon->lt[selmon->sellt]->preset.nmaster != -1) + selmon->nmaster = selmon->lt[selmon->sellt]->preset.nmaster; + if (selmon->lt[selmon->sellt]->preset.nstack != -1) + selmon->nstack = selmon->lt[selmon->sellt]->preset.nstack; + + selmon->ltaxis[LAYOUT] = selmon->lt[selmon->sellt]->preset.layout; + selmon->ltaxis[MASTER] = selmon->lt[selmon->sellt]->preset.masteraxis; + selmon->ltaxis[STACK] = selmon->lt[selmon->sellt]->preset.stack1axis; + selmon->ltaxis[STACK2] = selmon->lt[selmon->sellt]->preset.stack2axis; + + #if PERTAG_PATCH + selmon->pertag->ltaxis[selmon->pertag->curtag][LAYOUT] = selmon->ltaxis[LAYOUT]; + selmon->pertag->ltaxis[selmon->pertag->curtag][MASTER] = selmon->ltaxis[MASTER]; + selmon->pertag->ltaxis[selmon->pertag->curtag][STACK] = selmon->ltaxis[STACK]; + selmon->pertag->ltaxis[selmon->pertag->curtag][STACK2] = selmon->ltaxis[STACK2]; + #endif // PERTAG_PATCH + #endif // FLEXTILE_DELUXE_LAYOUT strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); if (selmon->sel) arrange(selmon); @@ -2957,38 +3020,11 @@ updatewmhints(Client *c) void view(const Arg *arg) { - #if PERTAG_PATCH - int i; - unsigned int tmptag; - #endif // PERTAG_PATCH - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; selmon->seltags ^= 1; /* toggle sel tagset */ #if PERTAG_PATCH - if (arg->ui & TAGMASK) { - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - if (arg->ui == ~0) - selmon->pertag->curtag = 0; - else { - for (i=0; !(arg->ui & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - #if PERTAGBAR_PATCH - if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) - togglebar(NULL); - #endif // PERTAGBAR_PATCH + pertagview(arg); #else if (arg->ui & TAGMASK) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; diff --git a/patch/cfacts.c b/patch/cfacts.c index b06098a..705e914 100644 --- a/patch/cfacts.c +++ b/patch/cfacts.c @@ -17,6 +17,7 @@ setcfact(const Arg *arg) arrange(selmon); } +#if BSTACK_LAYOUT || BSTACKHORIZ_LAYOUT || CENTEREDMASTER_LAYOUT || CENTEREDFLOATINGMASTER_LAYOUT || DECK_LAYOUT || TILE_LAYOUT || MONOCLE_LAYOUT void getfacts(Monitor *m, float *mf, float *sf) { @@ -30,6 +31,7 @@ getfacts(Monitor *m, float *mf, float *sf) else sfacts += c->cfact; } - *mf = mfacts; // total factor of master area - *sf = sfacts; // total factor of slave area -} \ No newline at end of file + *mf = mfacts; // total factor of master area + *sf = sfacts; // total factor of slave area +} +#endif \ No newline at end of file diff --git a/patch/cfacts.h b/patch/cfacts.h index 1005f97..bd32213 100644 --- a/patch/cfacts.h +++ b/patch/cfacts.h @@ -1,2 +1,4 @@ +#if BSTACK_LAYOUT || BSTACKHORIZ_LAYOUT || CENTEREDMASTER_LAYOUT || CENTEREDFLOATINGMASTER_LAYOUT || DECK_LAYOUT || TILE_LAYOUT || MONOCLE_LAYOUT static void getfacts(Monitor *m, float *mf, float *sf); +#endif static void setcfact(const Arg *arg); \ No newline at end of file diff --git a/patch/combo.c b/patch/combo.c index d34142a..3f13f16 100644 --- a/patch/combo.c +++ b/patch/combo.c @@ -1,13 +1,15 @@ static int combo = 0; void -keyrelease(XEvent *e) { +keyrelease(XEvent *e) +{ combo = 0; } void -combotag(const Arg *arg) { - if(selmon->sel && arg->ui & TAGMASK) { +combotag(const Arg *arg) +{ + if (selmon->sel && arg->ui & TAGMASK) { if (combo) { selmon->sel->tags |= arg->ui & TAGMASK; } else { @@ -20,15 +22,21 @@ combotag(const Arg *arg) { } void -comboview(const Arg *arg) { +comboview(const Arg *arg) +{ unsigned newtags = arg->ui & TAGMASK; if (combo) { selmon->tagset[selmon->seltags] |= newtags; } else { selmon->seltags ^= 1; /*toggle tagset*/ combo = 1; - if (newtags) + if (newtags) { + #if PERTAG_PATCH + pertagview(&((Arg) { .ui = newtags })); + #else selmon->tagset[selmon->seltags] = newtags; + #endif // PERTAG_PATCH + } } focus(NULL); arrange(selmon); diff --git a/patch/flextile-deluxe.c b/patch/flextile-deluxe.c new file mode 100644 index 0000000..ae6a870 --- /dev/null +++ b/patch/flextile-deluxe.c @@ -0,0 +1,658 @@ +typedef struct { + void (*arrange)(Monitor *, int, int, int, int, int, int, int); +} LayoutArranger; + +typedef struct { + void (*arrange)(Monitor *, int, int, int, int, int, int, int, int, int); +} TileArranger; + +static const LayoutArranger flexlayouts[] = { + { layout_no_split }, + { layout_split_vertical }, + { layout_split_horizontal }, + { layout_split_centered_vertical }, + { layout_split_centered_horizontal }, + { layout_split_vertical_dual_stack }, + { layout_split_horizontal_dual_stack }, + { layout_floating_master }, + { layout_split_vertical_fixed }, + { layout_split_horizontal_fixed }, + { layout_split_centered_vertical_fixed }, + { layout_split_centered_horizontal_fixed }, + { layout_split_vertical_dual_stack_fixed }, + { layout_split_horizontal_dual_stack_fixed }, + { layout_floating_master_fixed }, +}; + +static const TileArranger flextiles[] = { + { arrange_top_to_bottom }, + { arrange_left_to_right }, + { arrange_monocle }, + { arrange_gapplessgrid }, + { arrange_gridmode }, + { arrange_horizgrid }, + { arrange_dwindle }, + { arrange_spiral }, +}; + +static float +getfactsforrange(Monitor *m, int an, int ai) +{ + int i; + float facts; + Client *c; + + facts = 0; + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i >= ai && i < (ai + an)) + #if CFACTS_PATCH + facts += c->cfact; + #else + facts += 1; + #endif // CFACTS_PATCH + + return facts; +} + +static void +layout_no_split(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, n, 0); +} + +static void +layout_split_vertical(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (m->nmaster && n > m->nmaster) { + layout_split_vertical_fixed(m, x, y, h, w, ih, iv, n); + } else { + layout_no_split(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_vertical_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sw, sx; + + sw = (w - iv) * (1 - m->mfact); + w = (w - iv) * m->mfact; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sx = x; + x += sw + iv; + } else { + sx = x + w + iv; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, sx, y, h, sw, ih, iv, n, n - m->nmaster, m->nmaster); +} + +static void +layout_split_vertical_dual_stack(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (!m->nmaster || n <= m->nmaster) { + layout_no_split(m, x, y, h, w, ih, iv, n); + } else if (n <= m->nmaster + (m->nstack ? m->nstack : 1)) { + layout_split_vertical(m, x, y, h, w, ih, iv, n); + } else { + layout_split_vertical_dual_stack_fixed(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_vertical_dual_stack_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sh, sw, sx, oy, sc; + + if (m->nstack) + sc = m->nstack; + else + sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); + + sw = (w - iv) * (1 - m->mfact); + sh = (h - ih) / 2; + w = (w - iv) * m->mfact; + oy = y + sh + ih; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sx = x; + x += sw + iv; + } else { + sx = x + w + iv; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, sx, y, sh, sw, ih, iv, n, sc, m->nmaster); + (&flextiles[m->ltaxis[STACK2]])->arrange(m, sx, oy, sh, sw, ih, iv, n, n - m->nmaster - sc, m->nmaster + sc); +} + +static void +layout_split_horizontal(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (m->nmaster && n > m->nmaster) { + layout_split_horizontal_fixed(m, x, y, h, w, ih, iv, n); + } else { + layout_no_split(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_horizontal_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sh, sy; + + sh = (h - ih) * (1 - m->mfact); + h = (h - ih) * m->mfact; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sy = y; + y += sh + ih; + } else { + sy = y + h + ih; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, x, sy, sh, w, ih, iv, n, n - m->nmaster, m->nmaster); +} + +static void +layout_split_horizontal_dual_stack(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (!m->nmaster || n <= m->nmaster) { + layout_no_split(m, x, y, h, w, ih, iv, n); + } else if (n <= m->nmaster + (m->nstack ? m->nstack : 1)) { + layout_split_horizontal(m, x, y, h, w, ih, iv, n); + } else { + layout_split_horizontal_dual_stack_fixed(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_horizontal_dual_stack_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sh, sy, ox, sc; + + if (m->nstack) + sc = m->nstack; + else + sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); + + sh = (h - ih) * (1 - m->mfact); + h = (h - ih) * m->mfact; + sw = (w - iv) / 2; + ox = x + sw + iv; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sy = y; + y += sh + ih; + } else { + sy = y + h + ih; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, x, sy, sh, sw, ih, iv, n, sc, m->nmaster); + (&flextiles[m->ltaxis[STACK2]])->arrange(m, ox, sy, sh, sw, ih, iv, n, n - m->nmaster - sc, m->nmaster + sc); +} + +static void +layout_split_centered_vertical(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (!m->nmaster || n <= m->nmaster) { + layout_no_split(m, x, y, h, w, ih, iv, n); + } else if (n <= m->nmaster + (m->nstack ? m->nstack : 1)) { + layout_split_vertical(m, x, y, h, w, ih, iv, n); + } else { + layout_split_centered_vertical_fixed(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_centered_vertical_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sw, sx, ox, sc; + + if (m->nstack) + sc = m->nstack; + else + sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); + + sw = (w - 2*iv) * (1 - m->mfact) / 2; + w = (w - 2*iv) * m->mfact; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sx = x; + x += sw + iv; + ox = x + w + iv; + } else { + ox = x; + x += sw + iv; + sx = x + w + iv; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, sx, y, h, sw, ih, iv, n, sc, m->nmaster); + (&flextiles[m->ltaxis[STACK2]])->arrange(m, ox, y, h, sw, ih, iv, n, n - m->nmaster - sc, m->nmaster + sc); +} + +static void +layout_split_centered_horizontal(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (!m->nmaster || n <= m->nmaster) { + layout_no_split(m, x, y, h, w, ih, iv, n); + } else if (n <= m->nmaster + (m->nstack ? m->nstack : 1)) { + layout_split_horizontal(m, x, y, h, w, ih, iv, n); + } else { + layout_split_centered_horizontal_fixed(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_split_centered_horizontal_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int sh, sy, oy, sc; + + if (m->nstack) + sc = m->nstack; + else + sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); + + sh = (h - 2*ih) * (1 - m->mfact) / 2; + h = (h - 2*ih) * m->mfact; + if (m->ltaxis[LAYOUT] < 0) { // mirror + sy = y; + y += sh + ih; + oy = y + h + ih; + } else { + oy = y; + y += sh + ih; + sy = y + h + ih; + } + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, h, w, ih, iv, n, m->nmaster, 0); + (&flextiles[m->ltaxis[STACK]])->arrange(m, x, sy, sh, w, ih, iv, n, sc, m->nmaster); + (&flextiles[m->ltaxis[STACK2]])->arrange(m, x, oy, sh, w, ih, iv, n, n - m->nmaster - sc, m->nmaster + sc); +} + +static void +layout_floating_master(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + /* Split master into master + stack if we have enough clients */ + if (!m->nmaster || n <= m->nmaster) { + layout_no_split(m, x, y, h, w, ih, iv, n); + } else { + layout_floating_master_fixed(m, x, y, h, w, ih, iv, n); + } +} + +static void +layout_floating_master_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n) +{ + int mh, mw; + + /* Draw stack area first */ + (&flextiles[m->ltaxis[STACK]])->arrange(m, x, y, h, w, ih, iv, n, n - m->nmaster, m->nmaster); + + if (w > h) { + mw = w * m->mfact; + mh = h * 0.9; + } else { + mw = w * 0.9; + mh = h * m->mfact; + } + x += (w - mw) / 2; + y += (h - mh) / 2; + + (&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, mh, mw, ih, iv, n, m->nmaster, 0); +} + +static void +arrange_left_to_right(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int i; + float facts, fact = 1; + Client *c; + + w -= iv * (an - 1); + facts = getfactsforrange(m, an, ai); + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i >= ai && i < (ai + an)) { + #if CFACTS_PATCH + fact = c->cfact; + #endif // CFACTS_PATCH + resize(c, x, y, w * (fact / facts) - (2*c->bw), h - (2*c->bw), 0); + x += WIDTH(c) + iv; + } + } +} + +static void +arrange_top_to_bottom(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int i; + float facts, fact = 1; + Client *c; + + h -= ih * (an - 1); + facts = getfactsforrange(m, an, ai); + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i >= ai && i < (ai + an)) { + #if CFACTS_PATCH + fact = c->cfact; + #endif // CFACTS_PATCH + resize(c, x, y, w - (2*c->bw), h * (fact / facts) - (2*c->bw), 0); + y += HEIGHT(c) + ih; + } + } +} + +static void +arrange_monocle(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int i; + Client *c; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i >= ai && i < (ai + an)) + resize(c, x, y, w - (2*c->bw), h - (2*c->bw), 0); +} + +static void +arrange_gridmode(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int i, cols, rows, ch, cw, cx, cy; // counters + Client *c; + + /* grid dimensions */ + for (rows = 0; rows <= an/2; rows++) + if (rows*rows >= an) + break; + cols = (rows && (rows - 1) * rows >= an) ? rows - 1 : rows; + + /* window geoms (cell height/width) */ + ch = (h - ih * (rows - 1)) / (rows ? rows : 1); + cw = (w - iv * (cols - 1)) / (cols ? cols : 1); + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i >= ai && i < (ai + an)) { + cx = x + ((i - ai) / rows) * (cw + iv); + cy = y + ((i - ai) % rows) * (ch + ih); + resize(c, cx, cy, cw - 2*c->bw, ch - 2*c->bw, False); + } + } +} + +static void +arrange_horizgrid(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int ntop, nbottom, i; + Client *c; + + /* Exception when there is only one client; don't split into two rows */ + if (an == 1) { + arrange_monocle(m, x, y, h, w, ih, iv, n, an, ai); + return; + } + + ntop = an / 2; + nbottom = an - ntop; + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i >= ai && i < (ai + an)) { + if ((i - ai) < ntop) + resize( + c, + x + (i - ai) * ((w - iv*(ntop - 1)) / ntop + iv), + y, + (w - iv*(ntop - 1)) / ntop - (2*c->bw), + (h - ih) / 2 - (2*c->bw), + False + ); + else + resize( + c, + x + (i - ai - ntop) * ((w - iv*(nbottom - 1)) / nbottom + iv), + y + ih + (h - ih) / 2, + (w - iv*(nbottom - 1)) / nbottom - (2*c->bw), + (h - ih) / 2 - (2*c->bw), + False + ); + } + } +} + +static void +arrange_gapplessgrid(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + int i, cols, rows, cn, rn, cc; // counters + Client *c; + + /* grid dimensions */ + for (cols = 1; cols <= an/2; cols++) + if (cols*cols >= an) + break; + if (an == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ + cols = 2; + rows = an/cols; + cn = rn = cc = 0; // reset cell no, row no, client count + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i >= ai && i < (ai + an)) { + if (cc/rows + 1 > cols - an%cols) + rows = an/cols + 1; + resize(c, + x + cn*((w - iv*(cols - 1)) / cols + iv), + y + rn*((h - ih*(rows - 1)) / rows + ih), + (w - iv*(cols - 1)) / cols, + (h - ih*(rows - 1)) / rows, + 0); + rn++; + cc++; + if (rn >= rows) { + rn = 0; + cn++; + } + } + } +} + +static void +arrange_fibonacci(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai, int s) +{ + int i, j, nx = x, ny = y, nw = w, nh = h, r = 1; + Client *c; + + for (i = 0, j = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), j++) { + if (j >= ai && j < (ai + an)) { + if (r) { + if ((i % 2 && ((nh - ih) / 2) <= (20 + 2*c->bw)) || (!(i % 2) && ((nw - iv) / 2) <= (20 + 2*c->bw))) { + r = 0; + } + if (r && i < an - 1) { + if (i % 2) + nh = (nh - ih) / 2; + else + nw = (nw - iv) / 2; + + if ((i % 4) == 2 && !s) + nx += nw + iv; + else if ((i % 4) == 3 && !s) + ny += nh + ih; + } + if ((i % 4) == 0) { + if (s) + ny += nh + ih; + else + ny -= nh + ih; + } + else if ((i % 4) == 1) + nx += nw + iv; + else if ((i % 4) == 2) + ny += nh + ih; + else if ((i % 4) == 3) { + if (s) + nx += nw + iv; + else + nx -= nw + iv; + } + if (i == 0) { + if (an != 1) + nw = (w - iv) * m->mfact; + ny = y; + } + else if (i == 1) + nw = w - nw - iv; + i++; + } + resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False); + } + } +} + +static void +arrange_dwindle(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + arrange_fibonacci(m, x, y, h, w, ih, iv, n, an, ai, 1); +} + +static void +arrange_spiral(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, int an, int ai) +{ + arrange_fibonacci(m, x, y, h, w, ih, iv, n, an, ai, 0); +} + +static void +flextile(Monitor *m) +{ + unsigned int n; + int oh = 0, ov = 0, ih = 0, iv = 0; // gaps outer/inner horizontal/vertical + + #if VANITYGAPS_PATCH + getgaps(m, &oh, &ov, &ih, &iv, &n); + #else + Client *c; + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + #endif // VANITYGAPS_PATCH + + if (m->lt[m->sellt]->preset.layout != m->ltaxis[LAYOUT] || + m->lt[m->sellt]->preset.masteraxis != m->ltaxis[MASTER] || + m->lt[m->sellt]->preset.stack1axis != m->ltaxis[STACK] || + m->lt[m->sellt]->preset.stack2axis != m->ltaxis[STACK2]) + setflexsymbols(m, n); + else if (m->lt[m->sellt]->preset.symbolfunc != NULL) + m->lt[m->sellt]->preset.symbolfunc(m, n); + + if (n == 0) + return; + + #if VANITYGAPS_PATCH + /* No outer gap if full screen monocle */ + if (abs(m->ltaxis[MASTER]) == MONOCLE && (abs(m->ltaxis[LAYOUT]) == NO_SPLIT || n <= m->nmaster)) { + oh = 0; + ov = 0; + } + #endif // VANITYGAPS_PATCH + + (&flexlayouts[abs(m->ltaxis[LAYOUT])])->arrange(m, m->wx + ov, m->wy + oh, m->wh - 2*oh, m->ww - 2*ov, ih, iv, n); + return; +} + +static void +setflexsymbols(Monitor *m, unsigned int n) +{ + int l; + char sym1, sym2, sym3; + Client *c; + + if (n == 0) + for (c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + + l = abs(m->ltaxis[LAYOUT]); + if (m->ltaxis[MASTER] == MONOCLE && (l == NO_SPLIT || !m->nmaster || n <= m->nmaster)) { + monoclesymbols(m, n); + return; + } + + if (m->ltaxis[STACK] == MONOCLE && (l == SPLIT_VERTICAL || l == SPLIT_HORIZONTAL_FIXED)) { + decksymbols(m, n); + return; + } + + /* Layout symbols */ + if (l == NO_SPLIT || !m->nmaster) { + sym1 = sym2 = sym3 = (int)tilesymb[m->ltaxis[MASTER]]; + } else { + sym2 = layoutsymb[l]; + if (m->ltaxis[LAYOUT] < 0) { + sym1 = tilesymb[m->ltaxis[STACK]]; + sym3 = tilesymb[m->ltaxis[MASTER]]; + } else { + sym1 = tilesymb[m->ltaxis[MASTER]]; + sym3 = tilesymb[m->ltaxis[STACK]]; + } + } + + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); +} + +static void +monoclesymbols(Monitor *m, unsigned int n) +{ + if (n > 0) + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + else + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[M]"); +} + +static void +decksymbols(Monitor *m, unsigned int n) +{ + if (n > m->nmaster) + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[]%d", n); + else + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[D]"); +} + +/* Mirror layout axis for flextile */ +void +mirrorlayout(const Arg *arg) +{ + if (!selmon->lt[selmon->sellt]->arrange) + return; + selmon->ltaxis[LAYOUT] *= -1; + #if PERTAG_PATCH + selmon->pertag->ltaxis[selmon->pertag->curtag][0] = selmon->ltaxis[LAYOUT]; + #endif // PERTAG_PATCH + arrange(selmon); +} + +/* Rotate layout axis for flextile */ +void +rotatelayoutaxis(const Arg *arg) +{ + if (!selmon->lt[selmon->sellt]->arrange) + return; + if (arg->i == 0) { + if (selmon->ltaxis[LAYOUT] >= 0) + selmon->ltaxis[LAYOUT] = selmon->ltaxis[LAYOUT] + 1 >= LAYOUT_LAST ? 0 : selmon->ltaxis[LAYOUT] + 1; + else + selmon->ltaxis[LAYOUT] = selmon->ltaxis[LAYOUT] - 1 <= -LAYOUT_LAST ? -0 : selmon->ltaxis[LAYOUT] - 1; + } else + selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 >= AXIS_LAST ? 0 : selmon->ltaxis[arg->i] + 1; + #if PERTAG_PATCH + selmon->pertag->ltaxis[selmon->pertag->curtag][arg->i] = selmon->ltaxis[arg->i]; + #endif // PERTAG_PATCH + arrange(selmon); + setflexsymbols(selmon, 0); +} + +void +incnstack(const Arg *arg) +{ + #if PERTAG_PATCH + selmon->nstack = selmon->pertag->nstacks[selmon->pertag->curtag] = MAX(selmon->nstack + arg->i, 0); + #else + selmon->nstack = MAX(selmon->nstack + arg->i, 0); + #endif // PERTAG_PATCH + arrange(selmon); +} \ No newline at end of file diff --git a/patch/flextile-deluxe.h b/patch/flextile-deluxe.h new file mode 100644 index 0000000..919ac3c --- /dev/null +++ b/patch/flextile-deluxe.h @@ -0,0 +1,107 @@ +static void flextile(Monitor *m); +static void mirrorlayout(const Arg *arg); +static void rotatelayoutaxis(const Arg *arg); +static void incnstack(const Arg *arg); + +/* Symbol handlers */ +static void setflexsymbols(Monitor *m, unsigned int n); +static void monoclesymbols(Monitor *m, unsigned int n); +static void decksymbols(Monitor *m, unsigned int n); + +/* Layout split */ +static void layout_no_split(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_vertical(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_horizontal(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_vertical_dual_stack(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_horizontal_dual_stack(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_centered_vertical(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_centered_horizontal(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_floating_master(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_vertical_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_horizontal_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_vertical_dual_stack_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_horizontal_dual_stack_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_centered_vertical_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_split_centered_horizontal_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); +static void layout_floating_master_fixed(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n); + +/* Layout tile arrangements */ +static void arrange_left_to_right(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_top_to_bottom(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_monocle(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_gapplessgrid(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_gridmode(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_horizgrid(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_dwindle(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); +static void arrange_spiral(Monitor *m, int ax, int ay, int ah, int aw, int ih, int iv, int n, int an, int ai); + +/* Named flextile constants */ +enum { + LAYOUT, // controls overall layout arrangement / split + MASTER, // indicates the tile arrangement for the master area + STACK, // indicates the tile arrangement for the stack area + STACK2, // indicates the tile arrangement for the secondary stack area + LTAXIS_LAST, +}; + +/* Layout arrangements */ +enum { + NO_SPLIT, + SPLIT_VERTICAL, // master stack vertical split + SPLIT_HORIZONTAL, // master stack horizontal split + SPLIT_CENTERED_VERTICAL, // centered master vertical split + SPLIT_CENTERED_HORIZONTAL, // centered master horizontal split + SPLIT_VERTICAL_DUAL_STACK, // master stack vertical split with dual stack + SPLIT_HORIZONTAL_DUAL_STACK, // master stack vertical split with dual stack + FLOATING_MASTER, // (fake) floating master + SPLIT_VERTICAL_FIXED, // master stack vertical fixed split + SPLIT_HORIZONTAL_FIXED, // master stack horizontal fixed split + SPLIT_CENTERED_VERTICAL_FIXED, // centered master vertical fixed split + SPLIT_CENTERED_HORIZONTAL_FIXED, // centered master horizontal fixed split + SPLIT_VERTICAL_DUAL_STACK_FIXED, // master stack vertical split with fixed dual stack + SPLIT_HORIZONTAL_DUAL_STACK_FIXED, // master stack vertical split with fixed dual stack + FLOATING_MASTER_FIXED, // (fake) fixed floating master + LAYOUT_LAST, +}; + +static char layoutsymb[] = { + 32, // " ", + 124, // "|", + 61, // "=", + 94, // "^", + 126, // "~", + 58, // ":", + 59, // ";", + 43, // "+", + 124, // "¦", + 61, // "=", + 94, // "^", + 126, // "~", + 58, // ":", + 59, // ";", + 43, // "+", +}; + +/* Tile arrangements */ +enum { + TOP_TO_BOTTOM, // clients are stacked vertically + LEFT_TO_RIGHT, // clients are stacked horizontally + MONOCLE, // clients are stacked in deck / monocle mode + GAPPLESSGRID, // clients are stacked in a gappless grid + GRIDMODE, // clients are stacked in a grid + HORIZGRID, // clients are stacked in a grid + DWINDLE, // clients are stacked in fibonacci dwindle mode + SPIRAL, // clients are stacked in fibonacci spiral mode + AXIS_LAST, +}; + +static char tilesymb[] = { + 61, // "=", + 124, // "|", + 68, // "D", + 35, // "#", + 35, // "#", + 35, // "#", + 92, // "\\", + 64, // "@", +}; \ No newline at end of file diff --git a/patch/flextile.c b/patch/flextile.c deleted file mode 100644 index 695b312..0000000 --- a/patch/flextile.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Set predefined flextile layout. - * - * The arg int value is a binary representation of the setup where certain bits have different - * meanings, similar to how Linux permissions work. - * - * The first two bits represents the stack axis, bits 3 and 4 the master axis. Bits 5 and 6 - * are used to control the layout while bit 7 indicates whether or not the layout is mirrored. - * The 8th bit is reserved while bit 9 through 12 control nmaster with up to 15 clients in the - * master stack. - * - * Bitwise layout: - * - * 0000 (nmaster: 0-15 = clients in master stack) - * 0 (reserved) - * 0 (orientation: 0 = normal, 1 = mirror) - * 00 (layout: 00 = vertical, 01 = horizontal, 10 = centered (vert), 11 = centered (horz)) - * 00 (master axis: 00 = left to right, 01 = top to bottom, 10 = monocle, 11 = grid) - * 00 (stack axis: 00 = left to right, 01 = top to bottom, 10 = monocle, 11 = grid) - * - * Examples: - * binary int layout - * -------------------------- - * 000000000110 6 monocle - * 000100000110 262 deck layout - * 000100010000 272 bstack layout - * 000100010001 273 bstackhoriz layout - * 000000000111 7 grid layout - * 000100000101 261 default tile layout - * 000100100101 293 centered master - * 000100000111 263 default tile layout with grid stack - * 000100000001 257 columns (col) layout - */ -void -setflexlayout(const Arg *arg) -{ - int i; - - /* Find flextile layout */ - for (i = 0; i < LENGTH(layouts); i++) - if (layouts[i].arrange == flextile) - break; - - selmon->nmaster = ((arg->i & 0x0F00) >> 8); - selmon->ltaxis[0] = (1 + ((arg->i & 0x30) >> 4)) * (arg->i & 0x40 ? -1 : 1); - selmon->ltaxis[1] = 1 + ((arg->i & 0xC) >> 2); - selmon->ltaxis[2] = 1 + (arg->i & 0x3); - - #if PERTAG_PATCH - selmon->pertag->nmasters[selmon->pertag->curtag] = selmon->nmaster; - selmon->pertag->ltaxes[selmon->pertag->curtag][0] = selmon->ltaxis[0]; - selmon->pertag->ltaxes[selmon->pertag->curtag][1] = selmon->ltaxis[1]; - selmon->pertag->ltaxes[selmon->pertag->curtag][2] = selmon->ltaxis[2]; - #endif - - setlayout(&((Arg) { .v = &layouts[i] })); -} - -#if VANITYGAPS_PATCH -static void -flextile(Monitor *m) -{ - unsigned int i, n, nc = 0, sc = 0, lt, cn = 0, rn = 0, cc = 0; // counters - int cols = 1, rows = 1; - int x, y, h, w; // master x, y, height, width - int sx, sy, sh, sw; // stack x, y, height, width - int ox, oy; // other stack x, y (centered layout) - int oh, ov, ih, iv; // gaps outer/inner horizontal/vertical - - float facts, sfacts, ofacts; - Client *c; - - getgaps(m, &oh, &ov, &ih, &iv, &n); - setflexsymbols(m, n); - - if (n == 0) - return; - - /* No outer gap if full screen monocle */ - if ((!m->nmaster && m->ltaxis[STACK] == MONOCLE) || (n <= m->nmaster && m->ltaxis[MASTER] == MONOCLE)) { - ox = sx = x = m->wx; - oy = sy = y = m->wy; - sh = h = m->wh; - sw = w = m->ww; - } else { - ox = sx = x = m->wx + ov; - oy = sy = y = m->wy + oh; - sh = h = m->wh - 2*oh; - sw = w = m->ww - 2*ov; - } - sc = n - m->nmaster; - - #if CFACTS_PATCH - getfacts(m, &facts, &sfacts); - ofacts = sfacts; - #else - facts = MIN(n, m->nmaster); - ofacts = sfacts = sc; - #endif // CFACTS_PATCH - - /* Split master into master + stack if we have enough clients */ - if (m->nmaster && n > m->nmaster) { - if (abs(m->ltaxis[LAYOUT]) == SPLIT_VERTICAL - || (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V && n == m->nmaster + 1)) { - sw = (w - iv) * (1 - m->mfact); - w = (w - iv) * m->mfact; - if (m->ltaxis[LAYOUT] < 0) // mirror - x = sx + sw + iv; - else - sx = x + w + iv; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_HORIZONTAL - || (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H && n == m->nmaster + 1)) { - sh = (h - ih) * (1 - m->mfact); - h = (h - ih) * m->mfact; - if (m->ltaxis[LAYOUT] < 0) // mirror - y = sy + sh + ih; - else - sy = y + h + ih; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V) { - sw = (w - 2*iv) * (1 - m->mfact) / 2; - w = (w - 2*iv) * m->mfact; - x = sx + sw + iv; - if (m->ltaxis[LAYOUT] < 0) // mirror - ox = x + w + iv; - else - sx = x + w + iv; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H) { - sh = (h - 2*ih) * (1 - m->mfact) / 2; - h = (h - 2*ih) * m->mfact; - y = sy + sh + ih; - if (m->ltaxis[LAYOUT] < 0) // mirror - oy = y + h + ih; - else - sy = y + h + ih; - } - - if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V || abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H) { - sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); - facts = sfacts = ofacts = 0; - for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { - #if CFACTS_PATCH - if (i < m->nmaster) - facts += c->cfact; // total factor of master area - else if (sc && i < m->nmaster + sc) - sfacts += c->cfact; // total factor of first stack area - else - ofacts += c->cfact; // total factor of second stack area - #else - if (i < m->nmaster) - facts += 1; - else if (sc && i < m->nmaster + sc) - sfacts += 1; - else - ofacts += 1; - #endif // CFACTS_PATCH - } - } - } - - for (i = 0, lt = MASTER, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { - if (i == 0 || (m->nmaster && i == m->nmaster) || i == (m->nmaster + sc)) { - nc = MIN(n, m->nmaster); - if (!m->nmaster || i == m->nmaster) { // switch to stack area - x = sx, y = sy, h = sh, w = sw, facts = sfacts, lt = STACK; - nc = sc; - } else if (i > 0 && i == (m->nmaster + sc)) { // switch to second stack area - x = ox, y = oy, h = sh, w = sw, nc = n - i, facts = ofacts; - } - - if (m->ltaxis[lt] == LEFT_TO_RIGHT) - w -= iv * (nc - 1); - else if (m->ltaxis[lt] == TOP_TO_BOTTOM) - h -= ih * (nc - 1); - else if (m->ltaxis[lt] == GRID) { - /* grid dimensions */ - for (cols = 1; cols <= nc/2; cols++) - if (cols*cols >= nc) - break; - if (nc == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ - cols = 2; - rows = nc/cols; - cn = rn = cc = 0; // reset cell no, row no, client count - } - } - - if (m->ltaxis[lt] == LEFT_TO_RIGHT) { - #if CFACTS_PATCH - resize(c, x, y, w * (c->cfact / facts) - (2*c->bw), h - (2*c->bw), 0); - #else - resize(c, x, y, w / facts - (2*c->bw), h - (2*c->bw), 0); - #endif // CFACTS_PATCH - x = x + WIDTH(c) + iv; - } else if (m->ltaxis[lt] == TOP_TO_BOTTOM) { - #if CFACTS_PATCH - resize(c, x, y, w - (2*c->bw), h * (c->cfact / facts) - (2*c->bw), 0); - #else - resize(c, x, y, w - (2*c->bw), h / facts - (2*c->bw), 0); - #endif // CFACTS_PATCH - y = y + HEIGHT(c) + ih; - } else if (m->ltaxis[lt] == MONOCLE) { - resize(c, x, y, w - (2*c->bw), h - (2*c->bw), 0); - } else if (m->ltaxis[lt] == GRID) { - if (cc/rows + 1 > cols - nc%cols) - rows = nc/cols + 1; - resize(c, - x + cn*((w - iv*(cols - 1)) / cols + iv), - y + rn*((h - ih*(rows - 1)) / rows + ih), - (w - iv*(cols - 1)) / cols, - (h - ih*(rows - 1)) / rows, - 0); - rn++; - cc++; - if (rn >= rows) { - rn = 0; - cn++; - } - } - } -} -#else -static void -flextile(Monitor *m) -{ - unsigned int i, n, nc = 0, sc = 0, lt, cn = 0, rn = 0, cc = 0; // counters - int cols = 1, rows = 1; - int x, y, h, w; // master x, y, height, width - int sx, sy, sh, sw; // stack x, y, height, width - int ox, oy; // other stack x, y (centered layout) - - float facts, sfacts, ofacts; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - setflexsymbols(m, n); - if (n == 0) - return; - - ox = sx = x = m->wx; - oy = sy = y = m->wy; - sh = h = m->wh; - sw = w = m->ww; - sc = n - m->nmaster; - - #if CFACTS_PATCH - getfacts(m, &facts, &sfacts); - ofacts = sfacts; - #else - facts = MIN(n, m->nmaster); - ofacts = sfacts = sc; - #endif // CFACTS_PATCH - - /* Split master into master + stack if we have enough clients */ - if (m->nmaster && n > m->nmaster) { - if (abs(m->ltaxis[LAYOUT]) == SPLIT_VERTICAL - || (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V && n == m->nmaster + 1)) { - sw = w * (1 - m->mfact); - w = w * m->mfact; - if (m->ltaxis[LAYOUT] < 0) // mirror - x = sx + sw; - else - sx = x + w; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_HORIZONTAL - || (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H && n == m->nmaster + 1)) { - sh = h * (1 - m->mfact); - h = h * m->mfact; - if (m->ltaxis[LAYOUT] < 0) // mirror - y = sy + sh; - else - sy = y + h; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V) { - sw = w * (1 - m->mfact) / 2; - w = w * m->mfact; - x = sx + sw; - if (m->ltaxis[LAYOUT] < 0) // mirror - ox = x + w; - else - sx = x + w; - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H) { - sh = h * (1 - m->mfact) / 2; - h = h * m->mfact; - y = sy + sh; - if (m->ltaxis[LAYOUT] < 0) // mirror - oy = y + h; - else - sy = y + h; - } - - if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V || abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H) { - sc = (n - m->nmaster) / 2 + ((n - m->nmaster) % 2 > 0 ? 1 : 0); - facts = sfacts = ofacts = 0; - for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { - #if CFACTS_PATCH - if (i < m->nmaster) - facts += c->cfact; // total factor of master area - else if (sc && i < m->nmaster + sc) - sfacts += c->cfact; // total factor of first stack area - else - ofacts += c->cfact; // total factor of second stack area - #else - if (i < m->nmaster) - facts += 1; - else if (sc && i < m->nmaster + sc) - sfacts += 1; - else - ofacts += 1; - #endif // CFACTS_PATCH - } - } - } - - for (i = 0, lt = MASTER, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { - if (i == 0 || (m->nmaster && i == m->nmaster) || i == (m->nmaster + sc)) { - nc = MIN(n, m->nmaster); - if (!m->nmaster || i == m->nmaster) { // switch to stack area - x = sx, y = sy, h = sh, w = sw, facts = sfacts, lt = STACK; - nc = sc; - } else if (i > 0 && i == (m->nmaster + sc)) { // switch to second stack area - x = ox, y = oy, h = sh, w = sw, nc = n - i, facts = ofacts; - } - - if (m->ltaxis[lt] == GRID) { - /* grid dimensions */ - for (cols = 1; cols <= nc/2; cols++) - if (cols*cols >= nc) - break; - if (nc == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ - cols = 2; - rows = nc/cols; - cn = rn = cc = 0; // reset cell no, row no, client count - } - } - - if (m->ltaxis[lt] == LEFT_TO_RIGHT) { - #if CFACTS_PATCH - resize(c, x, y, w * (c->cfact / facts) - (2*c->bw), h - (2*c->bw), 0); - #else - resize(c, x, y, w / facts - (2*c->bw), h - (2*c->bw), 0); - #endif // CFACTS_PATCH - x = x + WIDTH(c); - } else if (m->ltaxis[lt] == TOP_TO_BOTTOM) { - #if CFACTS_PATCH - resize(c, x, y, w - (2*c->bw), h * (c->cfact / facts) - (2*c->bw), 0); - #else - resize(c, x, y, w - (2*c->bw), h / facts - (2*c->bw), 0); - #endif // CFACTS_PATCH - y = y + HEIGHT(c); - } else if (m->ltaxis[lt] == MONOCLE) { - resize(c, x, y, w - (2*c->bw), h - (2*c->bw), 0); - } else if (m->ltaxis[lt] == GRID) { - if (cc/rows + 1 > cols - nc%cols) - rows = nc/cols + 1; - resize(c, - x + cn * (w / cols), - y + rn * (h / rows), - w / cols, - h / rows, - 0); - rn++; - cc++; - if (rn >= rows) { - rn = 0; - cn++; - } - } - } -} -#endif - - -static void -setflexsymbols(Monitor *m, unsigned int n) -{ - char sym1 = 61, sym2 = 93, sym3 = 61, sym = 0; - - /* Predefined layouts */ - /* bstack */ - if (abs(m->ltaxis[LAYOUT]) == SPLIT_HORIZONTAL && m->ltaxis[MASTER] == LEFT_TO_RIGHT && m->ltaxis[STACK] == LEFT_TO_RIGHT) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, (m->ltaxis[LAYOUT] < 0 ? "⚍⚍⚍" : "⚎⚎⚎")); - return; - } - - /* bstackhoriz */ - if (abs(m->ltaxis[LAYOUT]) == SPLIT_HORIZONTAL && m->ltaxis[MASTER] == LEFT_TO_RIGHT && m->ltaxis[STACK] == TOP_TO_BOTTOM) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, (m->ltaxis[LAYOUT] < 0 ? "☳☳☳" : "☶☶☶")); - return; - } - - /* centered master horizontal split */ - if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H && m->ltaxis[MASTER] == TOP_TO_BOTTOM && m->ltaxis[STACK] == TOP_TO_BOTTOM) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "☰☰☰"); - return; - } - - if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H && m->ltaxis[MASTER] == LEFT_TO_RIGHT && m->ltaxis[STACK] == LEFT_TO_RIGHT) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "☵☵☵"); - return; - } - - /* monocle */ - if (n <= 1 && ((!m->nmaster && m->ltaxis[STACK] == MONOCLE) || (n <= m->nmaster && m->ltaxis[MASTER] == MONOCLE))) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[M]"); - return; - } - - /* Layout symbols */ - if (abs(m->ltaxis[LAYOUT]) == SPLIT_VERTICAL) { - if (m->nmaster > 1 || m->ltaxis[MASTER] == MONOCLE) - sym2 = 124; // | - else if (m->ltaxis[LAYOUT] < 0) - sym2 = 91; // [ - else - sym2 = 93; // ] - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_HORIZONTAL) { - if (m->nmaster > 1 || m->ltaxis[MASTER] == MONOCLE) - sym2 = 58; // : - else if (m->ltaxis[LAYOUT] < 0) - sym2 = 91; // [ - else - sym2 = 93; // ] - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_V) { - if (m->ltaxis[LAYOUT] < 0) - sym2 = 87; // W - else - sym2 = 77; // M - } else if (abs(m->ltaxis[LAYOUT]) == SPLIT_CENTERED_H) { - if (m->ltaxis[LAYOUT] < 0) - sym2 = 87; // W - else - sym2 = 77; // M - } - - if (m->ltaxis[MASTER] == LEFT_TO_RIGHT) - sym1 = 124; // | ⏸ - else if (m->ltaxis[MASTER] == TOP_TO_BOTTOM) - sym1 = 61; // = - else if (m->ltaxis[MASTER] == MONOCLE) - sym1 = MIN(n, m->nmaster); - else if (m->ltaxis[MASTER] == GRID) - sym1 = 35; // # - - if (m->ltaxis[STACK] == LEFT_TO_RIGHT) - sym3 = 124; // | - else if (m->ltaxis[STACK] == TOP_TO_BOTTOM) - sym3 = 61; // = - else if (m->ltaxis[STACK] == MONOCLE) - sym3 = n - m->nmaster; - else if (m->ltaxis[STACK] == GRID) - sym3 = 35; // # - - - /* Generic symbols */ - if (!m->nmaster) { - if (m->ltaxis[STACK] == MONOCLE) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%d%c", 91, sym3, 93); - } else { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym3, sym3, sym3); - } - return; - } - - if (n <= m->nmaster) { - if (m->ltaxis[MASTER] == MONOCLE) { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%d%c", 91, sym1, 93); - } else { - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", 91, sym1, 93); - } - } else { - if (m->ltaxis[LAYOUT] < 0) { - sym = sym1; - sym1 = sym3; - sym3 = sym; - } - if (m->nmaster == 1 && abs(m->ltaxis[LAYOUT]) <= SPLIT_HORIZONTAL && m->ltaxis[MASTER] != MONOCLE) { - if (m->ltaxis[LAYOUT] > 0) - sym1 = 91; - else - sym3 = 93; - } - if (m->ltaxis[MASTER] == MONOCLE && m->ltaxis[STACK] == MONOCLE) - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3); - else if ((m->nmaster && m->ltaxis[MASTER] == MONOCLE && m->ltaxis[LAYOUT] > 0) || (m->ltaxis[STACK] == MONOCLE && m->ltaxis[LAYOUT] < 0)) - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3); - else if ((m->ltaxis[STACK] == MONOCLE && m->ltaxis[LAYOUT] > 0) || (m->nmaster && m->ltaxis[MASTER] == MONOCLE && m->ltaxis[LAYOUT] < 0)) - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, n - m->nmaster); - else - snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); - } -} - -/* Mirror layout axis for flextile */ -void -mirrorlayout(const Arg *arg) -{ - if (!selmon->lt[selmon->sellt]->arrange) - return; - selmon->ltaxis[0] *= -1; - #if PERTAG_PATCH - selmon->pertag->ltaxes[selmon->pertag->curtag][0] = selmon->ltaxis[0]; - #endif // PERTAG_PATCH - arrange(selmon); -} - -/* Rotate layout axis for flextile */ -void -rotatelayoutaxis(const Arg *arg) -{ - if (!selmon->lt[selmon->sellt]->arrange) - return; - if (arg->i == 0) { - if (selmon->ltaxis[0] > 0) - selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 4 ? 1 : selmon->ltaxis[0] + 1; - else - selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -4 ? -1 : selmon->ltaxis[0] - 1; - } else - selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 4 ? 1 : selmon->ltaxis[arg->i] + 1; - #if PERTAG_PATCH - selmon->pertag->ltaxes[selmon->pertag->curtag][arg->i] = selmon->ltaxis[arg->i]; - #endif // PERTAG_PATCH - arrange(selmon); -} \ No newline at end of file diff --git a/patch/flextile.h b/patch/flextile.h deleted file mode 100644 index 86ef620..0000000 --- a/patch/flextile.h +++ /dev/null @@ -1,18 +0,0 @@ -static void flextile(Monitor *m); -static void mirrorlayout(const Arg *arg); -static void rotatelayoutaxis(const Arg *arg); -static void setflexlayout(const Arg *arg); -static void setflexsymbols(Monitor *m, unsigned int n); - -/* Named flextile constants */ -#define LAYOUT 0 -#define MASTER 1 -#define STACK 2 -#define SPLIT_VERTICAL 1 // master stack vertical split -#define SPLIT_HORIZONTAL 2 // master stack horizontal split -#define SPLIT_CENTERED_V 3 // centered master vertical split -#define SPLIT_CENTERED_H 4 // centered master horizontal split -#define LEFT_TO_RIGHT 1 // clients are stacked horizontally -#define TOP_TO_BOTTOM 2 // clients are stacked vertically -#define MONOCLE 3 // clients are stacked in deck / monocle mode -#define GRID 4 // clients are stacked in grid mode \ No newline at end of file diff --git a/patch/include.c b/patch/include.c index bae6733..9fd267f 100644 --- a/patch/include.c +++ b/patch/include.c @@ -124,8 +124,8 @@ #include "fibonacci.c" #endif -#if FLEXTILE_LAYOUT -#include "flextile.c" +#if FLEXTILE_DELUXE_LAYOUT +#include "flextile-deluxe.c" #endif #if GAPPLESSGRID_LAYOUT diff --git a/patch/include.h b/patch/include.h index cf4b9a4..cc6ac94 100644 --- a/patch/include.h +++ b/patch/include.h @@ -36,6 +36,10 @@ #include "ewmhtags.h" #endif +#if PERTAG_PATCH +#include "pertag.h" +#endif + #if PUSH_NO_MASTER_PATCH #include "push_no_master.h" #elif PUSH_PATCH @@ -120,8 +124,8 @@ #include "fibonacci.h" #endif -#if FLEXTILE_LAYOUT -#include "flextile.h" +#if FLEXTILE_DELUXE_LAYOUT +#include "flextile-deluxe.h" #endif #if GAPPLESSGRID_LAYOUT diff --git a/patch/pertag.c b/patch/pertag.c index 730a0d1..708943d 100644 --- a/patch/pertag.c +++ b/patch/pertag.c @@ -1,16 +1,61 @@ struct Pertag { unsigned int curtag, prevtag; /* current and previous tag */ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ - #if FLEXTILE_LAYOUT - int ltaxes[LENGTH(tags) + 1][3]; - #endif // FLEXTILE_LAYOUT + #if FLEXTILE_DELUXE_LAYOUT + int nstacks[LENGTH(tags) + 1]; /* number of windows in primary stack area */ + int ltaxis[LENGTH(tags) + 1][LTAXIS_LAST]; + const Layout *ltidxs[LENGTH(tags) + 1][3]; /* matrix of tags and layouts indexes */ + #else + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ + #endif // FLEXTILE_DELUXE_LAYOUT float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ - const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ #if PERTAGBAR_PATCH Bool showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ #endif // PERTAGBAR_PATCH #if ZOOMSWAP_PATCH Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ #endif // ZOOMSWAP_PATCH -}; \ No newline at end of file +}; + +void +pertagview(const Arg *arg) +{ + int i; + unsigned int tmptag; + + if (arg->ui & TAGMASK) { + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + if (arg->ui == ~0) + selmon->pertag->curtag = 0; + else { + for (i=0; !(arg->ui & 1 << i); i++) ; + selmon->pertag->curtag = i + 1; + } + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; + #if FLEXTILE_DELUXE_LAYOUT + selmon->nstack = selmon->pertag->nstacks[selmon->pertag->curtag]; + #endif // FLEXTILE_DELUXE_LAYOUT + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + #if FLEXTILE_DELUXE_LAYOUT && MONITOR_RULES_PATCH + selmon->ltaxis[LAYOUT] = selmon->pertag->ltaxis[selmon->pertag->curtag][LAYOUT]; + selmon->ltaxis[MASTER] = selmon->pertag->ltaxis[selmon->pertag->curtag][MASTER]; + selmon->ltaxis[STACK] = selmon->pertag->ltaxis[selmon->pertag->curtag][STACK]; + selmon->ltaxis[STACK2] = selmon->pertag->ltaxis[selmon->pertag->curtag][STACK2]; + #endif // FLEXTILE_DELUXE_LAYOUT && MONITOR_RULES_PATCH + #if PERTAGBAR_PATCH + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) + togglebar(NULL); + #endif // PERTAGBAR_PATCH + // strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); // ?? + // strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); +} \ No newline at end of file diff --git a/patch/pertag.h b/patch/pertag.h new file mode 100644 index 0000000..ac5288d --- /dev/null +++ b/patch/pertag.h @@ -0,0 +1 @@ +static void pertagview(const Arg *arg); \ No newline at end of file diff --git a/patches.h b/patches.h index 4bef728..7c83d28 100644 --- a/patches.h +++ b/patches.h @@ -355,10 +355,11 @@ */ #define FIBONACCI_SPIRAL_LAYOUT 0 -/* Flextile layout. - * https://dwm.suckless.org/patches/flextile/ +/* Flextile deluxe layout. + * A revamped, more flexible, and over-the-top version of the original flextile layout. + * https://dwm.suckless.org/patches/flextile/ (original) */ -#define FLEXTILE_LAYOUT 0 +#define FLEXTILE_DELUXE_LAYOUT 0 /* Gappless grid layout. * https://dwm.suckless.org/patches/gaplessgrid/