【发布时间】:2020-07-26 09:43:02
【问题描述】:
我有一个基于 xcb 的小型 GUI 编程库。它的一种方法强制重绘窗口区域中的指定矩形。它创建 Expose 事件并将其发送到一个窗口:
void GWindow::redrawRectangle(const I2Rectangle& r) {
xcb_rectangle_t rect;
rect.x = (short) r.left(); rect.y = (short) r.top();
rect.width = (unsigned short) r.width();
rect.height = (unsigned short) r.height();
xcb_set_clip_rectangles(m_Connection, XCB_CLIP_ORDERING_UNSORTED,
m_GC, 0, 0, 1, &rect);
xcb_expose_event_t *e = (xcb_expose_event_t*)malloc(sizeof(xcb_expose_event_t));
memset(e, 0, sizeof(xcb_expose_event_t));
e->response_type = XCB_EXPOSE;
e->window = m_Window;
e->x = r.left();
e->y = r.top();
e->width = r.width();
e->height = r.height();
e->count = 0;
xcb_send_event(m_Connection, 0, m_Window, XCB_EVENT_MASK_EXPOSURE, (char*)e);
xcb_flush(m_Connection);
}
这里r 是一个矩形,其顶点具有整数坐标。
另外,我有一个事件循环,它使用xcb_wait_for_event 来获取一个事件并将它分派给一个适当的回调函数。
所以,当我调用redrawRectangle 方法时,屏幕上什么也没有发生。我已经调查并发现该函数生成的事件不会进入事件循环。但是 xscope 说 X 服务器获取事件请求并发出它。它有什么问题?
UPD 1 窗口事件掩码通过xcb_set_window_attributes 设置。掩码是XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE
UPD 2 ClientMessage 也没有被 xcb_wait_for_event 捕获。
【问题讨论】:
-
xscope不会拦截服务器和您的应用程序之间的所有流量吗?因此,如果xscope显示该事件,那么它必须到达您的应用程序。 -
另外,为什么你需要给自己发送一个暴露事件?你不能直接重绘受影响的矩形吗?
-
@UliSchlachter 在将事件传递给应用程序之前和之后执行了一些代码。此代码设置剪辑矩形。当然,我可以将此逻辑添加到
GWindow::redraw,但我仍然对解决原始问题感兴趣。我想这是由于对 xcb 中的某些东西的误解造成的。