diff --git a/src/base/memory.h b/src/base/memory.h index c9a47bf..ed772ed 100644 --- a/src/base/memory.h +++ b/src/base/memory.h @@ -18,6 +18,13 @@ *(void **)__ptr = nullptr; \ } while (0) +#define p_take(dst_p, src_p) \ + do { \ + p_delete(dst_p); \ + *(dst_p) = *(src_p); \ + *(src_p) = nullptr; \ + } while (0) + static inline char *p_strdup(const char *text) { char *r = strdup(text); if (!r) abort(); diff --git a/src/core/state.c b/src/core/state.c index f61342d..227aede 100644 --- a/src/core/state.c +++ b/src/core/state.c @@ -7,6 +7,7 @@ #include "base/array.h" #include "base/log.h" #include "base/memory.h" +#include "core/event.h" #include "core/layer.h" #include "core/types.h" #include "core/wm_desc.h" @@ -435,6 +436,31 @@ void state_window_set_frame_rect(state_t *state, window_id_t window_id, window->frame_rect = frame_rect; } +bool state_window_take_metadata(state_t *state, window_id_t window_id, + window_metadata_t *metadata, + uint32_t changed_fields) { + window_t *window = (window_t *)state_window_get(state, window_id); + if (!window) return false; + + 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); + } + + return true; +} + bool state_window_set_title(state_t *state, window_id_t window_id, const char *title) { window_t *window = (window_t *)state_window_get(state, window_id); diff --git a/src/core/state.h b/src/core/state.h index df5c3bb..d8c43a1 100644 --- a/src/core/state.h +++ b/src/core/state.h @@ -1,9 +1,11 @@ #pragma once #include +#include #include "core/layer.h" #include "core/types.h" +#include "core/window.h" #include "core/wm_desc.h" /* 核心实体定义 */ @@ -167,6 +169,23 @@ void state_window_set_float_rect(state_t *state, window_id_t window_id, rect_t float_rect); void state_window_set_frame_rect(state_t *state, window_id_t window_id, rect_t frame_rect); +/** + * @brief 按字段掩码转移窗口元数据的所有权 + * @param state 状态实例指针 + * @param window_id 目标窗口 id + * @param metadata 元数据来源;成功时仅被转移字段会被置空 + * @param changed_fields 需要转移的字段掩码 + * @return 成功返回 true;若目标窗口不存在则返回 false + * @details + * 成功时,仅转移 changed_fields 指定的字段到目标 window,并将 metadata 中对应 + * 字段置空;未置位字段保持在 metadata 中,所有权仍归调用方。 + * + * 失败时,不接管 metadata 中任何字段的所有权,metadata 保持不变,仍由调用方负 + * 责后续访问与释放。 + */ +bool state_window_take_metadata(state_t *state, window_id_t window_id, + window_metadata_t *metadata, + uint32_t changed_fields); bool state_window_set_title(state_t *state, window_id_t window_id, const char *title); bool state_window_set_app_id(state_t *state, window_id_t window_id,