添加布局算法并在新建窗口时应用规则

This commit is contained in:
2025-08-22 23:01:25 +08:00
parent c3bcb7ddd2
commit 69c69200d8
9 changed files with 248 additions and 19 deletions

98
src/layout.c Normal file
View File

@@ -0,0 +1,98 @@
#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;
c->height = m->window_height;
}
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;
c->height = m->monitor_height;
}
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);
}
}