创建Linux XCB无框架窗口

创建Linux XCB无框架窗口,linux,x11,xcb,Linux,X11,Xcb,我想通过XCB创建一个无框架窗口。 我将XCB_CW_OVERRIDE_重定向掩码设置为true。 它可以工作,但键盘事件无法工作 uint32_t value_mask, value_list[32]; window = xcb_generate_id(connection); value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; value_list[0] = screen->black_pixel; value_list[1] =

我想通过XCB创建一个无框架窗口。 我将XCB_CW_OVERRIDE_重定向掩码设置为true。 它可以工作,但键盘事件无法工作

uint32_t value_mask, value_list[32];

window = xcb_generate_id(connection);

value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
value_list[0] = screen->black_pixel;
value_list[1] =
    XCB_EVENT_MASK_KEY_RELEASE |
    XCB_EVENT_MASK_KEY_PRESS |
    XCB_EVENT_MASK_EXPOSURE |
    XCB_EVENT_MASK_STRUCTURE_NOTIFY |
    XCB_EVENT_MASK_POINTER_MOTION |
    XCB_EVENT_MASK_BUTTON_PRESS |
    XCB_EVENT_MASK_BUTTON_RELEASE;

if (settings.fullscreen)
{
    width = destWidth = screen->width_in_pixels;
    height = destHeight = screen->height_in_pixels;
}

xcb_create_window(connection,
    XCB_COPY_FROM_PARENT,
    window, screen->root,
    0, 0, width, height, 0,
    XCB_WINDOW_CLASS_INPUT_OUTPUT,
    screen->root_visual,
    value_mask, value_list);


const uint32_t values[] ={true,};
xcb_change_window_attributes (connection, window, XCB_CW_OVERRIDE_REDIRECT, values);

有人知道如何通过xcb创建一个无框架窗口,而不存在按键事件错误吗?

如果您希望覆盖重定向窗口具有输入焦点,则必须显式地
xcb\u设置\u输入\u焦点(连接,窗口)。由于输入焦点只能指定给可视窗口,因此必须在映射窗口后进行

在X11中,键盘事件(基本上)发送到当前具有输入焦点的窗口。通常,输入焦点由窗口管理器管理。由于您正在创建一个覆盖重定向窗口,因此窗口管理器看不到您的窗口,无法对其进行聚焦。因此,您必须自己聚焦窗口。请注意,WM仍然可以将焦点提供给其他窗口,因此您的窗口会失去焦点

实际上,我不确定根据ICCCM对焦窗口的正确方法是什么。我没有找到一个快速搜索“覆盖重定向”或“焦点”的相关部分


我的直觉是,处理这个问题的正确方法是不要使用覆盖重定向窗口。

如果你真的只是想摆脱WM的窗口装饰,你应该使用motif提示来请求。OverrideRedirect做了一些不同的事情(而且做的更多)。在GTK和Qt中,上下文菜单是override重定向窗口,只需抓取键盘和鼠标即可获得输入。因此,如果您的应用程序在其菜单可见时恰好遇到断点,则您有一个问题。。。(有很多方法可以取消RAB,但您仍然需要做一些事情来摆脱这种情况。)xcb_map_窗口(连接,窗口);设置输入焦点(连接、输入焦点、指针根、窗口、当前时间);解决这个问题。非常感谢。大家好,欢迎来到Stack Overflow。通常,在发布答案时,围绕答案的更多细节是有必要的。在本例中:发布的代码如何满足提问者的要求?有一个解决方案很好,但更好的是知道它是如何工作的以及为什么工作的。这可能会有帮助:
xcb_map_window(connection, window); 
xcb_set_input_focus(connection,XCB_INPUT_FOCUS_POINTER_ROOT,window,XCB_CURRENT_TIME);