如何订阅不同的事件并在 xcb 演示应用程序中调试它们?

问题描述 投票:0回答:1

我正在尝试创建一个与 xcb 库函数交互的简单应用程序。我的目标是模拟简单窗口管理器的行为。据我了解,我需要在根窗口上设置子结构重定向,然后侦听该窗口上的特定事件,以便按照我想要的方式组织其顶级窗口。问题是,我只是不知道如何测试我想出的解决方案。

这是负责执行我所解释的操作的代码:

#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>

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

    /* Subscribing to the desired events */
    uint32_t mask = XCB_CW_EVENT_MASK | 
                    XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | 
                    XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
    uint32_t values[3] = { XCB_KEY_PRESS, 1, 1 };

    /* This applies the values and mask to the root window I think */
    xcb_change_window_attributes(connection, screen->root, mask, values);

    xcb_generic_event_t *ev;
    while( (ev = xcb_wait_for_event(connection)) ) {
        switch(ev->response_type & ~0x80) {
            case XCB_KEY_PRESS: {
                xcb_key_press_event_t *ev = (xcb_key_press_event_t *)ev;

                if(ev->state & XCB_MOD_MASK_1) {
                    printf("Pressed the Alt key modifier\n");
                }
                printf("Key pressed: Keycode %d\n", ev->detail);

                break;
            }
            case XCB_CREATE_NOTIFY: {
                printf("CREATE NOTIFY");
                break;
            }
            case XCB_MAP_NOTIFY: {
                printf("MAP NOTIFY");
                break;
            }
        }

        free(ev);
    }

    xcb_disconnect(connection);
}

如您所见,代码非常简单,如果我能找到手头问题的解决方案,我计划扩展它。

我正在使用 Xephyr 来运行该程序。我刚刚运行

Xephyr -br -ac -noreset -screen 500x500 :1
创建一个新窗口,然后运行
DISPLAY=:1 ./myprogram
来测试它。显然屏幕上没有任何反应,但我想知道如何获得
printf
调用的输出。

c x11 window-managers xcb
1个回答
0
投票

xcb_flush()
循环之前调用
while

默认情况下,发送的请求最终位于输出缓冲区中。您需要显式调用

xcb_flush()
才能实际发送请求。

但我想知道如何获得 printf 调用的输出。

没有输出,因为尚未运行

printf
调用,因为您的
ChangeWindowAttributes
请求尚未实际发送。


实际上,当这样做并在 x11trace 下运行你的程序时,会显示:

000:<:0001: 16: Request(2): ChangeWindowAttributes window=0x0000051e value-list={event-mask=KeyRelease}
000:>:0001:Error 16=Length: major=2, minor=0, bad=0x0000051e, seq=0001

您的请求失败。并且不会发送您期望它发送的内容。

你想要:

uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t values[3] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT };

这仍然没有产生任何输出。我看到正在生成

ConfigureRequest
MapRequest
类型的事件,但这些事件都没有被打印。

我将以下内容添加到

switch
以实际获得一些输出:

default: printf("%d\n", ev->response_type);

(此外,您的

printf
呼叫缺少尾随的
\n
。)

© www.soinside.com 2019 - 2024. All rights reserved.