添加布局算法并在新建窗口时应用规则
This commit is contained in:
98
src/layout.c
Normal file
98
src/layout.c
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user