我正在尝试创建一个与 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
调用的输出。
在
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
。)