feat(runtime): 启动时扫描并接管已有窗口

从 handle_map_request 中提取 populate_window_event 供复用,
新增 backend_scan_windows 扫描 X11 根窗口子树,
runtime_scan 将扫描到的窗口走完整 policy 流程纳入管理。
route_map_request 增加 override_redirect 过滤。
This commit is contained in:
2026-05-07 06:36:58 +08:00
parent c1a4795a85
commit 9275d14c5f
7 changed files with 141 additions and 23 deletions

View File

@@ -37,3 +37,17 @@ bool backend_apply_effect(
const effect_t *effects,
size_t effect_count
);
typedef struct backend_scan_result_t {
window_map_request_event_t *windows;
size_t count;
size_t capacity;
} backend_scan_result_t;
/**
* @brief 扫描已有窗口
*
* @details 仅扫描窗口并获取其基础信息
*/
backend_scan_result_t *backend_scan_windows(backend_t *backend);
void backend_scan_result_destroy(backend_scan_result_t *result);

View File

@@ -53,6 +53,7 @@ static void route_map_request(
const window_map_request_event_t *e,
command_buffer_t *out
) {
if (e->override_redirect) return;
if (state_window_get(state, e->window)) return;
window_layer_type_t layer_type = window_classify_layer(&e->props);

View File

@@ -257,20 +257,14 @@ static void runtime_arrange(runtime_t *runtime) {
}
}
void runtime_run(runtime_t *runtime) {
runtime->running = true;
backend_t *backend = runtime->backend;
command_buffer_t *command_buffer = &runtime->command_buffer;
plan_t *plan = &runtime->plan;
policy_context_t policy_context_init(runtime_t *runtime) {
policy_context_t ctx = {
.bind_table = runtime->binding_table,
.state = &runtime->state,
.rules = &runtime->rules,
.border = &runtime->border,
.layouts = &runtime->layouts,
.runtime = runtime,
.bind_table = (runtime)->binding_table,
.state = &(runtime)->state,
.rules = &(runtime)->rules,
.border = &(runtime)->border,
.layouts = &(runtime)->layouts,
.runtime = (runtime),
.action_api = {
.spawn = spawn,
.quit = quit,
@@ -284,6 +278,46 @@ void runtime_run(runtime_t *runtime) {
.cycle_current_output = cycle_current_output,
},
};
return ctx;
}
void runtime_scan(runtime_t *runtime) {
auto result = backend_scan_windows(runtime->backend);
if (!result) return;
policy_context_t ctx = policy_context_init(runtime);
auto backend = runtime->backend;
auto command_buffer = &runtime->command_buffer;
auto plan = &runtime->plan;
command_buffer_reset(command_buffer);
plan_reset(plan);
for (size_t i = 0; i < result->count; i++) {
event_t event = {
.type = ZDWM_EVENT_WINDOW_MAP_REQUEST,
.as.window_map_request = result->windows[i],
};
policy_route_event(&ctx, &event, command_buffer);
}
policy_apply_command(&ctx, command_buffer, plan);
if (plan->need_relayout) runtime_arrange(runtime);
if (plan->count) backend_apply_effect(backend, plan->effects, plan->count);
backend_scan_result_destroy(result);
result = nullptr;
}
void runtime_run(runtime_t *runtime) {
runtime->running = true;
backend_t *backend = runtime->backend;
command_buffer_t *command_buffer = &runtime->command_buffer;
plan_t *plan = &runtime->plan;
policy_context_t ctx = policy_context_init(runtime);
while (runtime->running) {
event_t event = {0};

View File

@@ -46,4 +46,5 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
void runtime_shutdown(runtime_t *runtime);
void runtime_setup(runtime_t *runtime);
void runtime_scan(runtime_t *runtime);
void runtime_run(runtime_t *runtime);