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;
if (window_need_layout(window)) {
window_id_t *window_id_slot = window_id_t *window_id_slot =
array_push(window_ids, window_count, window_list_capacity); array_push(window_ids, window_count, window_list_capacity);
*window_id_slot = window->id; *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,33 +205,28 @@ 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_arrange(runtime_t *runtime) { static void runtime_apply_window_rect(
auto result = runtime_layout_calc(runtime); state_t *state,
if (!result) return; window_id_t window_id,
rect_t rect,
auto state = &runtime->state; plan_t *plan
auto plan = &runtime->plan; ) {
for (size_t i = 0; i < result->item_count; ++i) {
auto window_id = result->items[i].window_id;
auto window = state_window_get(state, window_id); auto window = state_window_get(state, window_id);
if (!window) return;
if (!window) continue; auto need_move = window_need_move(window, rect.x, rect.y);
auto need_resize = window_need_resize(window, rect.width, rect.height);
auto rect = result->items[i].rect; if (need_move) {
auto frame_rect = window->frame_rect;
if (frame_rect.x != rect.x || frame_rect.y != rect.y) {
effect_t move_window_effect = { effect_t move_window_effect = {
.type = ZDWM_EFFECT_MOVE_WINDOW, .type = ZDWM_EFFECT_MOVE_WINDOW,
.as.move = { .as.move = {
.window = window->id, .window = window_id,
.left_top_point = {.x = rect.x, .y = rect.y} .left_top_point = {.x = rect.x, .y = rect.y}
} }
}; };
plan_push_effect(plan, &move_window_effect); plan_push_effect(plan, &move_window_effect);
} }
if (need_resize) {
if (frame_rect.width != rect.width || frame_rect.height != rect.height) {
effect_t resize_window_effect = { effect_t resize_window_effect = {
.type = ZDWM_EFFECT_RESIZE_WINDOW, .type = ZDWM_EFFECT_RESIZE_WINDOW,
.as.resize = { .as.resize = {
@@ -232,10 +238,23 @@ static void runtime_arrange(runtime_t *runtime) {
plan_push_effect(plan, &resize_window_effect); plan_push_effect(plan, &resize_window_effect);
} }
if (need_move || need_resize) {
state_window_set_frame_rect(state, window_id, rect); state_window_set_frame_rect(state, window_id, rect);
} }
} }
static void runtime_arrange(runtime_t *runtime) {
auto result = runtime_layout_calc(runtime);
if (!result) return;
auto state = &runtime->state;
auto plan = &runtime->plan;
for (size_t i = 0; i < result->item_count; ++i) {
auto item = &result->items[i];
runtime_apply_window_rect(state, item->window_id, item->rect, plan);
}
}
void runtime_run(runtime_t *runtime) { void runtime_run(runtime_t *runtime) {
runtime->running = true; runtime->running = true;
@@ -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);