refactor(core/runtime): 调整布局计算流程

This commit is contained in:
2026-04-28 03:28:03 +08:00
parent 722d3946c6
commit 78200debf5
3 changed files with 72 additions and 40 deletions

View File

@@ -2,6 +2,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <zdwm/layout.h> #include <zdwm/layout.h>
#include "action.h" #include "action.h"
@@ -145,9 +146,6 @@ void runtime_setup(runtime_t *runtime) {
} }
static const layout_result_t *runtime_layout_calc(runtime_t *runtime) { static const layout_result_t *runtime_layout_calc(runtime_t *runtime) {
auto plan = &runtime->plan;
if (!plan->need_relayout) return nullptr;
auto result = &runtime->layout_result; auto result = &runtime->layout_result;
zdwm_layout_result_reset(result); zdwm_layout_result_reset(result);
@@ -169,11 +167,24 @@ static const layout_result_t *runtime_layout_calc(runtime_t *runtime) {
for (size_t j = 0; j < state_window_count(state); j++) { for (size_t j = 0; j < state_window_count(state); j++) {
auto window = state_window_at(state, j); auto window = state_window_at(state, j);
if (!window || window->workspace_id != workspace->id) continue; if (!window || window->workspace_id != workspace->id) continue;
if (!window_need_layout(window)) continue;
window_id_t *window_id_slot = if (window_need_layout(window)) {
array_push(window_ids, window_count, window_list_capacity); window_id_t *window_id_slot =
*window_id_slot = window->id; array_push(window_ids, window_count, window_list_capacity);
*window_id_slot = window->id;
} else if (window->geometry_mode == ZDWM_GEOMETRY_FULLSCREEN) {
layout_item_t item = {
.window_id = window->id,
.rect = output->geometry,
};
layout_result_push(result, item);
} else if (window->geometry_mode == ZDWM_GEOMETRY_MAXIMIZED) {
layout_item_t item = {
.window_id = window->id,
.rect = output->workarea,
};
layout_result_push(result, item);
}
} }
if (window_count) { if (window_count) {
@@ -194,6 +205,44 @@ static const layout_result_t *runtime_layout_calc(runtime_t *runtime) {
return result->item_count ? result : nullptr; return result->item_count ? result : nullptr;
} }
static void runtime_apply_window_rect(
state_t *state,
window_id_t window_id,
rect_t rect,
plan_t *plan
) {
auto window = state_window_get(state, window_id);
if (!window) return;
auto need_move = window_need_move(window, rect.x, rect.y);
auto need_resize = window_need_resize(window, rect.width, rect.height);
if (need_move) {
effect_t move_window_effect = {
.type = ZDWM_EFFECT_MOVE_WINDOW,
.as.move = {
.window = window_id,
.left_top_point = {.x = rect.x, .y = rect.y}
}
};
plan_push_effect(plan, &move_window_effect);
}
if (need_resize) {
effect_t resize_window_effect = {
.type = ZDWM_EFFECT_RESIZE_WINDOW,
.as.resize = {
.window = window_id,
.width = rect.width,
.height = rect.height,
}
};
plan_push_effect(plan, &resize_window_effect);
}
if (need_move || need_resize) {
state_window_set_frame_rect(state, window_id, rect);
}
}
static void runtime_arrange(runtime_t *runtime) { static void runtime_arrange(runtime_t *runtime) {
auto result = runtime_layout_calc(runtime); auto result = runtime_layout_calc(runtime);
if (!result) return; if (!result) return;
@@ -201,38 +250,8 @@ static void runtime_arrange(runtime_t *runtime) {
auto state = &runtime->state; auto state = &runtime->state;
auto plan = &runtime->plan; auto plan = &runtime->plan;
for (size_t i = 0; i < result->item_count; ++i) { for (size_t i = 0; i < result->item_count; ++i) {
auto window_id = result->items[i].window_id; auto item = &result->items[i];
auto window = state_window_get(state, window_id); runtime_apply_window_rect(state, item->window_id, item->rect, plan);
if (!window) continue;
auto rect = result->items[i].rect;
auto frame_rect = window->frame_rect;
if (frame_rect.x != rect.x || frame_rect.y != rect.y) {
effect_t move_window_effect = {
.type = ZDWM_EFFECT_MOVE_WINDOW,
.as.move = {
.window = window->id,
.left_top_point = {.x = rect.x, .y = rect.y}
}
};
plan_push_effect(plan, &move_window_effect);
}
if (frame_rect.width != rect.width || frame_rect.height != rect.height) {
effect_t resize_window_effect = {
.type = ZDWM_EFFECT_RESIZE_WINDOW,
.as.resize = {
.window = window_id,
.width = rect.width,
.height = rect.height,
}
};
plan_push_effect(plan, &resize_window_effect);
}
state_window_set_frame_rect(state, window_id, rect);
} }
} }
@@ -261,7 +280,7 @@ void runtime_run(runtime_t *runtime) {
policy_route_event(&ctx, &event, command_buffer); policy_route_event(&ctx, &event, command_buffer);
policy_apply_command(&ctx, command_buffer, plan); policy_apply_command(&ctx, command_buffer, plan);
runtime_arrange(runtime); if (plan->need_relayout) runtime_arrange(runtime);
if (plan->count) backend_apply_effect(backend, plan->effects, plan->count); if (plan->count) backend_apply_effect(backend, plan->effects, plan->count);
event_cleanup(&event); event_cleanup(&event);

View File

@@ -135,3 +135,14 @@ bool window_need_layout(const window_t *window) {
return true; return true;
} }
bool window_need_resize(const window_t *window, int32_t width, int32_t height);
bool window_need_move(const window_t *window, int32_t x, int32_t y) {
return window->frame_rect.x != x || window->frame_rect.y != y;
}
bool window_need_resize(const window_t *window, int32_t width, int32_t height) {
return window->frame_rect.width != width ||
window->frame_rect.height != height;
}

View File

@@ -121,3 +121,5 @@ void window_take_metadata(
* @brief 窗口是否需要参与布局计算 * @brief 窗口是否需要参与布局计算
*/ */
bool window_need_layout(const window_t *window); bool window_need_layout(const window_t *window);
bool window_need_move(const window_t *window, int32_t x, int32_t y);
bool window_need_resize(const window_t *window, int32_t width, int32_t height);