XCB多窗口事件区分方法及上下文管理器替代方案咨询
XCB多窗口事件区分与上下文管理问题解答
1. 单个连接即可区分事件来源,无需建立多连接
所有XCB事件结构体(比如xcb_expose_event_t、xcb_button_press_event_t等)都包含window字段,这个字段就是触发事件的窗口ID。你只需要在创建窗口时保存每个窗口的ID(比如存入数组或哈希表),在事件循环里取出事件的window值,和你保存的窗口ID对比,就能精准判断事件来自哪个窗口。
示例代码片段:
// 提前保存创建好的窗口ID xcb_window_t win1, win2; xcb_generic_event_t *event; while ((event = xcb_wait_for_event(conn))) { switch (event->response_type & ~0x80) { case XCB_EXPOSE: { xcb_expose_event_t *expose = (xcb_expose_event_t *)event; if (expose->window == win1) { // 处理窗口1的暴露事件 } else if (expose->window == win2) { // 处理窗口2的暴露事件 } break; } // 其他事件类型(点击、输入等)同理处理 } free(event); }
2. XCB无内置Context Manager,但可自行实现
XCB确实没有Xlib那种直接的窗口上下文管理接口,但你可以用哈希表(比如C语言常用的uthash库,或者自行实现简单的键值对映射)来关联窗口ID和自定义的上下文数据(比如每个窗口的状态、控件信息等结构体指针)。
实现思路:
- 创建窗口后,将窗口ID作为键,自定义上下文结构体指针作为值,存入哈希表
- 事件到来时,根据事件的
window字段从哈希表中取出对应的上下文 - 窗口销毁时,从哈希表中移除对应条目,避免内存泄漏
示例思路(基于uthash):
#include "uthash.h" typedef struct { xcb_window_t win_id; // 自定义上下文字段,比如窗口标题、尺寸、状态等 char title[64]; int width, height; UT_hash_handle hh; } WinContext; WinContext *contexts = NULL; // 添加窗口上下文 void add_win_context(xcb_window_t win_id, const char *title, int w, int h) { WinContext *ctx = malloc(sizeof(WinContext)); ctx->win_id = win_id; strncpy(ctx->title, title, sizeof(ctx->title)-1); ctx->width = w; ctx->height = h; HASH_ADD_INT(contexts, win_id, ctx); } // 根据窗口ID查找上下文 WinContext *find_win_context(xcb_window_t win_id) { WinContext *ctx; HASH_FIND_INT(contexts, &win_id, ctx); return ctx; } // 事件处理时使用上下文 xcb_generic_event_t *event; while ((event = xcb_wait_for_event(conn))) { xcb_window_t event_win = ((xcb_window_event_t *)event)->window; WinContext *ctx = find_win_context(event_win); if (ctx) { // 基于上下文处理事件,比如根据窗口标题区分逻辑 printf("Handling event for window: %s\n", ctx->title); } free(event); }
内容的提问来源于stack exchange,提问作者nightingazer
相关产品推荐
相关产品推荐

