我试图了解 Linux 系统的不同组件如何与显示服务器提供的服务进行交互。在使用基于 Wayland 的显示服务器使问题变得复杂之前,让我首先关注 X11:
- 我知道,为了为基于 X11 的系统实现一个非常基本的 GUI 应用程序,理论上可以针对X11的C库绑定并利用低级原语(例如
XMapWindow
或 )XDrawString
来创建特定的 X 客户端。这也是常见 GUI 工具包(例如 GTK 或 Qt)在其 Linux 实现的最低级别使用的 API 吗?或者他们以不同的方式绘制按钮和文本字段? - 根据这个帖子,窗口管理器的工作之一是控制窗口的位置。这究竟是如何发生的?显示服务器是否知道窗口管理器想要显示的每个窗口,并且对于每个窗口,期望窗口管理器为其提供位置和所需的尺寸?例如,当调整窗口大小时,窗口管理器有责任更新这些尺寸吗?
- 再次考虑上面的帖子,窗口管理器的另一项工作是装饰窗口,即绘制应用程序的边框和控件。窗口管理器如何做到这一点?它是否再次使用上述 X11 原语在实际 X 客户端周围绘制对象?如果确实如此:它如何知道 X 客户端的开发人员将哪些菜单编程到其 GUI 中?
- 如果我们不仅运行窗口管理器,而且运行完整的桌面环境(例如 GNOME):如何绘制特定于环境的组件(例如面板和窗口切换器)?它们作为单独的 X 客户端运行吗?
最后,考虑 Wayland 而不是 X11。如果我明白的话本文正确地说,基于 Wayland 的显示服务器被称为“Wayland 合成器”,并集成了合成窗口管理器的功能。这是否意味着像 Mutter 这样的 Wayland 合成器与像 Compiz 这样的传统窗口管理器完全不兼容?
答案1
工具包最初使用 X11 低级原语在屏幕上绘制内容。如今,字体处理和文本渲染都是在客户端完成的,并且可以使用 GLX(基于 X 协议的 OpenGL)和直接渲染 (DRI) 等 X 协议扩展。
X 服务器知道所有窗口及其大小和位置。窗口是 X11 中的服务器端对象。客户端可以向 X 服务器发送窗口创建请求,服务器用所创建窗口的 id 进行响应。当用户与窗口管理器交互时,窗口通常会调整大小,而窗口管理器又会使用 X11 API 调用向服务器发送请求来调整窗口大小。
窗口管理器是一个普通的 X11 客户端应用程序,尽管是一个特殊的应用程序。窗口管理器确实使用与普通 X 客户端应用程序相同的 X 调用并处理相同的事件,例如绘图基元和指针事件。应用程序菜单不是窗口管理器绘制的装饰的一部分,而是由应用程序本身处理。
桌面环境的“面板”和“窗口切换器”可以是单独的 X 客户端,也可以是窗口管理器的一部分,特别是当它们执行诸如切换窗口之类的任务时。
Wayland 窗口管理器在最低级别上与 X11 对应的窗口管理器非常不同,因为 Wayland 架构与 X11 有很大不同。如果您正在运行 Wayland,则需要 Wayland 窗口管理器/合成器。另一方面,一些 Wayland 窗口管理器(例如 KWin)是以原始 X11 版本为起点编写的,其目标是提供几乎相同的用户体验,因此从用户的角度来看,这两个变体(KWin/ X11 和 KWin/Wayland) 兼容。
答案2
我使用 Xlib 编写了一个 X11 应用程序(一个小游戏)。我看过窗口管理器是如何工作的,但没有写过。
第 2 部分和第 3 部分窗口管理器
当客户端创建窗口时,服务器接收请求。当客户端映射窗口时(要求服务器显示它。它也可以取消映射:就像它隐藏在任务栏中一样),服务器将通知窗口管理器(我认为客户端必须注册为窗口-经理)。窗口管理器拦截映射,并获取新窗口的窗口 ID,然后创建自己的窗口,其中包含标题栏、框架部分(左、右、下)和中间一大块的子窗口。它告诉服务器将原始窗口重新设置为中间的这一大位。然后映射这个现在窗口。
注意,在 X11 中一切都是窗口。窗口包含其他窗口。显示器有一个窗口,即根窗口。所有其他窗口都在该根窗口内。就像文件系统中的目录一样。重新设置父级就像将一个目录移动到具有相同文件系统的另一个目录。
第 4 部分面板
这些只是其他客户。任务栏将与窗口管理器协作。窗口管理器将告诉任务栏窗口的状态是什么。
客户端菜单等
这些可以使用与窗口管理器相同的工具包来创建。然而,他们是客户的一部分。
有趣的实验。
尝试在没有窗口管理器的情况下运行 X11。尝试在没有桌面环境其余部分的情况下使用窗口管理器。尝试暂停(在进程管理器中停止)窗口管理器和其他客户端(分别)。尝试在不注销或关闭其他客户端的情况下切换窗口管理器。
这些实验将帮助您了解窗口管理器的作用。