XCB map/draw 其他进程的 GUI 如何显示到屏幕上?

How does XCB map/draw other processes' GUIs to the screen?

我已经阅读了很多关于 XCB 的文章 API 并从各个站点编译了很多示例。但是,其中 none 直接解决了为 GUI 应用程序实际创建真实 windows 的问题;他们都对如何使用 XCB 绘制原始 2d 图形犹豫不决。例如。创建一个window,画几个方块,关闭window.

您实际上如何让进程在您的 XCB window 管理器中产生它们的 windows?

我只能假设当创建一个进程时,X 服务器会收到通知并将请求转发给您的应用程序,然后您将进程的 window 映射到屏幕以及任何底层图形子系统执行代表 X 服务器(和您的 window 经理)绘图。

我还从他们的 window 经理那里了解到人们如何 fork() 第三方流程。这似乎是一个愚蠢的想法。是吗?应用程序 运行 不应该独立于 window 管理器吗?

我通读了很多 window 管理器源代码,称我为新手,但我没有看到任何与应用程序如何绘制自己的 windows 直接相关的东西。

如果有人能阐明您应该如何通过 XCB 处理应用程序的 window 创建,我将不胜感激。谢谢

However, none of them directly address the issue of actually creating real windows for GUI applications;

无论如何,这不是您想要使用裸协议级 API 做的事情。如果您想要丰富的 GUI,请使用可以为您完成所有繁重工作的工具包。 Xlib / XCB 只会为您提供基本的工具,这些工具非常简单 windows;即使在那里,我也不会在没有至少使用像开罗这样的东西的情况下开始一个项目。

How do you actually make processes spawn their windows within your XCB window manager?

通过调用 xcb_create_window 然后 xcb_map_window。就是这样。就这样。你创建一个 window 然后你让它可见。

当然,您还应该用 windows 做很多其他事情,但就创建和显示而言,仅此而已。

I can only assume that when a process is made, X server is notified

X 服务器不关心进程。

forwards the request to your application

什么要求?

Shouldn't applications run independently of the window manager?

嗯,是的……但实际上,window 管理器的生命周期等于 X 服务器的生命周期(人们通常不会在两者之间切换 window 管理器)。如果没有 X 服务器,所有 X 客户端都会死掉。

所以理论上它是完全独立的,但现实是没有真正的理由进行这样的区分。也就是说,我所知道的所有 window 管理器都提供了一些启动应用程序的方法,因此即使 window 管理器退出,分叉进程仍然存在。

I've read through a lot of window manager source code and, call me a novice, but I've seen nothing that's directly linked to how applications draw their own windows.

那是因为 window 管理器根本不参与渲染 windows。 window 管理器只知道 windows 存在并管理它们的抽象属性,但是对于所有 window 管理器来说,window 是一个具有一些属性的矩形。

实际上渲染到 window 是 X 客户端将自己直接与 X 服务器进行的事情。

window 经理通常参与的一种渲染是装饰渲染(window 边框和标题等)。但是 window 管理器也只是一个 X 客户端,所以在这方面它只是另一个呈现某些东西的应用程序(通常 window 管理器将这样的装饰渲染到它自己创建的框架 windows 中 – so-called 重新抚养 window 经理)。


在您发表第一条评论后更新: X 客户端(想要创建 window)将这些请求(创建/映射 window)发送到X 服务器。 X 提供了如何实现这种情况的多种实现,如今 Linux 系统上最常见的情况是 UNIX 套接字。

在 X 中有不同的事件客户端可以 select。其中一种事件类型是子结构重定向,这意味着客户端可以要求 X 服务器在某些 window 时得到通知,例如,创建 child windows.

根 window 也只是一个 window,但它有一些独特的属性,比如它始终存在且无法关闭。只有一个 X 客户端可以在根 window 上 select 子结构重定向——这样做是 window 管理器成为 window 管理器的原因。

所以现在我们有一个在根 window(我们的 WM)上带有子结构重定向的 X 客户端。现在,每当客户端请求映射 window 时,X 服务器会将此请求重定向到 window 管理器客户端(通过 MapRequestEvent)并在那里停止。 唯一的例外是来自window管理器本身的地图请求:这些X服务器将处理(为了不只是与[=81=打乒乓球) ]永远的经理)。

这基本上建立了一个干预循环:客户端请求 X 服务器映射 window,X 服务器将请求转发给 window 管理器,window 管理器可以选择发送window 的映射请求返回到服务器,服务器处理映射请求,因为它来自 window 管理器。

就是这样;这就是映射 window 的方式。

How is my window manager meant to tell when to make and map a window?

window 经理不告诉客户该做什么。它怎么知道客户甚至想做什么?恰恰相反:客户端做事,window 管理器进行干预并做出它认为合适的反应(在某些方面 – window 管理器决不能完全控制 X 服务器)。

Is there some kind of event loop I need to create a case for (where there would be a request to create a window from X server)?

如上所述,决定何时创建 windows 取决于客户。但是,是的,X 客户端的一个核心概念是他们需要设置一个事件循环。

例如在映射 window 的情况下:客户端发送映射请求并且不得假设 window 被映射(因为 window 管理器可以选择拒绝请求!)。客户端知道他们的 window 已被映射,因为当它发生时,X 服务器将创建一个 MapEvent 并将其发送给客户端。

请注意,window 管理器不仅可以拒绝来自客户端的映射请求,它甚至可以映射 windows 它甚至从未收到来自客户端的映射请求。因此,客户端必须始终等待这些事件,并在其 windows 之一已被映射时做出相应的反应。

还有一大堆对客户端很重要的事件,特别是 Expose 事件,它告诉客户端它需要重绘其 window.

的(部分)