0x00 引言
Linux图形界面包括前后端,后端的选择方案有著名的”X Window System”和”Wayland”,前端包括以下几个重要组成部分:显示管理器、窗口管理器、文件管理器以及GTK+/QT图形库等。
1984年MIT大学创造了”X Window System”(XWindow),这是在UNIX系统构建图形化视窗系统的设计方案,又称X规范(协议)。并在1987年形成了第11版(X11),目前使用最广的软件实现是Xorg。
2008年,RedHat的员工创造了Wayland。Wayland是在XWindow基础上实现的一种协议,前者去除了后者中不必要的设计(比如将X Server和窗口管理器整合到一起作为服务端)。但目前而言,前者仍有许多缺陷,比如在远程桌面能力不足,重度依赖Linux内核技术不易移植到其他系统平台。
前后端分离的好处是,用户在Linux中可以随意切换前端,享受不同界面风格。比较常用的前端界面环境有Gnome、KDE、Unity、XFCE、LXDE、DDE等。
0x01 X Window System
1 | 1 设计原理 |
1、设计原理
- X11采用了C/S的架构,在其设计下,整个图形视窗系统主要分为3个部分:
- X Server(X服务器)。一方面负责和设备驱动交互,监听显示器和键盘鼠标;另一方面响应X Client需求传递键盘、鼠标事件、绘制图形文字等
- X Client(X客户端)。由GTK+/QT等图形库开发实现,负责在收到设备事件后计算出绘图数据,由于本身没有绘制能力,只能向X Server发送绘制请求和绘图数据。X Client可以和X Server在同一个主机上,也可以通过TCP/IP网络连接。
- Window Manager(窗口管理器),或者叫合成器(Compositor)。掌管各X Client的窗口视觉外观,如形状、排列、移动、重叠渲染甚至是半透明效果等。注意窗管并非X Server的一部分,而是一个特殊的X Client程序。
2、通信流程
0x02 Wayland
Wayland将X Server和窗口管理器整合到一起作为服务端,也可以称为合成器(Compositor),注意在XWindow中窗管被称为合成器。
0x03 显示管理器
显示管理器用于开机后显示登陆界面,并启动窗口管理器等XWindow组件。如果没有显示管理器,Linux开机会显示命令行登陆界面,需要使用命令行登陆后手动启动X server和窗口管理器才能显示GUI。
0x04 窗口管理器
1 | 1 窗口层级 |
窗口管理器是前端的核心组件,其主要负责管理每个独立窗口如何显示/移动,怎样反馈输入,怎样组织各个窗口。目前常用的窗管有XFCE的xfwm,Gnome的mutter,KDE的Kwin等。XWindow并未指定一个专用的窗口管理器,也没有定义窗口管理器的行为,因此用户可以任意替换。关于如何写一个窗口管理器可以参考文献[1]。
窗口管理器的本质上就是一个常规的X Client,它并没有超级用户权限,也并不能直接调用内核函数。但是,窗管能通过X Server提供的特殊API来控制屏幕显示(X Server至多只会有一个窗口管理器的存在)。窗管与X Server的交互是通过属性和事件机制实现的。下面将详细介绍窗管实现的细节:
1、窗口层级
在显示器显示的时候,所有窗口的管理实际上是一个树形结构,这个树的根就是顶层窗口(一个虚拟的,不可见的窗口,但是它的大小跟屏幕一样,同时会永远的存在)。有Qt开发经验的都清楚,每个界面应用(X Client)都有一个QWindows(QWidget)作为主窗口,而所有的主窗口最后都会挂载到顶层窗口中。
2、子框架重定向
在X Window System的设计理念中,X Server并不直接管理窗口显示,这个功能均转交给窗管实现。实际上如果没有窗管,那么显示就由X Server直接处理,然而在有窗管存在的情况下,显示过程中窗管会先拦截X Client对界面显示操作的请求,这种拦截技术被称为子框架重定向(Substructure Redirection)。
X Server在任何情况下,只允许一个窗口管理器注册子框架重定向。当有第二个窗管在对一个已被注册子框架重定向的X Server进行注册时,原先的窗管不会从X Sever解注册,断连或者崩溃。
3、二次排版
为了实现窗口风格的统一,窗口管理器在接收到X Client的窗口绘制时会主动为其添加包含标题栏的框架窗口(Frame Window),这也是为什么Qt窗口应用默认会有标题栏的原因。
4、窗口合成管理器
现代的界面显示已经不能满足于窗口了,例如Shift Switcher:
为了实现更加复杂的显示,出现了离屏内存缓冲区的概念(Wayland中使用的DRM技术)。实现步骤如下:
1. 渲染每一个顶层窗口以及它的内部UI节点到一个离屏内存缓冲区,而不是直接输出到硬件上;
2.根据我们的设计,使用旋转,扭曲这样的方式来变化每个缓冲区的样式;
3.将这些经过变化的缓冲区融合到一个最终的缓冲区中,同时还需要将背景和其他需要展示的UI也合并进来;
4.将这个最终缓冲区的内容渲染到屏幕上。
0x05 文件管理器
管理硬盘的分区显示。
0x06 常见问题
1.通过Windows的远程桌面功能远程连接到Linux的桌面系统,无法显示水印进程。而直接在Linux上安装向日葵,并远程连接,可以正常显示水印进程。
0x07 引用文献
[1]https://jichu4n.com/posts/how-x-window-managers-work-and-how-to-write-one-part-i