99 lines
2.6 KiB
C
99 lines
2.6 KiB
C
#include "layout.h"
|
|
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
|
|
#include "types.h"
|
|
|
|
client_t *next_visible_client(client_t *c) {
|
|
while (c &&
|
|
(c->floating || c->fullscreen || c->maximize || !CLIENT_VISIBLE(c))) {
|
|
c = c->next;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
void maximize_client(client_t *c) {
|
|
monitor_t *m = c->monitor;
|
|
c->x = m->window_x;
|
|
c->y = m->window_y;
|
|
c->width = m->window_width - 2 * c->border_width;
|
|
c->height = m->window_height - 2 * c->border_width;
|
|
}
|
|
|
|
void fullscreen_client(client_t *c) {
|
|
monitor_t *m = c->monitor;
|
|
c->x = m->monitor_x;
|
|
c->y = m->monitor_y;
|
|
c->width = m->monitor_width - 2 * c->border_width;
|
|
c->height = m->monitor_height - 2 * c->border_width;
|
|
}
|
|
|
|
void monocle(monitor_t *monitor) {
|
|
client_t *c = next_visible_client(monitor->clients);
|
|
for (; c; c = next_visible_client(c->next)) maximize_client(c);
|
|
}
|
|
|
|
void tile(monitor_t *monitor) {
|
|
uint32_t n;
|
|
client_t *c = NULL;
|
|
for (n = 0, c = next_visible_client(monitor->clients); c;
|
|
c = next_visible_client(c->next), ++n);
|
|
|
|
if (n == 0) {
|
|
return;
|
|
}
|
|
|
|
uint32_t columns = (uint32_t)floor(sqrt(n));
|
|
if (columns * (columns + 1) <= n) {
|
|
columns++;
|
|
}
|
|
uint32_t rows_in_other_cols = n / columns;
|
|
uint32_t rows_in_main_col;
|
|
while ((rows_in_main_col = n - (columns - 1) * rows_in_other_cols) >
|
|
rows_in_other_cols) {
|
|
rows_in_other_cols++;
|
|
}
|
|
|
|
uint32_t width_avg = monitor->window_width / columns;
|
|
uint32_t width_for_main_col =
|
|
monitor->window_width - (columns - 1) * width_avg;
|
|
uint32_t width_for_other_cols = width_avg;
|
|
|
|
uint32_t i = 0, row = 0, col = 0, row_count, width, height;
|
|
int32_t y = monitor->window_y, x = monitor->window_x;
|
|
for (c = next_visible_client(monitor->clients); c;
|
|
c = next_visible_client(c->next), i++) {
|
|
if (i < rows_in_main_col) {
|
|
row = i;
|
|
width = width_for_main_col;
|
|
row_count = rows_in_main_col;
|
|
} else {
|
|
width = width_for_other_cols;
|
|
row_count = rows_in_other_cols;
|
|
if (((i - rows_in_main_col) % row_count) == 0) {
|
|
col++;
|
|
row = 0;
|
|
x += col == 1 ? width_for_main_col : width_for_other_cols;
|
|
y = monitor->window_y;
|
|
}
|
|
}
|
|
|
|
uint32_t h_avg = monitor->window_height / row_count;
|
|
uint32_t h_main = monitor->window_height - h_avg * (row_count - 1);
|
|
height = row == 0 ? h_main : h_avg;
|
|
c->x = x;
|
|
c->y = y;
|
|
c->width = width - 2 * c->border_width;
|
|
c->height = height - 2 * c->border_width;
|
|
y += height;
|
|
}
|
|
}
|
|
|
|
void calc_clients_geometry_of_monitor(monitor_t *monitor) {
|
|
if (monitor && monitor->layout && monitor->layout->arrange) {
|
|
monitor->layout->arrange(monitor);
|
|
}
|
|
}
|