简体   繁体   English

XCB 获取所有根事件

[英]XCB get all root events

I'm writing an xcb app that tooks all root events.我正在编写一个处理所有根事件的 xcb 应用程序。 I wrote this code:我写了这段代码:

#include <stdio.h>
#include <stdlib.h>

#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>

int main(void) {
    xcb_connection_t *connection = xcb_connect(NULL, NULL);
    xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
    xcb_generic_event_t *event;

    const uint32_t values[] = {
        XCB_EVENT_MASK_BUTTON_PRESS
    };

    xcb_change_window_attributes(connection, screen->root, XCB_CW_EVENT_MASK, values);
    xcb_aux_sync(connection);
    xcb_flush(connection);

    while ((event = xcb_wait_for_event(connection))) {
        switch (event->response_type & ~0x80) {
            case XCB_EXPOSE: {
                puts("expose");
                break;
            }
            case XCB_BUTTON_PRESS: {
                puts("mouse clicked");
                break;
            }
        }
        free(event);
    }

    xcb_disconnect(connection);

    return 0;
}

But this doesn't work if I need to get events on DISPLAY:0, how can I do this?但是,如果我需要在 DISPLAY:0 上获取事件,这不起作用,我该怎么做? If I try to check what xcb_poll_for_event returns, it returns NULL because another window manager is running, so I need to get access to the running wm.如果我尝试检查xcb_poll_for_event返回的内容,它会返回 NULL 因为另一个 window 管理器正在运行,所以我需要访问正在运行的 wm。

xcb_poll_for_event is the non-blocking alternative to xcb_wait_for_event . xcb_poll_for_eventxcb_wait_for_event的非阻塞替代方案。 The difference is that it returns NULL if there are no queued events, while xcb_wait_for_event blocks until an event is received.不同之处在于,如果没有排队的事件,它会返回 NULL,而xcb_wait_for_event阻塞,直到收到事件。 If you are calling xcb_poll_for_event , a return value of NULL is not (at least directly) because another window manager is running.如果您正在调用xcb_poll_for_event ,则返回值 NULL 不是(至少直接),因为另一个 window 管理器正在运行。 If your code does not need to run code outside of the event loop once the event loop has started, you might be looking for xcb_wait_for_event .如果您的代码在事件循环开始后不需要在事件循环之外运行代码,您可能正在寻找xcb_wait_for_event Otherwise, continuing with xcb_poll_for_event , you will want to continue to poll for events until you receive the events you are interested in (ignoring NULL return values).否则,继续使用xcb_poll_for_event ,您将需要继续轮询事件,直到收到您感兴趣的事件(忽略 NULL 返回值)。

From my understanding of the XCB and Xlib documentation, it is possible that the window manager could be preventing your client from receiving button press events by setting the XCB_CW_DONT_PROPAGATE mask.根据我对 XCB 和 Xlib 文档的理解,window 管理器可能会通过设置XCB_CW_DONT_PROPAGATE掩码来阻止您的客户端接收按钮按下事件。 This might cause your client to not be able to receive button press events on the root window.这可能会导致您的客户端无法在根 window 上接收按钮按下事件。 The window manager registering to receive button press events on the root window shouldn't stop your client from receiving these same button press events unless XCB_CW_DONT_PROPAGATE is indeed set.注册以接收根 window 上的按钮按下事件的 window 管理器不应阻止您的客户端接收这些相同的按钮按下事件,除非确实设置XCB_CW_DONT_PROPAGATE

While in your code example you are only registering for the XCB_BUTTON_PRESS event mask, your question says you want to receive all events on the root window.虽然在您的代码示例中您只注册XCB_BUTTON_PRESS事件掩码,但您的问题是您希望接收根 window 上的所有事件。 This is not fully possible when another window manager is running: an X window manager is, by definition, the one client that can register for substructure redirection on the root window (this is not unique to the root window; only one client can register for substructure redirection on any window). This is not fully possible when another window manager is running: an X window manager is, by definition, the one client that can register for substructure redirection on the root window (this is not unique to the root window; only one client can register for任何窗口上的子结构重定向)。 Substructure redirection is required for your client to receive the following events on the root window:您的客户端需要子结构重定向才能在根 window 上接收以下事件:

  • XCB_CIRCULATE_REQUEST
  • XCB_CONFIGURE_REQUEST
  • XCB_MAP_REQUEST

However, to my knowledge, your client should be able to receive all other events that the window manager has not restricted the generation or propagation of.但是,据我所知,您的客户端应该能够接收 window 管理器未限制生成或传播的所有其他事件。 If you wish for your client to all events by becoming a window manager, then you can register for the XCB_SUBSTRUCTURE_REDIRECT and XCB_SUBSTRUCTURE_NOTIFY event masks on the root window yourself.如果您希望通过成为 window 经理来让您的客户参与所有事件,那么您可以自己在根 window 上注册XCB_SUBSTRUCTURE_REDIRECTXCB_SUBSTRUCTURE_NOTIFY事件掩码。

Do note, however, that if your client is not the first to attempt to register for substructure redirection on the root window it will not be granted substructure redirection.但是请注意,如果您的客户端不是第一个尝试在根 window 上注册子结构重定向的客户端,则不会授予子结构重定向。 A typical window manager will crash in response to not being granted substructure redirection on the root window, printing a message explaining that another window manager is running.典型的 window 管理器将响应未在根 window 上授予子结构重定向而崩溃,并打印一条消息,说明另一个 window 管理器正在运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM