refactor(core): 提取 window 相关类型和操作到独立模块

This commit is contained in:
2026-04-20 00:20:04 +08:00
parent a7225836e4
commit fd843dc826
12 changed files with 228 additions and 179 deletions

View File

@@ -1,25 +1,7 @@
#include "core/event.h" #include "core/event.h"
#include "base/memory.h" #include "base/memory.h"
#include "core/window.h"
static void window_layer_props_cleanup(window_layer_props_t *props) {
if (!props) return;
p_delete(&props->types);
props->type_count = 0;
p_delete(&props->states);
props->state_count = 0;
}
static void window_metadata_cleanup(window_metadata_t *metadata) {
if (!metadata) return;
p_delete(&metadata->title);
p_delete(&metadata->app_id);
p_delete(&metadata->role);
p_delete(&metadata->class_name);
p_delete(&metadata->instance_name);
}
void event_cleanup(event_t *event) { void event_cleanup(event_t *event) {
if (!event) return; if (!event) return;

View File

@@ -86,14 +86,6 @@ typedef struct window_remove_event_t {
window_remove_reason_t reason; window_remove_reason_t reason;
} window_remove_event_t; } window_remove_event_t;
typedef enum window_metadata_change_flags_t {
ZDWM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0,
ZDWM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1,
ZDWM_WINDOW_METADATA_CHANGE_ROLE = 1u << 2,
ZDWM_WINDOW_METADATA_CHANGE_CLASS = 1u << 3,
ZDWM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 4,
} window_metadata_change_flags_t;
typedef struct window_metadata_change_event_t { typedef struct window_metadata_change_event_t {
window_id_t window; window_id_t window;
uint32_t changed_fields; uint32_t changed_fields;

View File

@@ -5,7 +5,6 @@
#include "base/array.h" #include "base/array.h"
#include "base/memory.h" #include "base/memory.h"
#include "core/types.h" #include "core/types.h"
#include "core/window.h"
void layer_stack_cleanup(layer_stack_t *layer) { void layer_stack_cleanup(layer_stack_t *layer) {
p_delete(&layer->order); p_delete(&layer->order);
@@ -87,17 +86,3 @@ bool layer_stack_lower(layer_stack_t *layer, window_id_t window) {
return true; return true;
} }
layer_type_t layer_classify(const window_layer_props_t *props) {
for (size_t i = 0; i < props->type_count; ++i) {
window_type_t type = props->types[i];
if (type == ZDWM_WINDOW_TYPE_NOTIFICATION) return ZDWM_WINDOW_LAYER_OVERLAY;
}
for (size_t i = 0; i < props->state_count; ++i) {
window_state_t state = props->states[i];
if (state == ZDWM_WINDOW_STATE_ABOVE) return ZDWM_WINDOW_LAYER_TOP;
}
return ZDWM_WINDOW_LAYER_NORMAL;
}

View File

@@ -3,16 +3,6 @@
#include <stddef.h> #include <stddef.h>
#include "core/types.h" #include "core/types.h"
#include "core/window.h"
/* 层级从低到高 */
typedef enum layer_type_t {
ZDWM_WINDOW_LAYER_DESKTOP = 0,
ZDWM_WINDOW_LAYER_NORMAL,
ZDWM_WINDOW_LAYER_TOP,
ZDWM_WINDOW_LAYER_OVERLAY,
ZDWM_WINDOW_LAYER_COUNT,
} layer_type_t;
typedef struct layer_stack_t { typedef struct layer_stack_t {
window_id_t *order; window_id_t *order;
@@ -56,5 +46,3 @@ bool layer_stack_raise(layer_stack_t *layer, window_id_t window);
* @return 仅在窗口存在且顺序发生变化时返回 true否则返回 false。 * @return 仅在窗口存在且顺序发生变化时返回 true否则返回 false。
*/ */
bool layer_stack_lower(layer_stack_t *layer, window_id_t window); bool layer_stack_lower(layer_stack_t *layer, window_id_t window);
layer_type_t layer_classify(const window_layer_props_t *props);

View File

@@ -7,11 +7,11 @@
#include "core/command.h" #include "core/command.h"
#include "core/command_buffer.h" #include "core/command_buffer.h"
#include "core/event.h" #include "core/event.h"
#include "core/layer.h"
#include "core/plan.h" #include "core/plan.h"
#include "core/rules.h" #include "core/rules.h"
#include "core/state.h" #include "core/state.h"
#include "core/types.h" #include "core/types.h"
#include "core/window.h"
#include "core/wm_desc.h" #include "core/wm_desc.h"
static workspace_id_t derive_window_workspace(const state_t *state) { static workspace_id_t derive_window_workspace(const state_t *state) {
@@ -26,7 +26,7 @@ static bool route_map_request(
) { ) {
if (state_window_get(state, e->window)) return false; if (state_window_get(state, e->window)) return false;
layer_type_t layer_type = layer_classify(&e->props); window_layer_type_t layer_type = window_classify_layer(&e->props);
if (e->transient_for != ZDWM_WINDOW_ID_INVALID) { if (e->transient_for != ZDWM_WINDOW_ID_INVALID) {
const window_t *window = state_window_get(state, e->transient_for); const window_t *window = state_window_get(state, e->transient_for);
if (window) layer_type = MAX(window->layer, layer_type); if (window) layer_type = MAX(window->layer, layer_type);
@@ -138,7 +138,7 @@ static bool manage_window(
} }
static bool switch_workspace( static bool switch_workspace(
const state_t *state, state_t *state,
const switch_workspace_command_t *command, const switch_workspace_command_t *command,
plan_t *plan plan_t *plan
) { ) {

View File

@@ -8,9 +8,9 @@
#include "base/array.h" #include "base/array.h"
#include "base/log.h" #include "base/log.h"
#include "base/memory.h" #include "base/memory.h"
#include "core/event.h"
#include "core/layer.h" #include "core/layer.h"
#include "core/types.h" #include "core/types.h"
#include "core/window.h"
#include "core/wm_desc.h" #include "core/wm_desc.h"
void state_init( void state_init(
@@ -318,59 +318,6 @@ bool state_set_current_output(state_t *state, output_id_t output_id) {
return false; return false;
} }
static inline void window_set_geometry_mode(
window_t *window,
window_geometry_mode_t geometry_mode
) {
window->geometry_mode = geometry_mode;
}
static inline void window_set_floating(window_t *window, bool floating) {
window->floating = floating;
if (floating) window->float_rect = window->frame_rect;
}
static inline void window_set_sticky(window_t *window, bool sticky) {
window->sticky = sticky;
if (sticky) window_set_floating(window, true);
}
static inline void window_set_urgent(window_t *window, bool urgent) {
window->urgent = urgent;
}
static inline void window_set_fixed_size(window_t *window, bool fixed_size) {
window->fixed_size = fixed_size;
if (fixed_size) window_set_floating(window, true);
}
static inline void window_set_float_rect(window_t *window, rect_t rect) {
window->float_rect = rect;
}
static inline void window_set_frame_rect(window_t *window, rect_t rect) {
window->frame_rect = rect;
}
static inline void window_set_title(window_t *window, const char *title) {
p_delete(&window->title);
window->title = p_strdup_nullable(title);
}
static inline void window_set_app_id(window_t *window, const char *app_id) {
p_delete(&window->app_id);
window->app_id = p_strdup_nullable(app_id);
}
static inline void window_set_role(window_t *window, const char *role) {
p_delete(&window->role);
window->role = p_strdup_nullable(role);
}
static inline void window_set_class(window_t *window, const char *class_name) {
p_delete(&window->class_name);
window->class_name = p_strdup_nullable(class_name);
}
static inline void
window_set_instance(window_t *window, const char *instance_name) {
p_delete(&window->instance_name);
window->instance_name = p_strdup_nullable(instance_name);
}
static inline void
window_set_skip_taskbar(window_t *window, bool skip_taskbar) {
window->skip_taskbar = skip_taskbar;
}
const window_t *state_window_add(state_t *state, const window_info_t *info) { const window_t *state_window_add(state_t *state, const window_info_t *info) {
window_id_t id = info->id; window_id_t id = info->id;
window_t *window = (window_t *)state_window_get(state, id); window_t *window = (window_t *)state_window_get(state, id);
@@ -428,9 +375,9 @@ void state_window_remove(state_t *state, window_id_t id) {
} }
if (!matched) return; if (!matched) return;
window_t *window = &state->windows[index]; window_t *window = &state->windows[index];
layer_type_t layer_type = window->layer; window_layer_type_t layer_type = window->layer;
workspace_id_t workspace_id = window->workspace_id; workspace_id_t workspace_id = window->workspace_id;
p_delete(&window->title); p_delete(&window->title);
p_delete(&window->app_id); p_delete(&window->app_id);
p_delete(&window->role); p_delete(&window->role);
@@ -560,21 +507,7 @@ bool state_window_take_metadata(
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_TITLE) { window_take_metadata(window, metadata, changed_fields);
p_take(&window->title, &metadata->title);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_APP_ID) {
p_take(&window->app_id, &metadata->app_id);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_ROLE) {
p_take(&window->role, &metadata->role);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_CLASS) {
p_take(&window->class_name, &metadata->class_name);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_INSTANCE) {
p_take(&window->instance_name, &metadata->instance_name);
}
return true; return true;
} }
@@ -658,19 +591,3 @@ bool state_stack_lower(state_t *state, window_id_t window_id) {
return layer_stack_lower(layer, window_id); return layer_stack_lower(layer, window_id);
} }
bool window_need_layout(const window_t *window) {
if (window->sticky || window->floating) {
return false;
}
switch (window->geometry_mode) {
case ZDWM_GEOMETRY_FULLSCREEN:
case ZDWM_GEOMETRY_MAXIMIZED:
case ZDWM_GEOMETRY_MINIMIZED:
return false;
default:
}
return true;
}

View File

@@ -8,33 +8,6 @@
#include "core/window.h" #include "core/window.h"
#include "core/wm_desc.h" #include "core/wm_desc.h"
/* 核心实体定义 */
typedef struct window_t {
window_id_t id;
window_id_t transient_for;
workspace_id_t workspace_id;
layer_type_t layer;
window_geometry_mode_t geometry_mode;
bool floating;
bool sticky;
bool urgent;
bool fixed_size;
/* 几何信息(均为包含边框后的外框矩形) */
rect_t float_rect; /* floating 模式下记忆的外框矩形 */
rect_t frame_rect; /* 当前外框矩形(由 layout 或 float_rect 解析) */
/* 元数据(核心算法不依赖,仅用于规则匹配和信息展示) */
char *title;
char *app_id;
char *role;
char *class_name;
char *instance_name;
bool skip_taskbar;
} window_t;
typedef struct workspace_t { typedef struct workspace_t {
workspace_id_t id; workspace_id_t id;
output_id_t output_id; /* 固定归属某个输出 */ output_id_t output_id; /* 固定归属某个输出 */
@@ -288,8 +261,3 @@ bool state_window_set_instance(
bool state_stack_raise(state_t *state, window_id_t window_id); bool state_stack_raise(state_t *state, window_id_t window_id);
bool state_stack_lower(state_t *state, window_id_t window_id); bool state_stack_lower(state_t *state, window_id_t window_id);
/**
* @brief 窗口是否需要参与布局计算
*/
bool window_need_layout(const window_t *window);

137
src/core/window.c Normal file
View File

@@ -0,0 +1,137 @@
#include "core/window.h"
#include "base/memory.h"
window_layer_type_t window_classify_layer(const window_layer_props_t *props) {
for (size_t i = 0; i < props->type_count; ++i) {
window_type_t type = props->types[i];
if (type == ZDWM_WINDOW_TYPE_NOTIFICATION) return ZDWM_WINDOW_LAYER_OVERLAY;
}
for (size_t i = 0; i < props->state_count; ++i) {
window_state_t state = props->states[i];
if (state == ZDWM_WINDOW_STATE_ABOVE) return ZDWM_WINDOW_LAYER_TOP;
}
return ZDWM_WINDOW_LAYER_NORMAL;
}
void window_layer_props_cleanup(window_layer_props_t *props) {
if (!props) return;
p_delete(&props->types);
props->type_count = 0;
p_delete(&props->states);
props->state_count = 0;
}
void window_metadata_cleanup(window_metadata_t *metadata) {
if (!metadata) return;
p_delete(&metadata->title);
p_delete(&metadata->app_id);
p_delete(&metadata->role);
p_delete(&metadata->class_name);
p_delete(&metadata->instance_name);
}
void window_set_geometry_mode(
window_t *window,
window_geometry_mode_t geometry_mode
) {
window->geometry_mode = geometry_mode;
}
void window_set_floating(window_t *window, bool floating) {
window->floating = floating;
if (floating) window->float_rect = window->frame_rect;
}
void window_set_sticky(window_t *window, bool sticky) {
window->sticky = sticky;
if (sticky) window_set_floating(window, true);
}
void window_set_urgent(window_t *window, bool urgent) {
window->urgent = urgent;
}
void window_set_fixed_size(window_t *window, bool fixed_size) {
window->fixed_size = fixed_size;
if (fixed_size) window_set_floating(window, true);
}
void window_set_float_rect(window_t *window, rect_t rect) {
window->float_rect = rect;
}
void window_set_frame_rect(window_t *window, rect_t rect) {
window->frame_rect = rect;
}
void window_set_title(window_t *window, const char *title) {
p_delete(&window->title);
window->title = p_strdup_nullable(title);
}
void window_set_app_id(window_t *window, const char *app_id) {
p_delete(&window->app_id);
window->app_id = p_strdup_nullable(app_id);
}
void window_set_role(window_t *window, const char *role) {
p_delete(&window->role);
window->role = p_strdup_nullable(role);
}
void window_set_class(window_t *window, const char *class_name) {
p_delete(&window->class_name);
window->class_name = p_strdup_nullable(class_name);
}
void window_set_instance(window_t *window, const char *instance_name) {
p_delete(&window->instance_name);
window->instance_name = p_strdup_nullable(instance_name);
}
void window_set_skip_taskbar(window_t *window, bool skip_taskbar) {
window->skip_taskbar = skip_taskbar;
}
void window_take_metadata(
window_t *window,
window_metadata_t *metadata,
uint32_t changed_fields
) {
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_TITLE) {
p_take(&window->title, &metadata->title);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_APP_ID) {
p_take(&window->app_id, &metadata->app_id);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_ROLE) {
p_take(&window->role, &metadata->role);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_CLASS) {
p_take(&window->class_name, &metadata->class_name);
}
if (changed_fields & ZDWM_WINDOW_METADATA_CHANGE_INSTANCE) {
p_take(&window->instance_name, &metadata->instance_name);
}
}
bool window_need_layout(const window_t *window) {
if (window->sticky || window->floating) {
return false;
}
switch (window->geometry_mode) {
case ZDWM_GEOMETRY_FULLSCREEN:
case ZDWM_GEOMETRY_MAXIMIZED:
case ZDWM_GEOMETRY_MINIMIZED:
return false;
default:
}
return true;
}

View File

@@ -1,6 +1,9 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include "core/types.h"
/* Internal semantic window types mapped from backend-specific protocols. */ /* Internal semantic window types mapped from backend-specific protocols. */
typedef enum window_type_t { typedef enum window_type_t {
@@ -28,6 +31,23 @@ typedef enum window_state_t {
ZDWM_WINDOW_STATE_STICKY, ZDWM_WINDOW_STATE_STICKY,
} window_state_t; } window_state_t;
/* 层级从低到高 */
typedef enum window_layer_type_t {
ZDWM_WINDOW_LAYER_DESKTOP = 0,
ZDWM_WINDOW_LAYER_NORMAL,
ZDWM_WINDOW_LAYER_TOP,
ZDWM_WINDOW_LAYER_OVERLAY,
ZDWM_WINDOW_LAYER_COUNT,
} window_layer_type_t;
typedef enum window_metadata_change_flags_t {
ZDWM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0,
ZDWM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1,
ZDWM_WINDOW_METADATA_CHANGE_ROLE = 1u << 2,
ZDWM_WINDOW_METADATA_CHANGE_CLASS = 1u << 3,
ZDWM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 4,
} window_metadata_change_flags_t;
typedef struct window_layer_props_t { typedef struct window_layer_props_t {
window_type_t *types; window_type_t *types;
size_t type_count; size_t type_count;
@@ -43,3 +63,61 @@ typedef struct window_metadata_t {
char *class_name; char *class_name;
char *instance_name; char *instance_name;
} window_metadata_t; } window_metadata_t;
typedef struct window_t {
window_id_t id;
window_id_t transient_for;
workspace_id_t workspace_id;
window_layer_type_t layer;
window_geometry_mode_t geometry_mode;
bool floating;
bool sticky;
bool urgent;
bool fixed_size;
/* 几何信息(均为包含边框后的外框矩形) */
rect_t float_rect; /* floating 模式下记忆的外框矩形 */
rect_t frame_rect; /* 当前外框矩形(由 layout 或 float_rect 解析) */
/* 元数据(核心算法不依赖,仅用于规则匹配和信息展示) */
char *title;
char *app_id;
char *role;
char *class_name;
char *instance_name;
bool skip_taskbar;
} window_t;
window_layer_type_t window_classify_layer(const window_layer_props_t *props);
void window_layer_props_cleanup(window_layer_props_t *props);
void window_metadata_cleanup(window_metadata_t *metadata);
void window_set_geometry_mode(
window_t *window,
window_geometry_mode_t geometry_mode
);
void window_set_floating(window_t *window, bool floating);
void window_set_sticky(window_t *window, bool sticky);
void window_set_urgent(window_t *window, bool urgent);
void window_set_fixed_size(window_t *window, bool fixed_size);
void window_set_float_rect(window_t *window, rect_t rect);
void window_set_frame_rect(window_t *window, rect_t rect);
void window_set_title(window_t *window, const char *title);
void window_set_app_id(window_t *window, const char *app_id);
void window_set_role(window_t *window, const char *role);
void window_set_class(window_t *window, const char *class_name);
void window_set_instance(window_t *window, const char *instance_name);
void window_set_skip_taskbar(window_t *window, bool skip_taskbar);
void window_take_metadata(
window_t *window,
window_metadata_t *metadata,
uint32_t changed_fields
);
/**
* @brief 窗口是否需要参与布局计算
*/
bool window_need_layout(const window_t *window);

View File

@@ -3,8 +3,8 @@
#include <stddef.h> #include <stddef.h>
#include "base/memory.h" #include "base/memory.h"
#include "core/layer.h"
#include "core/types.h" #include "core/types.h"
#include "core/window.h"
/* /*
* 由 backend 提供的窗口基础信息。 * 由 backend 提供的窗口基础信息。
@@ -23,7 +23,7 @@ typedef struct window_info_t {
const char *instance_name; const char *instance_name;
window_geometry_mode_t geometry_mode; window_geometry_mode_t geometry_mode;
layer_type_t layer_type; window_layer_type_t layer_type;
bool urgent; bool urgent;
bool fixed_size; bool fixed_size;
bool skip_taskbar; bool skip_taskbar;

View File

@@ -50,6 +50,7 @@ add_executable(${RUNTIME_CONFIG_TEST_APP_NAME}
${SOURCE_DIR}/core/rules.c ${SOURCE_DIR}/core/rules.c
${SOURCE_DIR}/core/runtime.c ${SOURCE_DIR}/core/runtime.c
${SOURCE_DIR}/core/state.c ${SOURCE_DIR}/core/state.c
${SOURCE_DIR}/core/window.c
) )
target_include_directories(${RUNTIME_CONFIG_TEST_APP_NAME} SYSTEM target_include_directories(${RUNTIME_CONFIG_TEST_APP_NAME} SYSTEM
PRIVATE ${INCLUDE_DIR} PRIVATE ${INCLUDE_DIR}

View File

@@ -19,6 +19,7 @@ add_executable(${TEST_APP_NAME}
${SOURCE_DIR}/core/rules.c ${SOURCE_DIR}/core/rules.c
${SOURCE_DIR}/core/runtime.c ${SOURCE_DIR}/core/runtime.c
${SOURCE_DIR}/core/state.c ${SOURCE_DIR}/core/state.c
${SOURCE_DIR}/core/window.c
) )
target_include_directories(${TEST_APP_NAME} SYSTEM target_include_directories(${TEST_APP_NAME} SYSTEM