You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

X11 DestroyNotify返回错误window参数 XCB reparenting窗口管理器开发问题

解决方案

核心问题排查

  • 首先检查你是否取错了DestroyNotify的字段:xcb_destroy_notify_event_t包含两个窗口相关字段,event是事件投递的目标窗口(即你设置了监听掩码的窗口),window才是实际被销毁的窗口,你需要匹配的是ev->window而非ev->event。
  • 确认你在reparent客户端窗口时,给客户端原始窗口显式设置了XCB_EVENT_MASK_STRUCTURE_NOTIFY掩码,只有设置了该掩码,你才能收到客户端顶层窗口本身的销毁事件,此时ev->window就会和你存储的client.window完全匹配。
  • 你日志中出现的两次非预期DestroyNotify是客户端自行创建的子窗口销毁事件,这类窗口不属于你的管理列表,直接忽略即可,客户端顶层窗口销毁时你会收到对应事件。

实现修正

你需要单独实现DestroyNotify的处理逻辑,不要仅依赖UnmapNotify做取消管理,参考实现如下:

void handle_destroy_notify(xcb_destroy_notify_event_t *ev) {
    // 优先直接匹配管理的客户端窗口和框架窗口
    for (auto it = clients.begin(); it != clients.end(); ++it) {
        if (it->window == ev->window) {
            xcb_unmap_window(conn, it->frame);
            xcb_destroy_window(conn, it->frame); // 销毁自行创建的框架窗口避免资源泄漏
            clients.erase(it);
            return;
        }
        if (it->frame == ev->window) {
            clients.erase(it);
            return;
        }
    }

    // 兜底逻辑:遍历父窗口层级匹配,处理子窗口销毁触发的通知
    xcb_window_t current = ev->window;
    while (current != root_window && current != XCB_WINDOW_NONE) {
        xcb_query_tree_cookie_t cookie = xcb_query_tree(conn, current);
        xcb_query_tree_reply_t *reply = xcb_query_tree_reply(conn, cookie, nullptr);
        if (!reply) break;
        xcb_window_t parent = reply->parent;
        free(reply);

        for (auto it = clients.begin(); it != clients.end(); ++it) {
            if (it->window == parent) {
                xcb_unmap_window(conn, it->frame);
                xcb_destroy_window(conn, it->frame);
                clients.erase(it);
                return;
            }
        }
        current = parent;
    }
}

额外注意事项

  • Reparent客户端窗口后,需要重新设置一次客户端窗口的事件掩码,避免客户端自身的掩码设置覆盖了你添加的StructureNotify监听
  • 取消管理客户端时,务必销毁你自行创建的frame窗口,否则会产生僵尸窗口占用X服务器资源

内容的提问来源于stack exchange,提问作者gsb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:09:01