XCB中启用OVERRIDE_REDIRECT时事件处理异常问题咨询
问题根因
你的代码不存在配置遗漏,核心错误是win_values数组的元素顺序不符合XCB的接口规则,导致OVERRIDE_REDIRECT属性实际没有被设置为1。
XCB的窗口创建接口中,mask参数通过位标记声明要设置的窗口属性,对应的win_values数组必须严格按照xcb_cw_t枚举值从小到大的顺序排列,和你在mask中写位或运算的顺序无关。
错误细节
你当前mask中包含的四个属性,按枚举值从小到大排序应为:
XCB_CW_BACK_PIXEL(枚举值2)XCB_CW_BORDER_PIXEL(枚举值8)XCB_CW_OVERRIDE_REDIRECT(枚举值512)XCB_CW_EVENT_MASK(枚举值2048)
但你代码里的win_values把XCB_EVENT_MASK_EXPOSURE放在第三位、1放在第四位,相当于:
- 给
OVERRIDE_REDIRECT传的是事件掩码值,不是1,因此属性不生效 - 给
EVENT_MASK传的是1,对应XCB_EVENT_MASK_KEY_PRESS,根本不是你需要的暴露事件
你测试时去掉事件掩码配置后OVERRIDE_REDIRECT生效,本质是因为数组只剩三个元素,第三个元素的1刚好匹配到OVERRIDE_REDIRECT的位置,但此时你没有设置事件掩码,自然收不到需要的窗口事件。
修正代码
只需要调整win_values的元素顺序即可,不需要额外配置:
// Create a window xcb_window_t window = xcb_generate_id(connection); uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; uint32_t win_values[] = { default_screen->white_pixel, // 对应XCB_CW_BACK_PIXEL 0, // 对应XCB_CW_BORDER_PIXEL 1, // 对应XCB_CW_OVERRIDE_REDIRECT,设为1绕过窗口管理器 XCB_EVENT_MASK_EXPOSURE // 对应XCB_CW_EVENT_MASK,设置需要监听的事件 }; xcb_create_window( connection, default_screen->root_depth, window, default_screen->root, 0, 0, 500, 500, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, default_screen->root_visual, mask, win_values );
注意事项
后续如果需要新增其他XCB_CW_*属性,一定要先确认对应枚举值的大小,严格按升序排列value数组元素,这类参数错位问题不会触发接口报错,排查成本很高。
内容的提问来源于stack exchange,提问作者Cathal OGrady
相关产品推荐
相关产品推荐

