#include "layout.h" #include #include #include #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; } /** * @brief 设置全屏窗口的几何属性 */ void fullscreen_client(client_t *c) { if (c->floating) { c->old_x = c->x; c->old_y = c->y; c->old_width = c->width; c->old_height = c->height; } monitor_t *m = c->monitor; c->x = m->monitor_x; c->y = m->monitor_y; c->width = m->monitor_width; c->height = m->monitor_height; c->old_border_width = c->border_width; c->border_width = 0; } 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); } }