集成 XCB 和 libX11 事件循环 - 挂在 Xt 内的选择/轮询上

kdm*_*kdm 5 x11 events qt motif xcb

我试图将两个代码体集成到同一个进程中,每个进程以前都为各自的 GUI 工具包提供独立的事件循环——其中一个使用 Xt,另一个使用 Qt5。目的只是为了能够显示 Qt 子窗口,而不是像现在已经不复存在的 Qt/Motif 集成扩展那样实现完全集成。

我已经能够构建一个使用标准 Qt 事件循环运行的粗略原型,带有将 XCB 事件转换为 XEvents 的本机事件过滤器(使用 XESetWireToEvent + 其处理程序从 xEvents / X11 线格式转换)。然后它使用 XtDispatchEvent() 将这些 XEvent 直接分派到 Xt。此时,我可以运行该程序,并在同一个程序中创建 Xt/Motif 小部件和 Qt 小部件,使用菜单,绘制 2D 图形,并同时使用 Qt 和 Motif 小部件。

我遇到的问题是,在创建新的 Motif 对话框时会有很长的延迟。我已经将其追溯到 libXt 中的 _XtWaitForSomething(),最终归结为 X 服务器连接套接字上的 select() 或 poll()。对 _XtWaitForSomething() 的调用是 XtManageChild() 内部发生的窗口布局管理的结果。_XtWaitForSomething() 似乎正在检查事件队列中是否有待处理的事件。

我有几个问题:

  1. 当在同一个程序中同时使用 XCB 和 libX11 调用(使用 XCB 作为事件队列主控器)时,我是否可以期望来自经典 Xlib 的调用也能正常工作——例如通过 libX11 调用将事件发布到 XCB 事件队列,或者确定是否有通过旧的 libX11 调用在 XCB 事件队列中挂起的任何事件?

  2. 为什么 XtManageChild() 最终会阻塞 libXt 中的 _XtWaitForSomething()?看起来它可能正在等待几何更改事件。有趣的是,Qt 的平台层在单独的线程中读取 XCB 事件,然后在主线程中调度它们。我现在想知道 Qt 的 XCB 读取器线程是否在 Xt 有机会检查事件队列是否包含 _XtWaitForSomething() 中的任何内容之前吃掉事件,从而导致死锁。当我调用 Xt 时,有什么方法可以导致 Qt 的 XCB 事件循环 [或通用 XCB 事件循环] 阻塞?我不能只是修改 Qt 以在 XCB 层中有一个条件变量,因为更改 Qt 不是一种选择。

 

#0  0x00000037b30e9a5d in poll () from /lib64/libc.so.6
#1  0x000000355f82d468 in _XtWaitForSomething () from /lib64/libXt.so.6
#2  0x00007ffff77b871f in _XmRootGeometryManager () from /lib64/libXm.so.2
#3  0x000000355f82569f in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#4  0x000000355f8257aa in XtMakeGeometryRequest () from /lib64/libXt.so.6

#5  0x00007ffff77b77e6 in geometry_manager () from /lib64/libXm.so.2
#6  0x000000355f8255f4 in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#6  0x000000355f8255f4 in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#7  0x000000355f8257aa in XtMakeGeometryRequest () from /lib64/libXt.so.6
#8  0x00007ffff773852e in _XmMakeGeometryRequest () from /lib64/libXm.so.2
#9  0x00007ffff770ed51 in change_managed () from /lib64/libXm.so.2
#10 0x000000355f82a2e8 in XtRealizeWidget () from /lib64/libXt.so.6
#11 0x00007ffff771c8d6 in change_managed () from /lib64/libXm.so.2
#12 0x000000355f82c57d in ManageChildren () from /lib64/libXt.so.6
#13 0x000000355f82ca11 in XtManageChildren () from /lib64/libXt.so.6
#14 0x000000355f82cb18 in XtManageChild () from /lib64/libXt.so.6
...
Run Code Online (Sandbox Code Playgroud)
  1. XCB 中的事件队列“所有者”状态究竟意味着什么 [XSetEventQueueOwner(..., XCBOwnsEventQueue)]。这是否意味着 XLib 调用收获事件实际上不会从事件队列的头部“获取”任何事件?

  2. 所描述的方法是否存在明显的阻塞问题?我已经知道我可能需要整理计时器(不再调用在事件循环中处理这些的 Xt 函数)、Qt 子窗口到主题小部件的窗口父系,......

谢谢。

Jan*_*ker 0

我看到类似的东西。不涉及 Qt(仅 X11)。在某些情况下,XtMakeGeometryRequest() 调用作为处理MapNotify事件的间接调用。通常这效果很好。有时会有延迟,似乎持续了 5 秒,您可以通过移动窗口(使用鼠标)来加速。这与时机有关。不确定这是否与窗口管理器计时或应用程序中与内部线程相关的计时。

这个问题很久以前就没有出现过。它是从一些 Linux 升级开始的,但恐怕什么时候才能重现。