feat(layouts): 实现 fair/fullscreen/maximize 内置布局
This commit is contained in:
@@ -18,8 +18,9 @@ extern "C" {
|
||||
typedef struct zdwm_config_builder_t zdwm_config_builder_t;
|
||||
|
||||
typedef struct zdwm_builtin_layouts_t {
|
||||
zdwm_layout_fn tile;
|
||||
zdwm_layout_fn monocle;
|
||||
zdwm_layout_fn fair;
|
||||
zdwm_layout_fn fullscreen;
|
||||
zdwm_layout_fn maximize;
|
||||
} zdwm_builtin_layouts_t;
|
||||
|
||||
typedef struct zdwm_api_t {
|
||||
|
||||
@@ -14,6 +14,7 @@ extern "C" {
|
||||
typedef struct zdwm_layout_ctx_t {
|
||||
zdwm_workspace_id_t workspace_id;
|
||||
zdwm_window_id_t focused_window_id;
|
||||
zdwm_rect_t output_geometry;
|
||||
zdwm_rect_t workarea;
|
||||
const zdwm_window_id_t *window_ids;
|
||||
size_t window_count;
|
||||
@@ -30,6 +31,11 @@ typedef struct zdwm_layout_result_t {
|
||||
size_t item_capacity;
|
||||
} zdwm_layout_result_t;
|
||||
|
||||
/**
|
||||
* @brief 自动布局算法
|
||||
*
|
||||
* @return out 有变化返回 true 否则返回 true
|
||||
*/
|
||||
typedef bool (*zdwm_layout_fn)(
|
||||
const zdwm_layout_ctx_t *ctx,
|
||||
zdwm_layout_result_t *out
|
||||
|
||||
@@ -20,29 +20,42 @@ bool config_defaults_build(
|
||||
) {
|
||||
if (!api || !builder || !outputs || output_count == 0) return false;
|
||||
|
||||
zdwm_layout_id_t tile_id = api->register_layout(
|
||||
zdwm_layout_id_t fair_id = api->register_layout(
|
||||
builder,
|
||||
"tile",
|
||||
"fair",
|
||||
"[]=",
|
||||
"builtin tile",
|
||||
api->builtin_layouts.tile
|
||||
"builtin fair",
|
||||
api->builtin_layouts.fair
|
||||
);
|
||||
zdwm_layout_id_t monocle_id = api->register_layout(
|
||||
zdwm_layout_id_t maximize_id = api->register_layout(
|
||||
builder,
|
||||
"monocle",
|
||||
"maximize",
|
||||
"[M]",
|
||||
"builtin monocle",
|
||||
api->builtin_layouts.monocle
|
||||
"builtin maximize",
|
||||
api->builtin_layouts.maximize
|
||||
);
|
||||
zdwm_layout_id_t fullscreen_id = api->register_layout(
|
||||
builder,
|
||||
"fullscreen",
|
||||
"[F]",
|
||||
"builtin fullscreen",
|
||||
api->builtin_layouts.fullscreen
|
||||
);
|
||||
zdwm_layout_id_t floating_id =
|
||||
api->register_layout(builder, "floating", "><>", "floating", nullptr);
|
||||
if (tile_id == ZDWM_LAYOUT_ID_INVALID ||
|
||||
monocle_id == ZDWM_LAYOUT_ID_INVALID ||
|
||||
if (fair_id == ZDWM_LAYOUT_ID_INVALID ||
|
||||
maximize_id == ZDWM_LAYOUT_ID_INVALID ||
|
||||
fullscreen_id == ZDWM_LAYOUT_ID_INVALID ||
|
||||
floating_id == ZDWM_LAYOUT_ID_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
zdwm_layout_id_t layout_ids[] = {tile_id, monocle_id, floating_id};
|
||||
zdwm_layout_id_t layout_ids[] = {
|
||||
fair_id,
|
||||
maximize_id,
|
||||
fullscreen_id,
|
||||
floating_id,
|
||||
};
|
||||
for (size_t i = 0; i < output_count; i++) {
|
||||
if (api->define_workspace(
|
||||
builder,
|
||||
@@ -50,7 +63,7 @@ bool config_defaults_build(
|
||||
"main",
|
||||
layout_ids,
|
||||
countof(layout_ids),
|
||||
tile_id
|
||||
fair_id
|
||||
) == ZDWM_WORKSPACE_ID_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include "core/runtime.h"
|
||||
#include "core/types.h"
|
||||
#include "core/wm_desc.h"
|
||||
#include "layouts/fair.h"
|
||||
#include "layouts/fullscreen.h"
|
||||
#include "layouts/maximize.h"
|
||||
|
||||
struct zdwm_config_builder_t {
|
||||
layout_registry_t layouts;
|
||||
@@ -216,8 +219,9 @@ static bool runtime_config_build(
|
||||
.abi_version = ZDWM_CONFIG_ABI_VERSION,
|
||||
.builtin_layouts =
|
||||
{
|
||||
.tile = nullptr,
|
||||
.monocle = nullptr,
|
||||
.fair = fair,
|
||||
.fullscreen = fullscreen,
|
||||
.maximize = maximize,
|
||||
},
|
||||
.register_layout = runtime_config_register_layout,
|
||||
.define_workspace = runtime_config_define_workspace,
|
||||
|
||||
1
src/layouts/.clang-format
Symbolic link
1
src/layouts/.clang-format
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.clang-format
|
||||
63
src/layouts/fair.c
Normal file
63
src/layouts/fair.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "layouts/fair.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
bool fair(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out) {
|
||||
auto windows = ctx->window_ids;
|
||||
auto count = (int32_t)ctx->window_count;
|
||||
if (!windows || !count) return false;
|
||||
|
||||
zdwm_layout_result_reset(out);
|
||||
|
||||
auto columns = (int32_t)floor(sqrt(count));
|
||||
if (columns * (columns + 1) <= count) ++columns;
|
||||
|
||||
auto rows_in_other_cols = count / columns;
|
||||
auto rows_in_main_col = count - (columns - 1) * rows_in_other_cols;
|
||||
while (rows_in_main_col > rows_in_other_cols) {
|
||||
++rows_in_other_cols;
|
||||
rows_in_main_col = count - (columns - 1) * rows_in_other_cols;
|
||||
}
|
||||
|
||||
auto workarea = &ctx->workarea;
|
||||
auto width_avg = workarea->width / columns;
|
||||
auto width_for_main_col = workarea->width - (columns - 1) * width_avg;
|
||||
auto width_for_other_col = width_avg;
|
||||
|
||||
int32_t row = 0, col = 0, row_count;
|
||||
int32_t x = workarea->x, y = workarea->y;
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
int32_t width;
|
||||
|
||||
if (i < rows_in_main_col) {
|
||||
row = i;
|
||||
width = width_for_main_col;
|
||||
row_count = rows_in_main_col;
|
||||
} else {
|
||||
width = width_for_other_col;
|
||||
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_col;
|
||||
y = workarea->y;
|
||||
}
|
||||
}
|
||||
|
||||
auto h_avg = workarea->height / row_count;
|
||||
auto h_main = workarea->height - h_avg * (row_count - 1);
|
||||
auto height = row == 0 ? h_main : h_avg;
|
||||
zdwm_layout_item_t item = {
|
||||
.window_id = windows[i],
|
||||
.rect = {.x = x, .y = y, .width = width, .height = height}
|
||||
};
|
||||
zdwm_layout_result_push(out, item);
|
||||
|
||||
y += height;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
5
src/layouts/fair.h
Normal file
5
src/layouts/fair.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
bool fair(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out);
|
||||
18
src/layouts/fullscreen.c
Normal file
18
src/layouts/fullscreen.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "layouts/fullscreen.h"
|
||||
|
||||
bool fullscreen(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out) {
|
||||
auto windows = ctx->window_ids;
|
||||
auto count = ctx->window_count;
|
||||
if (!windows || !count) return false;
|
||||
|
||||
zdwm_layout_result_reset(out);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
zdwm_layout_item_t item = {
|
||||
.window_id = windows[i],
|
||||
.rect = ctx->output_geometry,
|
||||
};
|
||||
zdwm_layout_result_push(out, item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
5
src/layouts/fullscreen.h
Normal file
5
src/layouts/fullscreen.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
bool fullscreen(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out);
|
||||
20
src/layouts/maximize.c
Normal file
20
src/layouts/maximize.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "layouts/maximize.h"
|
||||
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
bool maximize(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out) {
|
||||
auto windows = ctx->window_ids;
|
||||
auto count = ctx->window_count;
|
||||
if (!windows || !count) return false;
|
||||
|
||||
zdwm_layout_result_reset(out);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
zdwm_layout_item_t item = {
|
||||
.window_id = windows[i],
|
||||
.rect = ctx->workarea,
|
||||
};
|
||||
zdwm_layout_result_push(out, item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
5
src/layouts/maximize.h
Normal file
5
src/layouts/maximize.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
bool maximize(const zdwm_layout_ctx_t *ctx, zdwm_layout_result_t *out);
|
||||
@@ -53,6 +53,9 @@ add_executable(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
${SOURCE_DIR}/core/runtime.c
|
||||
${SOURCE_DIR}/core/state.c
|
||||
${SOURCE_DIR}/core/window.c
|
||||
${SOURCE_DIR}/layouts/fair.c
|
||||
${SOURCE_DIR}/layouts/fullscreen.c
|
||||
${SOURCE_DIR}/layouts/maximize.c
|
||||
)
|
||||
target_include_directories(${RUNTIME_CONFIG_TEST_APP_NAME} SYSTEM
|
||||
PRIVATE ${INCLUDE_DIR}
|
||||
@@ -63,6 +66,7 @@ target_include_directories(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
target_link_libraries(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
PRIVATE m
|
||||
PRIVATE ${deps_xkbcommon_MODULE_NAME}
|
||||
PRIVATE ${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
||||
@@ -22,6 +22,9 @@ add_executable(${TEST_APP_NAME}
|
||||
${SOURCE_DIR}/core/runtime.c
|
||||
${SOURCE_DIR}/core/state.c
|
||||
${SOURCE_DIR}/core/window.c
|
||||
${SOURCE_DIR}/layouts/fair.c
|
||||
${SOURCE_DIR}/layouts/fullscreen.c
|
||||
${SOURCE_DIR}/layouts/maximize.c
|
||||
)
|
||||
|
||||
target_include_directories(${TEST_APP_NAME} SYSTEM
|
||||
|
||||
Reference in New Issue
Block a user