Files
zdwm/src/core/state.h

204 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "core/layer.h"
#include "core/types.h"
#include "core/window.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 {
workspace_id_t id;
output_id_t output_id; /* 固定归属某个输出 */
layout_id_t layout_id; /* 当前活动布局(可用布局列表中的一个) */
window_id_t focused_window_id;
/* 当前 workspace 的可用布局列表 */
const layout_id_t *available_layouts;
size_t layout_count;
/* 名称(核心算法不依赖) */
const char *name;
} workspace_t;
typedef struct output_t {
output_id_t id;
workspace_id_t current_workspace_id;
const char *name;
rect_t geometry; /* 输出完整几何 */
rect_t workarea; /* 可用区域(排除面板等) */
} output_t;
/* 全局状态容器 */
typedef struct state_t {
/* 按 id 稳定引用的 workspace / output 集合 */
workspace_t *workspaces;
size_t workspace_count;
output_t *outputs;
size_t output_count;
size_t current_output_index;
window_t *windows;
size_t window_count;
size_t window_capacity;
/* 分层堆叠顺序:每层内部从低到高排列 */
layer_stack_t stacks[ZDWM_WINDOW_LAYER_COUNT];
} state_t;
/*
* 调用约束:
* - state 必须是有效的非空指针
* - state_init() / state_cleanup() 必须成对调用
* - 同一个 state 生命周期内state_init() 不允许重复调用
* - 除 state_init() 外,其余 state 相关接口都要求 state 已初始化
* - workspaces[i] 必须满足 workspace_desc_valid(&workspaces[i],
* output_count)
* - 传入空指针、未初始化对象或违反前置条件属于调用方错误
*
* 初始化时根据描述表构建 outputs[] 与 workspaces[]。
* workspace_id 由 state 按描述表顺序分配并保持稳定,不从 desc 中读取。
* 每个 output 的 current_workspace_id 会自动设置为首个归属到该 output 的
* workspace若某个 output 没有任何归属 workspacestate_init() 会失败。
*/
void state_init(state_t *state, const output_info_t *outputs,
size_t output_count, const workspace_desc_t *workspaces,
size_t workspace_count);
void state_cleanup(state_t *state);
/*
* state 持有的 workspace 集合接口
*
* 这组接口对外只提供只读访问。
* workspace 的运行期可变状态必须通过专门的 state 级更新接口修改。
*/
const workspace_t *state_workspace_get(const state_t *state, workspace_id_t id);
const workspace_t *state_workspace_at(const state_t *state, size_t index);
bool state_workspace_cycle_layout(state_t *state, workspace_id_t workspace_id);
bool state_workspace_set_layout_by_index(state_t *state,
workspace_id_t workspace_id,
size_t index);
bool state_workspace_set_layout_by_id(state_t *state,
workspace_id_t workspace_id,
layout_id_t layout_id);
void state_workspace_set_focused_window(state_t *state,
workspace_id_t workspace_id,
window_id_t window_id);
size_t state_workspace_count(const state_t *state);
bool state_workspace_valid(const state_t *state, workspace_id_t id);
/*
* state 持有的 output 集合接口
*
* 这组接口对外只提供只读访问。
* output 的运行期可变状态必须通过专门的 state 级更新接口修改。
*/
const output_t *state_output_get(const state_t *state, output_id_t id);
const output_t *state_output_at(const state_t *state, size_t index);
void state_output_set_workarea(state_t *state, output_id_t output_id,
rect_t workarea);
void state_output_set_current_workspace(state_t *state, output_id_t output_id,
workspace_id_t workspace_id);
size_t state_output_count(const state_t *state);
bool state_output_valid(const state_t *state, output_id_t id);
void state_cycle_current_output(state_t *state, int delta);
/*
* state 持有的 window 集合接口
*
* 这组接口负责管理 state_t.windows[] 容器本身,并维护分层的堆叠顺序。
* 接口返回的 window 对象仅提供只读访问。
* window 的运行期可变状态必须通过专门的 state 级更新接口修改。
*/
/*
* 添加窗口,并将其追加到对应堆栈顶部
*
* info 提供窗口的基础信息
* workspace 归属与其他策略相关字段由后续 state_window_* 接口设置。
*/
const window_t *state_window_add(state_t *state, const window_info_t *info);
const window_t *state_window_get(const state_t *state, window_id_t id);
const window_t *state_window_at(const state_t *state, size_t index);
/* 删除窗口,并同步将其从对应的堆叠栈中移除 */
void state_window_remove(state_t *state, window_id_t id);
size_t state_window_count(const state_t *state);
/* state 持有的单个 window 状态更新接口 */
void state_window_set_workspace(state_t *state, window_id_t window_id,
workspace_id_t workspace_id);
void state_window_set_geometry_mode(state_t *state, window_id_t window_id,
window_geometry_mode_t geometry_mode);
void state_window_set_floating(state_t *state, window_id_t window_id,
bool floating);
void state_window_set_sticky(state_t *state, window_id_t window_id,
bool sticky);
void state_window_set_urgent(state_t *state, window_id_t window_id,
bool urgent);
void state_window_set_fixed_size(state_t *state, window_id_t window_id,
bool fixed_size);
void state_window_set_skip_taskbar(state_t *state, window_id_t window_id,
bool skip_taskbar);
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,
const char *app_id);
bool state_window_set_role(state_t *state, window_id_t window_id,
const char *role);
bool state_window_set_class(state_t *state, window_id_t window_id,
const char *class_name);
bool state_window_set_instance(state_t *state, window_id_t window_id,
const char *instance_name);
bool state_stack_raise(state_t *state, window_id_t window_id);
bool state_stack_lower(state_t *state, window_id_t window_id);