swim.git
tile.c
/* swim - window manager
* Copyright (C) 2022-2023 ArcNyxx
* see LICENCE file for licensing information */
#include <stdbool.h>
#include <stdint.h>
#include <X11/Xlib.h>
#include "func.h"
#include "swim.h"
#include "tile.h"
#include "util.h"
#define GAPIH (mon->gap * 12)
#define GAPIV (mon->gap * 12)
#define GAPOH (mon->gap * 8)
#define GAPOV (mon->gap * 8)
static void move(cli_t *cli, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
static void
move(cli_t *cli, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
/* possible to loop through and hide remaining windows and skip extra
* computation but would add too much complexity for rare case */
if (y + h + 2 * BW > cli->mon->y + cli->mon->h) {
MOVE(cli->win, -2 * (cli->w + 2 * BW), cli->y);
} else if (x != cli->x || y != cli->y || w != cli->w || h != cli->h) {
cli->x = x, cli->y = y, cli->w = w, cli->h = h;
CSIZE(cli);
}
}
void
attach(cli_t *cli)
{
cli->next = cli->mon->cli, cli->mon->cli = cli;
}
void
detach(cli_t *cli)
{
cli_t **find;
for (find = &cli->mon->cli; *find != NULL && *find != cli;
find = &(*find)->next);
*find = cli->next;
}
cli_t *
next(cli_t *cli)
{
for (; cli != NULL && (cli->flt || cli->fsc || !VIS(cli));
cli = cli->next);
return cli;
}
void
tile(mon_t *mon)
{
int total = 0;
cli_t *cli = mon->cli;
for (; cli != NULL; total += (VIS(cli) && !cli->flt && !cli->fsc),
cli = cli->next)
MOVE(cli->win, VIS(cli) ?
cli->x : -2 * (cli->w + 2 * BW), cli->y);
int width = mon->w - 2 * GAPOH;
if (total > mon->nmaster) /* two columns */
width -= GAPIH, width = width * mon->mfact / 100;
int num = 0, space = 0;
for (cli = next(mon->cli); num < mon->nmaster && cli != NULL;
++num, cli = next(cli->next)) {
const int down = MIN(total, mon->nmaster) - num;
const int height = (mon->h - H * mon->show - space -
2 * GAPOV - GAPIV * (down - 1)) / down;
move(cli, mon->x + GAPOH, mon->y +
H * mon->show * mon->top + space + GAPOV,
width - 2 * BW, MAX(height - 2 * BW, H));
space += cli->h + 2 * BW + GAPIV;
}
space = 0;
for (; cli != NULL; ++num, cli = next(cli->next)) {
const int down = total - num;
const int height = (mon->h - H * mon->show - space -
2 * GAPOV - GAPIV * (down - 1)) / down;
move(cli, mon->x + GAPOH + width + GAPIH, mon->y +
H * mon->show * mon->top + space + GAPOV,
mon->w - width - 2 * BW - 2 * GAPOH -
GAPIH, MAX(height - 2 * BW, H));
space += cli->h + 2 * BW + GAPIV;
}
}