core: 补全 layout 注册表与结果集接口
- 新增 src/core/layout.c,实现 layout result 和 registry 的基础操作 - 精简 wm_layout_ctx_t,改为按顺序传递参与布局的窗口 id 列表 - 为 layout API 补充中文前置条件说明 - 在 utils 中补充 p_strdup 和容量扩展辅助函数
This commit is contained in:
99
src/core/layout.c
Normal file
99
src/core/layout.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "core/layout.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void wm_layout_result_init(wm_layout_result_t *result) {
|
||||
result->item_count = 0;
|
||||
result->item_capacity = INIT_CAPACITY;
|
||||
result->items = p_new(wm_layout_item_t, result->item_capacity);
|
||||
}
|
||||
|
||||
void wm_layout_result_reset(wm_layout_result_t *result) {
|
||||
result->item_count = 0;
|
||||
}
|
||||
|
||||
void wm_layout_result_shutdown(wm_layout_result_t *result) {
|
||||
p_delete(&result->items);
|
||||
result->item_count = 0;
|
||||
result->item_capacity = 0;
|
||||
}
|
||||
|
||||
void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item) {
|
||||
if (result->item_count == result->item_capacity) {
|
||||
size_t new_capacity = next_capacity(result->item_capacity);
|
||||
p_realloc(&result->items, new_capacity);
|
||||
result->item_capacity = new_capacity;
|
||||
}
|
||||
|
||||
result->items[result->item_count++] = item;
|
||||
}
|
||||
|
||||
void wm_layout_registry_init(wm_layout_registry_t *registry) {
|
||||
registry->slot_count = 0;
|
||||
registry->slot_capacity = INIT_CAPACITY;
|
||||
registry->slots = p_new(wm_layout_slot_t, registry->slot_capacity);
|
||||
}
|
||||
|
||||
void wm_layout_registry_shutdown(wm_layout_registry_t *registry) {
|
||||
while (registry->slot_count > 0) {
|
||||
wm_layout_slot_t *r = ®istry->slots[--registry->slot_count];
|
||||
p_delete(&r->name);
|
||||
p_delete(&r->symbol);
|
||||
p_delete(&r->description);
|
||||
r->fn = nullptr;
|
||||
r->id = WM_LAYOUT_ID_INVALID;
|
||||
}
|
||||
p_delete(®istry->slots);
|
||||
registry->slot_count = 0;
|
||||
registry->slot_capacity = 0;
|
||||
}
|
||||
|
||||
size_t wm_layout_registry_count(const wm_layout_registry_t *registry) {
|
||||
return registry->slot_count;
|
||||
}
|
||||
|
||||
const wm_layout_slot_t *wm_layout_registry_at(
|
||||
const wm_layout_registry_t *registry, size_t index) {
|
||||
if (index >= registry->slot_count) return nullptr;
|
||||
return ®istry->slots[index];
|
||||
}
|
||||
|
||||
wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
const char *name, const char *symbol,
|
||||
const char *description, wm_layout_fn fn) {
|
||||
if (!name || !symbol) return WM_LAYOUT_ID_INVALID;
|
||||
|
||||
if (registry->slot_count == registry->slot_capacity) {
|
||||
size_t new_capacity = next_capacity(registry->slot_capacity);
|
||||
p_realloc(®istry->slots, new_capacity);
|
||||
registry->slot_capacity = new_capacity;
|
||||
}
|
||||
wm_layout_id_t id = (wm_layout_id_t)registry->slot_count;
|
||||
|
||||
wm_layout_slot_t *r = ®istry->slots[registry->slot_count];
|
||||
r->id = id;
|
||||
r->name = p_strdup(name);
|
||||
r->symbol = p_strdup(symbol);
|
||||
r->description = description ? p_strdup(description) : nullptr;
|
||||
r->fn = fn;
|
||||
|
||||
registry->slot_count++;
|
||||
return id;
|
||||
}
|
||||
|
||||
wm_layout_fn wm_layout_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id) {
|
||||
const wm_layout_slot_t *layout_slot = wm_layout_slot_get(registry, id);
|
||||
if (layout_slot) return layout_slot->fn;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wm_layout_slot_t *wm_layout_slot_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id) {
|
||||
if (id >= registry->slot_count) return nullptr;
|
||||
return ®istry->slots[id];
|
||||
}
|
||||
@@ -4,17 +4,20 @@
|
||||
|
||||
#include "core/types.h"
|
||||
|
||||
typedef struct wm_layout_window_ref_t {
|
||||
wm_window_id_t window_id;
|
||||
wm_window_geometry_mode_t geometry_mode;
|
||||
} wm_layout_window_ref_t;
|
||||
|
||||
typedef struct wm_layout_ctx_t {
|
||||
wm_output_id_t output_id;
|
||||
wm_workspace_id_t workspace_id;
|
||||
wm_window_id_t focused_window_id;
|
||||
wm_rect_t workarea;
|
||||
const wm_layout_window_ref_t *windows;
|
||||
/*
|
||||
* 参与本次布局计算的窗口 ID 列表。
|
||||
*
|
||||
* 调用方负责在进入 layout 前完成筛选;这里不包含 floating、sticky、
|
||||
* fullscreen、minimized 等不参与平铺计算的窗口。
|
||||
*
|
||||
* 数组顺序具有语义,layout 应按该顺序解释窗口排列优先级。
|
||||
*/
|
||||
const wm_window_id_t *window_ids;
|
||||
size_t window_count;
|
||||
} wm_layout_ctx_t;
|
||||
|
||||
@@ -76,18 +79,48 @@ typedef struct wm_layout_registry_t {
|
||||
size_t slot_capacity;
|
||||
} wm_layout_registry_t;
|
||||
|
||||
/*
|
||||
* 调用约束:
|
||||
* - result 必须是有效的非空指针
|
||||
* - 除 init 之外,其余 result 相关接口都要求 result 已初始化
|
||||
* - 传入空指针或未初始化对象属于调用方错误
|
||||
*/
|
||||
void wm_layout_result_init(wm_layout_result_t *result);
|
||||
void wm_layout_result_reset(wm_layout_result_t *result);
|
||||
void wm_layout_result_shutdown(wm_layout_result_t *result);
|
||||
|
||||
bool wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item);
|
||||
void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item);
|
||||
|
||||
/*
|
||||
* 调用约束:
|
||||
* - registry 必须是有效的非空指针
|
||||
* - 除 init 之外,其余 registry 相关接口都要求 registry 已初始化
|
||||
* - 传入空指针或未初始化对象属于调用方错误
|
||||
*/
|
||||
void wm_layout_registry_init(wm_layout_registry_t *registry);
|
||||
void wm_layout_registry_shutdown(wm_layout_registry_t *registry);
|
||||
size_t wm_layout_registry_count(const wm_layout_registry_t *registry);
|
||||
const wm_layout_slot_t *wm_layout_registry_at(
|
||||
const wm_layout_registry_t *registry, size_t index);
|
||||
|
||||
/*
|
||||
* 注册一个布局并返回其稳定 ID。
|
||||
*
|
||||
* 前置条件:
|
||||
* - registry 必须已初始化
|
||||
*
|
||||
* 参数约束:
|
||||
* - name 不可为空,用于稳定配置名、日志和调试展示
|
||||
* - symbol 不可为空,用于状态栏等紧凑展示
|
||||
* - description 可为空
|
||||
* - fn 可为空;fn == NULL 表示 floating 布局,不参与平铺计算
|
||||
*
|
||||
* 返回值:
|
||||
* - 成功时返回新注册布局的 ID
|
||||
* - name 或 symbol 非法时返回 WM_LAYOUT_ID_INVALID
|
||||
*
|
||||
* 注册成功后,布局 ID 与其在 registry 中的槽位索引保持一致。
|
||||
*/
|
||||
wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
const char *name, const char *symbol,
|
||||
const char *description, wm_layout_fn fn);
|
||||
|
||||
12
src/utils.h
12
src/utils.h
@@ -28,6 +28,12 @@
|
||||
#define unlikely(expr) expr
|
||||
#endif
|
||||
|
||||
static inline char *p_strdup(const char *text) {
|
||||
char *r = strdup(text);
|
||||
if (!r) abort();
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void *__attribute__((malloc)) xmalloc(ssize_t size) {
|
||||
void *ptr;
|
||||
|
||||
@@ -101,3 +107,9 @@ static inline void logger(const char *format, ...) {
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
static constexpr size_t INIT_CAPACITY = 4;
|
||||
static inline size_t next_capacity(size_t capacity) {
|
||||
if (capacity) return capacity * 2;
|
||||
return INIT_CAPACITY;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user