* ZDWM 窗口管理器完整抽象层设计方案 ** 设计目标 创建一个清晰、实用、可落地的抽象层体系,解决当前项目的架构问题,提升可维护性和可扩展性,同时保持项目的简洁性和高性能。 ** 当前架构优势保留 ZDWM 现有的优秀设计基础: - ✅ 清晰的四层架构(UI/业务/数据/基础设施) - ✅ 优秀的观察者模式(状态栏更新) - ✅ 灵活的策略模式(布局系统) - ✅ 高效的事件驱动模型 - ✅ 良好的资源管理 ** 核心抽象层设计 *** 第一层:基础设施抽象层 (Infrastructure Layer) **** 1.1 上下文管理器 *问题*: 当前全局 =wm= 对象导致所有模块紧密耦合 *解决方案*: 引入上下文对象,实现依赖注入 #+BEGIN_SRC c // src/core/context.h // 前向声明 typedef struct display_backend_t display_backend_t; typedef struct wm_context_t { // 显示后端(X11 或 Wayland) display_backend_t *display_backend; // 核心状态 monitor_t *monitor_list; client_t *client_list; tag_t *tag_list; // 配置和状态 config_t *config; status_t *status; // 事件循环 GMainContext *main_context; // 引用计数 atomic_int ref_count; } wm_context_t; // 上下文生命周期管理 wm_context_t *wm_context_create(display_backend_type_t backend_type); wm_context_t *wm_context_ref(wm_context_t *ctx); void wm_context_unref(wm_context_t *ctx); // 获取全局上下文(向后兼容) wm_context_t *wm_context_get_default(void); // 显示后端访问(向后兼容) static inline xcb_connection_t* context_get_xcb_conn(wm_context_t *ctx) { return ctx->display_backend ? (xcb_connection_t*)ctx->display_backend->get_platform_handle() : NULL; } #+END_SRC *优势*: - 支持多实例(测试环境) - 清晰的生命周期管理 - 便于依赖注入 - 保持向后兼容 **** 1.2 日志系统 *问题*: 当前 =logger()= 输出简单,=fatal()= 直接退出 *解决方案*: 分级日志系统 #+BEGIN_SRC c // src/core/log.h typedef enum log_level_t { LOG_LEVEL_DEBUG = 0, LOG_LEVEL_INFO, LOG_LEVEL_WARN, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL } log_level_t; typedef struct log_handler_t { void (*write)(log_level_t level, const char *file, int line, const char *fmt, va_list args); log_level_t min_level; log_handler_t *next; } log_handler_t; // 日志API void log_init(log_level_t default_level); void log_cleanup(void); void log_add_handler(log_handler_t *handler); void log_remove_handler(log_handler_t *handler); // 便捷宏 #define LOG_DEBUG(fmt, ...) log_write(LOG_LEVEL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__) #define LOG_INFO(fmt, ...) log_write(LOG_LEVEL_INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__) #define LOG_WARN(fmt, ...) log_write(LOG_LEVEL_WARN, __FILE__, __LINE__, fmt, ##__VA_ARGS__) #define LOG_ERROR(fmt, ...) log_write(LOG_LEVEL_ERROR, __FILE__, __LINE__, fmt, ##__VA_ARGS__) #define LOG_FATAL(fmt, ...) log_write(LOG_LEVEL_FATAL, __FILE__, __LINE__, fmt, ##__VA_ARGS__) // 替代现有的 logger/fatal/warn #define logger LOG_INFO #define warn LOG_WARN #define fatal LOG_FATAL #+END_SRC **** 1.3 错误处理机制 *问题*: GError 使用不当,错误信息丢失 *解决方案*: 统一错误处理接口 #+BEGIN_SRC c // src/core/error.h typedef enum error_code_t { ERROR_NONE = 0, ERROR_NOMEM, ERROR_INVALID_ARG, ERROR_XCB_FAILED, ERROR_FILE_NOT_FOUND, ERROR_PARSE_FAILED, // ... 更多错误码 } error_code_t; typedef struct error_t { error_code_t code; char message[256]; const char *file; int line; } error_t; // 错误处理API void error_set(error_t **err, error_code_t code, const char *fmt, ...); void error_clear(error_t **err); const char *error_get_message(const error_t *err); // 错误传播宏 #define CHECK_ERROR(cond, err, code, fmt, ...) \ if (!(cond)) { \ error_set(err, code, fmt, ##__VA_ARGS__); \ return false; \ } #+END_SRC *** 第二层:数据抽象层 (Data Layer) **** 2.1 状态管理器 *问题*: 状态散落在多个模块,难以同步 *解决方案*: 统一状态管理接口 #+BEGIN_SRC c // src/core/state.h typedef enum state_type_t { STATE_MONITOR, STATE_CLIENT, STATE_TAG, STATUS_LAYOUT, STATE_CONFIG } state_type_t; typedef struct state_change_t { state_type_t type; void *old_state; void *new_state; } state_change_t; typedef void (*state_change_callback)(const state_change_t *change, void *user_data); typedef struct state_manager_t { // 状态变更监听器 state_change_callback *listeners; void **listener_data; size_t listener_count; // 状态存储 hash_table_t *states; } state_manager_t; // 状态管理API state_manager_t *state_manager_create(void); void state_manager_destroy(state_manager_t *mgr); void state_manager_notify(state_manager_t *mgr, const state_change_t *change); void state_manager_subscribe(state_manager_t *mgr, state_change_callback callback, void *user_data); // 状态访问 void *state_get(state_manager_t *mgr, state_type_t type); void state_set(state_manager_t *mgr, state_type_t type, void *data); #+END_SRC **** 2.2 配置抽象层 *问题*: 配置系统不统一,缺少热重载 *解决方案*: 分层配置系统 #+BEGIN_SRC c // src/config/config_layer.h typedef enum config_source_t { CONFIG_SOURCE_DEFAULT, // 编译时默认值 CONFIG_SOURCE_FILE, // 配置文件 CONFIG_SOURCE_XRESOURCE, // X资源数据库 CONFIG_SOURCE_RUNTIME, // 运行时API(最高优先级) } config_source_t; typedef struct config_value_t { config_source_t source; union { bool boolean; int integer; char *string; void *pointer; } value; } config_value_t; typedef struct config_layer_t { hash_table_t *values; // key -> config_value_t config_source_t source; bool readonly; } config_layer_t; typedef struct config_stack_t { config_layer_t **layers; size_t layer_count; } config_stack_t; // 配置API config_stack_t *config_stack_create(void); void config_stack_destroy(config_stack_t *stack); void config_stack_push_layer(config_stack_t *stack, config_source_t source); void config_stack_pop_layer(config_stack_t *stack); // 配置访问(自动从最高优先级层查找) bool config_get_bool(config_stack_t *stack, const char *key, bool *value); bool config_get_int(config_stack_t *stack, const char *key, int *value); bool config_get_string(config_stack_t *stack, const char *key, char **value); // 配置设置(总是设置到运行时层) bool config_set_bool(config_stack_t *stack, const char *key, bool value); bool config_set_int(config_stack_t *stack, const char *key, int value); bool config_set_string(config_stack_t *stack, const char *key, const char *value); // 配置热重载 bool config_reload_from_file(config_stack_t *stack, const char *filepath); #+END_SRC *** 第三层:服务抽象层 (Service Layer) **** 3.1 显示后端抽象 *问题*: XCB调用散落各处,难以测试,且无法支持 Wayland *解决方案*: 显示服务器无关的统一接口,支持 X11 和 Wayland #+BEGIN_SRC c // src/services/display_backend.h // 显示后端类型 typedef enum display_backend_type_t { DISPLAY_BACKEND_AUTO, // 自动检测 DISPLAY_BACKEND_X11, DISPLAY_BACKEND_WAYLAND } display_backend_type_t; // 统一的窗口表示(跨平台) typedef struct window_t { uint64_t id; // 平台无关的窗口ID void *platform_handle; // XCB window or wl_surface } window_t; // 几何信息 typedef struct rect_t { int32_t x, y; uint32_t width, height; } rect_t; // 输入事件 typedef struct input_event_t { enum { INPUT_KEY, INPUT_BUTTON, INPUT_MOTION, INPUT_AXIS } type; uint32_t time; uint32_t detail; // keycode or button number uint32_t state; // modifier state int32_t x, y; // cursor position int32_t axis; // scroll axis delta } input_event_t; // 渲染表面 typedef struct render_surface_t { void *handle; // cairo_surface_t* for X11, EGLSurface for Wayland uint32_t width, height; } render_surface_t; // 显示后端接口 typedef struct display_backend_t { const char *name; const char *version; // 生命周期 bool (*init)(wm_context_t *ctx); void (*cleanup)(void); // 事件处理 int (*get_fd)(void); // 获取事件文件描述符 bool (*dispatch_event)(void); // 分发单个事件 void (*flush)(void); // 刷新请求 // 屏幕信息 bool (*get_screen_geometry)(size_t screen_index, rect_t *geometry); size_t (*get_screen_count)(void); // 窗口操作 window_t (*create_window)(const rect_t *geometry); void (*destroy_window)(window_t window); void (*map_window)(window_t window); void (*unmap_window)(window_t window); // 窗口属性 typedef enum { WINDOW_PROPERTY_TITLE, WINDOW_PROPERTY_CLASS, WINDOW_PROPERTY_ROLE, WINDOW_PROPERTY_PID, WINDOW_PROPERTY_TYPE, WINDOW_PROPERTY_TRANSIENT_FOR, WINDOW_PROPERTY_SIZE_HINTS, WINDOW_PROPERTY_MOTIF_HINTS, WINDOW_PROPERTY_FULLSCREEN, WINDOW_PROPERTY_OPACITY, } window_property_t; bool (*get_window_property)(window_t window, window_property_t prop, void *data, size_t *size); bool (*set_window_property)(window_t window, window_property_t prop, const void *data, size_t size); // 窗口几何 bool (*configure_window)(window_t window, const rect_t *geometry); bool (*get_window_geometry)(window_t window, rect_t *geometry); void (*raise_window)(window_t window); void (*focus_window)(window_t window); // 输入处理 bool (*grab_keyboard)(window_t window); bool (*grab_pointer)(window_t window); void (*ungrab_keyboard)(void); void (*ungrab_pointer)(void); // 渲染集成 render_surface_t (*create_render_surface)(window_t window, uint32_t width, uint32_t height); void (*destroy_render_surface)(render_surface_t surface); cairo_t* (*create_cairo_context)(render_surface_t surface); // Wayland 特定:窗口状态(用于 xdg-shell) typedef enum { STATE_FLAG_FULLSCREEN = (1 << 0), STATE_FLAG_MAXIMIZED = (1 << 1), STATE_FLAG_ RESIZING = (1 << 2), STATE_FLAG_ACTIVATING = (1 << 3), } state_flag_t; bool (*set_window_state)(window_t window, uint32_t state_flags); bool (*set_window_bounds)(window_t window, const rect_t *bounds); // 平台特定扩展 void* (*get_platform_handle)(void); // xcb_connection_t* or wl_display* } display_backend_t; // 显示后端管理 display_backend_t *display_backend_create(display_backend_type_t type); bool display_backend_init(wm_context_t *ctx, display_backend_type_t type); void display_backend_cleanup(display_backend_t *backend); // X11 后端声明 extern display_backend_t x11_backend; // Wayland 后端声明(未来实现) extern display_backend_t wayland_backend; #+END_SRC *优势*: - 为 Wayland 移植奠定基础 - 显示逻辑与核心逻辑分离 - 便于使用 mock 后端进行测试 - 运行时可切换显示后端 *X11 后端实现*: #+BEGIN_SRC c // src/services/x11_backend.c #include #include #include typedef struct x11_backend_data_t { xcb_connection_t *conn; xcb_screen_t *screen; xcb_window_t root_window; xcb_atom_t wm_protocols; xcb_atom_t wm_delete_window; GHashTable *window_map; // uint64_t -> xcb_window_t } x11_backend_data_t; static bool x11_init(wm_context_t *ctx) { x11_backend_data_t *data = calloc(1, sizeof(x11_backend_data_t)); data->conn = xcb_connect(NULL, NULL); if (xcb_connection_has_error(data->conn)) { free(data); return false; } data->screen = xcb_setup_roots_iterator(xcb_get_setup(data->conn)).data; data->root_window = data->screen->root; // 初始化 atoms 和其他资源 // ... return true; } static window_t x11_create_window(const rect_t *geometry) { x11_backend_data_t *data = display_backend_get_data(&x11_backend); xcb_window_t xcb_win = xcb_generate_id(data->conn); // 创建窗口... return (window_t){ .id = (uint64_t)xcb_win, .platform_handle = (void *)(uintptr_t)xcb_win }; } // ... 其他 X11 实现 display_backend_t x11_backend = { .name = "x11", .version = "1.0", .init = x11_init, .cleanup = x11_cleanup, .create_window = x11_create_window, // ... 其他函数指针 }; #+END_SRC *Wayland 后端框架*: #+BEGIN_SRC c // src/services/wayland_backend.c #include typedef struct wayland_backend_data_t { struct wl_display *display; struct wl_compositor *compositor; struct wl_seat *seat; struct xdg_wm_base *xdg_wm_base; GHashTable *window_map; } wayland_backend_data_t; static bool wayland_init(wm_context_t *ctx) { wayland_backend_data_t *data = calloc(1, sizeof(wayland_backend_data_t)); data->display = wl_display_connect(NULL); if (!data->display) { free(data); return false; } // 注册全局对象监听器 wl_display_roundtrip(data->display); return true; } // ... 其他 Wayland 实现(未来工作) display_backend_t wayland_backend = { .name = "wayland", .version = "1.0", .init = wayland_init, // ... 其他函数指针 }; #+END_SRC **** 3.2 事件总线 *问题*: 事件处理直接耦合业务逻辑 *解决方案*: 发布-订阅事件系统 #+BEGIN_SRC c // src/services/event_bus.h typedef enum event_type_t { // 窗口事件 EVENT_WINDOW_CREATE, EVENT_WINDOW_DESTROY, EVENT_WINDOW_CONFIGURE, EVENT_WINDOW_FOCUS, // 监视器事件 EVENT_MONITOR_ADD, EVENT_MONITOR_REMOVE, EVENT_MONITOR_CHANGE, // 标签事件 EVENT_TAG_ADD, EVENT_TAG_REMOVE, EVENT_TAG_CHANGE, // 用户事件 EVENT_KEY_PRESS, EVENT_MOUSE_PRESS, EVENT_COMMAND, // 系统事件 EVENT_CONFIG_RELOAD, EVENT_RESTART, EVENT_EXIT } event_type_t; typedef struct event_t { event_type_t type; void *data; // 事件特定数据 void *source; // 事件源对象 } event_t; typedef void (*event_callback)(const event_t *event, void *user_data); typedef struct event_subscription_t { event_type_t type; event_callback callback; void *user_data; bool once; // 是否只触发一次 } event_subscription_t; typedef struct event_bus_t { event_subscription_t **subscriptions; size_t subscription_count; size_t capacity; } event_bus_t; // 事件总线API event_bus_t *event_bus_create(void); void event_bus_destroy(event_bus_t *bus); // 订阅事件 event_subscription_t *event_bus_subscribe(event_bus_t *bus, event_type_t type, event_callback callback, void *user_data); void event_bus_unsubscribe(event_bus_t *bus, event_subscription_t *sub); // 发布事件 void event_bus_publish(event_bus_t *bus, const event_t *event); // 便捷宏 #define EVENT_SUBSCRIBE(bus, type, callback, data) \ event_bus_subscribe(bus, type, callback, data) #define EVENT_PUBLISH(bus, type, data) \ event_bus_publish(bus, &(event_t){ .type = type, .data = data }) #+END_SRC **** 3.3 插件系统 *问题*: 扩展功能需要修改核心代码 *解决方案*: 轻量级插件接口 #+BEGIN_SRC c // src/services/plugin.h typedef struct plugin_t { char *name; char *version; void *handle; // dlopen句柄 // 生命周期 bool (*init)(wm_context_t *ctx); void (*cleanup)(void); // 事件处理 void (*on_event)(const event_t *event); // 配置 bool (*set_config)(const char *key, const char *value); } plugin_t; typedef struct plugin_manager_t { plugin_t **plugins; size_t plugin_count; event_bus_t *event_bus; } plugin_manager_t; // 插件管理API plugin_manager_t *plugin_manager_create(event_bus_t *bus); void plugin_manager_destroy(plugin_manager_t *mgr); // 插件加载 bool plugin_manager_load(plugin_manager_t *mgr, const char *path); bool plugin_manager_unload(plugin_manager_t *mgr, const char *name); // 插件API(供插件实现者使用) void plugin_register(plugin_t *plugin); void plugin_unregister(const char *name); // 插件宏(简化插件开发) #define PLUGIN_EXPORT(name, version, init_fn, cleanup_fn) \ __attribute__((used)) plugin_t *_plugin_get_info(void) { \ static plugin_t plugin = { \ .name = name, \ .version = version, \ .init = init_fn, \ .cleanup = cleanup_fn \ }; \ return &plugin; \ } #+END_SRC *** 第四层:业务抽象层 (Business Layer) **** 4.1 客户端抽象 *问题*: client.c 职责过多,难以维护 *解决方案*: 客户端接口抽象 #+BEGIN_SRC c // src/business/client_interface.h // 客户端状态机 typedef enum client_state_t { CLIENT_STATE_NEW, CLIENT_STATE_NORMAL, CLIENT_STATE_FLOATING, CLIENT_STATE_FULLSCREEN, CLIENT_STATE_MAXIMIZED, CLIENT_STATE_MINIMIZED, CLIENT_STATE_DOCK, CLIENT_STATE_DYING } client_state_t; // 客户端接口 typedef struct client_interface_t { // 生命周期 client_t* (*create)(xcb_window_t window); void (*destroy)(client_t *client); // 状态管理 client_state_t (*get_state)(const client_t *client); bool (*set_state)(client_t *client, client_state_t new_state); // 几何管理 bool (*set_geometry)(client_t *client, const rect_t *geometry); rect_t (*get_geometry)(const client_t *client); // 焦点管理 bool (*focus)(client_t *client); bool (*is_focused)(const client_t *client); // 属性管理 bool (*set_property)(client_t *client, const char *key, void *value); void* (*get_property)(const client_t *client, const char *key); // 渲染 bool (*needs_redraw)(const client_t *client); void (*draw)(client_t *client, cairo_t *cr); } client_interface_t; // 客户端管理器 typedef struct client_manager_t { client_interface_t *iface; list_t *clients; // 所有客户端 hash_table_t *window_map; // window -> client } client_manager_t; // 客户端管理API client_manager_t *client_manager_create(client_interface_t *iface); void client_manager_destroy(client_manager_t *mgr); client_t *client_manager_add(client_manager_t *mgr, xcb_window_t window); bool client_manager_remove(client_manager_t *mgr, client_t *client); client_t *client_manager_find(client_manager_t *mgr, xcb_window_t window); #+END_SRC **** 4.2 布局引擎抽象 *问题*: 布局系统已经设计良好,但缺少插件化 *解决方案*: 布局插件接口 #+BEGIN_SRC c // src/business/layout_engine.h typedef struct layout_context_t { tag_t *tag; rect_t workarea; client_t **clients; size_t client_count; } layout_context_t; typedef struct layout_algorithm_t { const char *name; const char *symbol; // 布局计算 void (*arrange)(const layout_context_t *ctx, rect_t *geometries); // 可选:预览布局(不实际应用) void (*preview)(const layout_context_t *ctx, rect_t *geometries); // 可选:布局参数 bool (*set_param)(const char *key, void *value); } layout_algorithm_t; typedef struct layout_engine_t { layout_algorithm_t **algorithms; size_t algorithm_count; layout_algorithm_t *default_algorithm; } layout_engine_t; // 布局引擎API layout_engine_t *layout_engine_create(void); void layout_engine_destroy(layout_engine_t *engine); bool layout_engine_register(layout_engine_t *engine, layout_algorithm_t *algo); bool layout_engine_unregister(layout_engine_t *engine, const char *name); layout_algorithm_t *layout_engine_find(layout_engine_t *engine, const char *name); void layout_engine_arrange(layout_engine_t *engine, const layout_context_t *ctx); // 便捷宏:定义布局算法 #define LAYOUT_ALGORITHM(name, symbol, arrange_fn) \ static layout_algorithm_t _layout_##name = { \ .name = #name, \ .symbol = symbol, \ .arrange = arrange_fn \ }; \ __attribute__((constructor)) \ static void _layout_register_##name(void) { \ layout_engine_register(layout_engine_get_default(), &_layout_##name); \ } #+END_SRC **** 4.3 操作抽象 *问题*: 操作系统已经设计良好,可以增强 *解决方案*: 命令模式增强 #+BEGIN_SRC c // src/business/command.h typedef enum command_arg_type_t { COMMAND_ARG_NONE, COMMAND_ARG_INT, COMMAND_ARG_STRING, COMMAND_ARG_BOOLEAN } command_arg_type_t; typedef struct command_arg_t { command_arg_type_t type; union { int integer; char *string; bool boolean; } value; } command_arg_t; typedef struct command_result_t { bool success; char *message; void *data; // 可选的返回数据 void (*data_cleanup)(void *data); } command_result_t; typedef struct command_t { const char *name; const char *description; // 参数定义 command_arg_type_t *arg_types; size_t arg_count; // 执行函数 command_result_t (*execute)(wm_context_t *ctx, const command_arg_t *args, size_t arg_count); // 可选:自动完成 char* (*complete)(const char *prefix, size_t arg_index); } command_t; typedef struct command_registry_t { hash_table_t *commands; // name -> command_t } command_registry_t; // 命令注册API command_registry_t *command_registry_create(void); void command_registry_destroy(command_registry_t *registry); bool command_registry_register(command_registry_t *registry, command_t *cmd); bool command_registry_unregister(command_registry_t *registry, const char *name); command_result_t command_execute(command_registry_t *registry, wm_context_t *ctx, const char *name, const command_arg_t *args, size_t arg_count); // 便捷宏 #define COMMAND_REGISTER(registry, name, fn) \ command_registry_register(registry, &(command_t){ \ .name = name, \ .execute = fn \ }) #+END_SRC *** 第五层:UI抽象层 (Presentation Layer) **** 5.1 渲染器抽象 *问题*: 渲染逻辑散落各处,难以扩展 *解决方案*: 统一渲染接口 #+BEGIN_SRC c // src/ui/renderer.h typedef struct render_context_t { cairo_t *cr; rect_t viewport; color_scheme_t *colors; } render_context_t; typedef struct renderer_t { const char *name; // 初始化 bool (*init)(wm_context_t *ctx); // 清理 void (*cleanup)(void); // 渲染 void (*render)(const render_context_t *ctx, void *data); // 尺寸计算 void (*measure)(const render_context_t *ctx, void *data, size_t *width, size_t *height); } renderer_t; typedef struct renderer_manager_t { renderer_t **renderers; size_t renderer_count; } renderer_manager_t; // 渲染器管理API renderer_manager_t *renderer_manager_create(void); void renderer_manager_destroy(renderer_manager_t *mgr); bool renderer_manager_register(renderer_manager_t *mgr, renderer_t *r); bool renderer_manager_unregister(renderer_manager_t *mgr, const char *name); renderer_t *renderer_manager_find(renderer_manager_t *mgr, const char *name); void renderer_manager_render(renderer_manager_t *mgr, const char *name, const render_context_t *ctx, void *data); #+END_SRC **** 5.2 状态栏组件系统 *问题*: 状态栏已经设计良好,可以组件化 *解决方案*: 组件化状态栏 #+BEGIN_SRC c // src/ui/statusbar_component.h typedef struct statusbar_component_t { const char *name; size_t preferred_width; size_t preferred_height; // 渲染 void (*render)(const render_context_t *ctx, void *data); // 尺寸计算 void (*measure)(const render_context_t *ctx, void *data, size_t *width, size_t *height); // 事件处理 void (*on_click)(void *data, int x, int y); void (*on_scroll)(void *data, int delta); // 生命周期 void (*init)(wm_context_t *ctx, void **data); void (*cleanup)(void *data); } statusbar_component_t; typedef struct statusbar_t { statusbar_component_t **components; void **component_data; size_t component_count; // 布局管理 enum { STATUSBAR_LAYOUT_LEFT_TO_RIGHT, STATUSBAR_LAYOUT_RIGHT_TO_LEFT } layout_direction; } statusbar_t; // 状态栏组件API statusbar_t *statusbar_create(void); void statusbar_destroy(statusbar_t *bar); bool statusbar_add_component(statusbar_t *bar, statusbar_component_t *comp); bool statusbar_remove_component(statusbar_t *bar, const char *name); void statusbar_render(statusbar_t *bar, const render_context_t *ctx); void statusbar_handle_event(statusbar_t *bar, const event_t *event); // 预定义组件 extern statusbar_component_t statusbar_clock_component; extern statusbar_component_t statusbar_cpu_component; extern statusbar_component_t statusbar_memory_component; extern statusbar_component_t statusbar_network_component; #+END_SRC ** 架构分层图 #+BEGIN_EXAMPLE ┌─────────────────────────────────────────────────────────────┐ │ UI 抽象层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 渲染器管理 │ │ 状态栏组件 │ │ 通知系统 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ ┌─────────────────────────────────────────────────────────────┐ │ 业务抽象层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 客户端接口 │ │ 布局引擎 │ │ 命令系统 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ ┌─────────────────────────────────────────────────────────────┐ │ 服务抽象层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 显示后端 │ │ 事件总线 │ │ 插件系统 │ │ │ │ (X11/Wayland)│ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ ┌─────────────────────────────────────────────────────────────┐ │ 数据抽象层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 状态管理器 │ │ 配置系统 │ │ 资源缓存 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ ┌─────────────────────────────────────────────────────────────┐ │ 基础设施抽象层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 上下文管理 │ │ 日志系统 │ │ 错误处理 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ #+END_EXAMPLE ** 实施路径 *** 阶段1:基础设施层 (2-3周) 1. *上下文管理器* - 创建 =wm_context_t= - 修改现有代码使用上下文 - 保持向后兼容宏 2. *日志系统* - 实现 =log.h/c= - 替换所有 =logger/fatal/warn= - 添加文件输出 handler 3. *错误处理* - 实现 =error.h/c= - 修复 GError 使用 - 添加错误恢复机制 *** 阶段2:数据抽象层 (3-4周) 1. *状态管理器* - 实现 =state_manager_t= - 迁移关键状态到统一管理 - 添加状态变更监听 2. *配置系统* - 实现配置栈 - 支持配置文件热重载 - 添加配置验证 *** 阶段3:服务抽象层 (4-6周) 1. *显示后端抽象* - 定义显示后端统一接口 - 实现 X11 后端(迁移现有 XCB 调用) - 创建 Wayland 后端框架(仅接口定义) - 实现 Mock 后端用于单元测试 - 修改核心逻辑使用显示后端接口 - 添加后端自动检测和运行时切换 2. *事件总线* - 实现发布-订阅系统 - 迁移现有事件处理 - 添加事件日志 3. *插件系统* - 实现插件加载器 - 定义插件接口 - 创建示例插件 *** 阶段4:业务抽象层 (6-8周) 1. *客户端重构* - 定义客户端接口 - 实现状态机 - 拆分 client.c 2. *布局引擎* - 提取布局算法 - 支持动态注册 - 添加布局预览 3. *命令系统* - 统一命令接口 - 支持参数验证 - 添加自动完成 *** 阶段5:UI抽象层 (4-6周) 1. *渲染器管理* - 统一渲染接口 - 支持多种渲染器 - 添加渲染缓存 2. *状态栏组件化* - 提取组件接口 - 实现预定义组件 - 支持自定义组件 ** 向后兼容策略 1. *渐进式迁移* - 新旧API并存 - 使用宏提供兼容层 - 标记旧API为deprecated 2. *编译时选项* #+BEGIN_SRC c #ifdef USE_NEW_ARCH // 使用新API #else // 使用旧API #endif #+END_SRC 3. *运行时切换* - 支持命令行参数选择架构 - 便于性能对比和问题定位 ** 测试策略 1. *单元测试* - 每个抽象层独立测试 - 使用mock对象隔离依赖 2. *集成测试* - 测试层间交互 - 端到端场景测试 3. *性能测试* - 对比新旧架构性能 - 内存使用分析 - 响应时间测试 ** 预期收益 *** 可维护性提升 - 清晰的职责划分 - 松耦合的模块设计 - 易于定位和修复问题 *** 可扩展性提升 - 插件化架构 - 组件化UI - 动态配置系统 *** 可测试性提升 - 依赖注入支持 - Mock对象友好 - 隔离测试环境 *** 用户体验提升 - 配置热重载 - 插件生态 - 更好的错误提示 这个抽象层设计既保持了ZDWM的简洁高效,又大幅提升了可维护性和可扩展性,为项目的长期发展奠定坚实基础。 ** 显示后端抽象与 Wayland 支持 *** 设计目标 通过引入显示后端抽象层,实现以下目标: - 为 Wayland 移植奠定基础,适应显示服务器技术演进 - 显示逻辑与核心业务逻辑完全分离 - 支持运行时后端切换,用户可选择 X11 或 Wayland - 便于使用 Mock 后端进行单元测试 *** 架构优势 1. *显示服务器无关性*: 核心窗口管理逻辑不依赖特定显示服务器 2. *渐进式迁移*: 先完善 X11 后端,再逐步实现 Wayland 后端 3. *性能无损*: 通过编译时优化和内联函数保持高性能 4. *测试友好*: Mock 后端使单元测试更简单 *** X11 后端实现重点 #+BEGIN_SRC c // X11 后端的核心职责 - 管理 xcb_connection_t 和 xcb_screen_t - 窗口生命周期管理(创建、销毁、映射、取消映射) - ICCCM/EWMH 协议实现 - 事件转换(XCB 事件 → 通用 display_event_t) - Cairo 集成(cairo_xcb_surface_t) - 输入设备抓取(键盘、鼠标) #+END_SRC *** Wayland 后端实现路线图 *阶段1:基础框架(未来 3-6 个月)* - 实现 Wayland 客户端协议绑定 - 支持 wl_display, wl_compositor, wl_shm - 实现 xdg-shell 基础功能 - 窗口创建和基本管理 *阶段2:核心功能(未来 6-12 个月)* - 完整的 xdg-shell 支持 - 输入事件处理(wl_seat, wl_pointer, wl_keyboard) - 表面和帧回调(wl_surface, wl_callback) - EGL/渲染集成 *阶段3:高级特性(未来 12-18 个月)* - xdg-activation 协议(焦点管理) - xdg-decoration 协议(服务器端装饰) - wl_output 多显示器支持 - Layer-shell 支持(面板、覆盖层) *** 后端切换策略 1. *编译时选择*(零成本抽象) #+BEGIN_SRC c #if defined(DISPLAY_BACKEND_X11) #define DISPLAY_CALL(func, ...) x11_##func(__VA_ARGS__) #elif defined(DISPLAY_BACKEND_WAYLAND) #define DISPLAY_CALL(func, ...) wayland_##func(__VA_ARGS__) #endif #+END_SRC 2. *运行时切换*(灵活性) #+BEGIN_SRC c // 通过环境变量选择 export ZDWM_BACKEND=x11 // 或 wayland // 通过命令行参数选择 zdwm --backend=x11 zdwm --backend=wayland // 自动检测 if (getenv("WAYLAND_DISPLAY")) { backend = &wayland_backend; } else if (getenv("DISPLAY")) { backend = &x11_backend; } #+END_SRC *** 配置示例 #+BEGIN_SRC c // 配置文件支持 typedef struct display_config_t { display_backend_type_t backend; struct { bool enable_ssd; // 服务器端装饰(X11) bool enable_csd; // 客户端装饰(Wayland) } decoration; struct { bool enable_vsync; bool use_egl; // EGL vs SHM(Wayland) } rendering; } display_config_t; #+END_SRC *** 兼容性考虑 1. *向后兼容*: 保持现有 XCB 调用接口,通过宏迁移到新接口 2. *功能对等*: 确保 X11 和 Wayland 后端功能一致性 3. *性能保持*: Wayland 后端性能应不低于 X11 后端 *** 测试策略 1. *Mock 后端测试* #+BEGIN_SRC c // 用于单元测试的模拟后端 static display_backend_t mock_backend = { .name = "mock", .init = mock_init, .create_window = mock_create_window, // ... 其他实现 }; // 测试核心逻辑 void test_client_management_with_mock_backend() { wm_context_t *ctx = wm_context_create(DISPLAY_BACKEND_MOCK); // 测试逻辑... } #+END_SRC 2. *双后端集成测试* - 使用相同测试用例验证 X11 和 Wayland 后端 - 确保行为一致性 *** 预期收益 1. *未来兼容性*: 为 Wayland 移植奠定基础 2. *架构清晰*: 显示逻辑与核心逻辑分离 3. *测试友好*: Mock 后端简化单元测试 4. *性能无损*: 通过编译时优化保持高性能 5. *用户选择*: 用户可根据需求选择 X11 或 Wayland 这个显示后端抽象设计确保了 ZDWM 能够适应显示服务器技术的演进,同时保持当前的优秀性能和稳定性。