首页 > 解决方案 > Xlib 和 XCB。一个进程中有多个窗口。Xlib 失败,而 XCB 没有

问题描述

不久前,我面临一个事实,即Xlib在存在多线程和多个窗口的情况下进行编程是一条荆棘之路。我面临的问题是,Xlib(或窗口管理器)在所谓的“顶级”窗口关闭后强制关闭与服务器的连接。

该问题很容易重现,您只需要创建一个窗口,然后将其关闭。Display尝试在上述步骤后使用 a 。将引发致命错误并且程序将退出。这是一个奇怪的行为Xlib

这个问题在几个SO主题中都面临着:如何优雅地退出 X11 事件循环?,你如何在没有错误的情况下退出 X11 程序。总结讨论,在 Xlib 文档的某处指出,Windows 管理器将关闭连接。

出于好奇,我检查了XCB图书馆是否有这种行为。与 Xlib 相比,它的XCB行为“正常”,我能够创建和销毁几个连接仍然存在的窗口。

问题是。在存在多个窗口和线程的情况下库如何XCB执行,因此它不会显示Xlib错误行为?是在幕后XCB使用Xlib,还是以其他格式向 X 服务器发送命令?不好意思,我不是很熟悉,如何与 X11 协议通信。特别是,它是怎么来的,那个窗口管理器没有关闭与XCB

我将接受任何可以阐明问题的答案。是否是指向XCB源代码的网络链接,它解释了聪明的做事方式。或者它会在X11协议方面进行解释。或者别的什么。

感谢您的长时间阅读。我希望我没有对所有这些文字感到厌烦。

更新

我把事情搞砸了。如果在 WM_PROTOCOLS 中设置了 WM_DELETE_WINDOW,Xlib 的行为与我预期的一样。只是排序或同步导致连接处于错误状态。我认为多个线程Xlib以随机方式干扰了状态,并且事件循环出错了。我必须警告其他人关于 Xlib,应该通过变量或原子原语进行同步。实际的Xlib状态更改应该只在主线程中并且在事件循环通过之后进行

标签: linuxx11xlibwindow-managersxcb

解决方案


总结讨论,在 Xlib 文档的某处指出,Windows 管理器将关闭连接。

“某处”是 Xlib 文档。你应该更仔细地阅读这些讨论,因为你似乎忽略了一些重要的观点。

XCB 库在存在多个窗口和线程的情况下如何执行,因此它不会显示 Xlib 错误行为?

您可能不喜欢 Xlib 在这方面的行为,但它不是“错误的”。它已记录在案,并且对许多程序很有用。此外,虽然关闭连接是 Xlib 下关闭顶级窗口时的默认行为,但这并不是唯一可能的行为。在您链接的问题的答案中,有一个描述(和文档引用)描述了您需要做的相对简单的事情,以避免在通过其关闭按钮关闭顶级窗口时关闭 X 连接。

那么,考虑到我们谈论的是 Xlib 的默认行为,而不是不可避免的行为,XCB 以不同的方式做事应该不足为奇,因为......

XCB 是在底层使用 Xlib,还是以其他格式向 X 服务器发送命令?

不,XCB 不使用 Xlib。它是 Xlib 的替代品,Xlib 是一个年轻的兄弟姐妹,用 Xlib 的经验编写的智慧。Xlib 和 XCB 都通过 X 协议与 X 服务器通信。*它们都是低级的,但 XCB 或多或少是一个直接的协议包装器,而 Xlib 提供了一个 API 外观,隐藏了 X 的客户端/服务器特性。

方向上的差异为关闭窗口按钮的默认行为差异提供了一个合理的解释。Xlib 试图猜测 GUI 应用程序的程序员最有可能想要什么,并据此选择默认值。大多数 X 应用程序都提供一个顶级窗口,关闭窗口会终止应用程序,而自动关闭 X 连接对于此类应用程序来说是一种便利。另一方面,XCB 不会试图隐藏 X 协议或分层策略(尽管构建在它之上的工具包可能会这样做)。XCB 就是要对其所做的事情保持透明。

不好意思,我不是很熟悉,如何与 X11 协议通信。

一般来说,您使用 Xlib 或 XCB 进行通信。原则上可以将原始 X11 用于 X 服务器——毕竟,这就是 Xlib 和 XCB 所做的——但这样做很复杂。这就是 Xlib 和 XCB 存在的原因。甚至那些也不是那么容易使用,这就是为什么他们在它们之上构建了更高级别的工具包。

特别是,那个窗口管理器怎么没有关闭与 XCB 的连接?

XCB 不指示窗口管理器这样做(至少,默认情况下不是)。Xlib 也不这样做,如果你告诉它不要这样做。


*或者最初是这样的。正如一位评论者所观察到的,这些天来,Xlib 不直接使用 X 协议,而是使用 XCB(而不是相反)。


推荐阅读