2019-09-30 21:52:51 +00:00
|
|
|
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 },
|
|
|
|
};
|
|
|
|
|
2020-03-20 14:20:07 +00:00
|
|
|
static void
|
|
|
|
getfactsforrange(Monitor *m, int an, int ai, int size, int *rest, float *fact)
|
2019-09-30 21:52:51 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
float facts;
|
|
|
|
Client *c;
|
2020-03-20 14:20:07 +00:00
|
|
|
int total = 0;
|
2019-09-30 21:52:51 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-03-20 14:20:07 +00:00
|
|
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
|
|
|
if (i >= ai && i < (ai + an))
|
|
|
|
#if CFACTS_PATCH
|
|
|
|
total += size * (c->cfact / facts);
|
|
|
|
#else
|
2020-03-21 13:23:27 +00:00
|
|
|
total += size / facts;
|
2020-03-20 14:20:07 +00:00
|
|
|
#endif // CFACTS_PATCH
|
|
|
|
|
|
|
|
*rest = size - total;
|
|
|
|
*fact = facts;
|
2019-09-30 21:52:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2020-03-20 14:20:07 +00:00
|
|
|
x = x + (w - mw) / 2;
|
|
|
|
y = y + (h - mh) / 2;
|
2019-09-30 21:52:51 +00:00
|
|
|
|
|
|
|
(&flextiles[m->ltaxis[MASTER]])->arrange(m, x, y, mh, mw, ih, iv, n, m->nmaster, 0);
|
2020-03-20 14:20:07 +00:00
|
|
|
reattachstack(m, m->nmaster, 0);
|
|
|
|
restack(m);
|
2019-09-30 21:52:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2020-03-20 14:20:07 +00:00
|
|
|
int i, rest;
|
2019-09-30 21:52:51 +00:00
|
|
|
float facts, fact = 1;
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
w -= iv * (an - 1);
|
2020-03-20 14:20:07 +00:00
|
|
|
getfactsforrange(m, an, ai, w, &rest, &facts);
|
2019-09-30 21:52:51 +00:00
|
|
|
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
|
2020-03-20 14:20:07 +00:00
|
|
|
resize(c, x, y, w * (fact / facts) + ((i - ai) < rest ? 1 : 0) - (2*c->bw), h - (2*c->bw), 0);
|
2019-09-30 21:52:51 +00:00
|
|
|
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)
|
|
|
|
{
|
2020-03-20 14:20:07 +00:00
|
|
|
int i, rest;
|
2019-09-30 21:52:51 +00:00
|
|
|
float facts, fact = 1;
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
h -= ih * (an - 1);
|
2020-03-20 14:20:07 +00:00
|
|
|
getfactsforrange(m, an, ai, h, &rest, &facts);
|
2019-09-30 21:52:51 +00:00
|
|
|
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
|
2020-03-20 14:20:07 +00:00
|
|
|
resize(c, x, y, w - (2*c->bw), h * (fact / facts) + ((i - ai) < rest ? 1 : 0) - (2*c->bw), 0);
|
2019-09-30 21:52:51 +00:00
|
|
|
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;
|
|
|
|
|
2020-03-07 16:03:19 +00:00
|
|
|
#if VANITYGAPS_PATCH && !VANITYGAPS_MONOCLE_PATCH
|
2019-09-30 21:52:51 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
2020-03-07 16:03:19 +00:00
|
|
|
#endif // VANITYGAPS_PATCH && !VANITYGAPS_MONOCLE_PATCH
|
2019-09-30 21:52:51 +00:00
|
|
|
|
|
|
|
(&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);
|
2020-03-20 14:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
reattachstack(Monitor *m, int an, int ai)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
|
|
|
if (i >= ai && i < (ai + an)) {
|
|
|
|
detachstack(c);
|
|
|
|
attachstack(c);
|
|
|
|
}
|
|
|
|
}
|