回顾

DDE 在 v15 时期,使用 Mutter 作为带合成器的窗管,以及 Metacity 这种不带合成器的窗管,一个是在高性能设备上使用,一个是为低性能设备上使用。

在 V20 时期,DDE 更换 KWin 当窗口管理器,由于 KWin 自带有关闭合成器的模式,所以 DDE 也放弃了 Metacity 作为备用窗管的选项。

Mutter

Mutter 是 GNOME 开发的带有合成器功能的窗口管理器。

Mutter

Metacity

一个不带有合成器功能的窗口管理器。

Metacity

KWin

KWin 是 KDE 开发的,具有动态切换渲染后端,动态开关合成器功能的窗口管理器。

KWin

需求和指标

在一个面向用户的产品中,拥有友好的界面是一个非常重要的事情,所以设计师给了一大堆非常好看的界面交互设计。

但更多的动画效果,以及更多的组件交互,通常就要求使用更多的资源,更多的内存,更高的功耗。

设计师说要动画华丽,要动画流畅,要优秀的用户体验。

架构师说要低资源占用,低内存,不能卡。

虽说一切目标都是为了用户体验,但两个大指标在实现上竟然是冲突的,那么如何平衡二者,就需要研发献祭一些头发了。

对比

在Linux下目前有两个技术栈,一个是历史悠久的X11,另一个是较新的 Wayland。

接下来,跟随我一起来对比两个技术。

X11

架构

X11采用了比较老的客户端-服务器架构。应用程序通过X服务器与硬件设备进行通信,这种架构非常灵活,支持网络传输,使得远程显示变得可能。然而,X11协议复杂且过时,在很多方面不再符合现代的图形需求。

性能

由于其设计较老,X11在一些现代场景下的性能表现不佳。它需要依赖很多扩展和补丁才能实现现代图形效果,例如合成管理器(Compositor)等。这些叠加的复杂性导致了额外的性能开销。

安全性

X11的安全性问题比较明显,因为所有应用程序都可以访问彼此的窗口信息。这意味着一个恶意程序可以读取或干扰其他程序的输入输出。虽然可以通过一些扩展和工具加强安全性,但这并不是X11的设计初衷。

可扩展性和兼容性

由于存在了几十年,X11有非常广泛的应用支持和兼容性。许多老的应用程序和桌面环境仍然依赖于X11协议,尤其是在远程桌面和某些专业领域。

输入设备支持

由于其历史悠久,X11对各种输入设备的支持相当成熟。但随着新硬件和新输入技术的出现,X11的设计显得有些不灵活,特别是在多点触控和手势支持方面。

远程桌面和网络透明性

X11的一个优势是其天然的网络透明性。它支持通过网络将显示内容远程传输,这是很多专业领域(如科学计算、服务器管理)中非常有用的功能。

Wayland

架构

Wayland采用的是更简单的设计,去掉了X服务器的复杂层次。消除了很多中间环节,提高了效率和响应速度。Wayland专注于本地显示,不像X11那样直接支持远程显示。

性能

Wayland的设计更加现代化,它简化了渲染过程,减少了中间层,性能提升显著。特别是在动画和窗口操作方面,Wayland通常比X11更为流畅。

安全性

Wayland在设计时考虑了安全性。应用程序之间的隔离更强,应用程序无法访问其他程序的图像或输入输出,这显著提高了系统的整体安全性。

可扩展性和兼容性

尽管Wayland逐渐被主流桌面环境(如GNOME、KDE等)支持,但其应用生态仍然不如X11广泛。在某些老旧或专业的应用场景中,可能需要通过兼容层(如XWayland)来运行基于X11的应用程序。

输入设备支持

Wayland针对现代硬件进行了优化,尤其是在多点触控、触摸板手势等方面有更好的支持。此外,它对显示器的DPI缩放、刷新率等也有更灵活的处理。

远程桌面和网络透明性

Wayland默认没有X11那样的网络透明性功能。这意味着原生的远程桌面功能比较有限,尽管可以通过一些第三方工具或协议(如VNC、RDP)实现远程桌面,但这不是Wayland的核心功能。

总结

总结下来,X11已经进入维护阶段,不再进行大幅更新。随着时间的推移,开发者和社区的注意力逐渐转移到Wayland上,X11可能会逐步淡出主流桌面环境。Wayland正在逐步成为Linux桌面的标准。随着越来越多的应用程序和桌面环境转向支持Wayland,其生态系统正在不断成熟和扩展。

架构设计

从技术层面上,我们认为是时候更新技术方案了,曾经的X11+窗口管理器+合成器的模式,灵活但不满足需求,Wayland从底层就将三者融合在了一起,并且更新画面是以每幅完整的画面作为基础的,这确保了画面不会因为不同窗口更新界面的时机不一致导致画面撕裂。

更重要的一点,自研的窗口管理器,它是以实现DDE的需求为目的的,这是第三方窗口管理器不能比拟的。通常使用第三方的项目时,都要进行大量破坏性的调整,导致fork后的项目无法和上游同步,不能及时获取更新和修复,并且第三方的项目已经发展了很长时间,内部有许多DDE用不上、甚至冲突的功能,都需要进行大量调整,更加剧了维护成本。

所以 DDE 决定开发一个新的窗口管理器——Treeland。

Treeland在底层使用 wlroots 作为 Wayland 的基础库,不修改 wlroots 的代码,也就意味着可以随时同步上游进度,获得新的功能与修复。上层使用 Qt,可以充分利用公司内大量的 Qt 开发者,不再需要一直有专人负责特定项目,让DDE的技术栈更加统一。

Treeland 结构图

简单介绍一些 Treeland 里涉及的重要项目。

  • QWlroots

    wlroots 的 Qt 绑定,将 wayland 信号转换成 Qt 风格的信号。

  • Waylib

    将 wlroots 中的组件封装成 QtQuick 对象,使用 QPA 为 Treeland 提供事件转换与分发。

  • DtkDeclarative

    DTK 的 QtQuick 组件,封装了大部分 DTK style 的控件。

在 Waylib中,会使用到 Qt 的 QPA 功能,将 wlroots 作为一个新的平台来处理一部分功能。

QPA 在 Treeland 中有着举足轻重的地位,来自系统底层的事件会先进入到 Waylib中,在 Waylib 里将事件转换成 Qt 内部事件,发送给上层。这样 Treeland 就可以在 QtQuick 中确定用户的点击位置、按键事件等行为。当用户点击的是窗口时,Treeland 还会通过 Waylib 生成一个事件,通过 seat 的接口发送给客户端,完成界面交互。

Treeland 处理底层事件与上层事件的流程

界面效果与优化

Treeland 作为一个窗口管理器,最重要的功能还是对窗口的管理及显示效果的控制,Treeland 所有的窗口都带有圆角和阴影,以及一些窗口模糊效果。

圆角

DDE及deepin社区应用都大量采用了窗口圆角的设计,由合成器提供圆角裁剪可以带来更加统一的界面设计。

红色为QtQuick圆角/黄色为Treeland圆角

QtQuick 圆角是由 Rectangle 组件提供的,它只能同时对四个角进行操作(红色块)。但 DTK 程序具备异形窗口的能力,所以 Treeland 提供了自己的裁圆角控件(黄色块)。
新的造型算法、几何顶点数量比 QtQuick 原生的 Rectangle 减少50%,GPU顶点渲染和三角细分性能提升100%。
采用新的抗锯齿算法,提高了GPU片元着色器性能,相比于普通 4xMSAA 抗锯齿算法,计算量减少1/4。

模糊

QtQuick 模糊控件

QtQuick 的模糊组件仅支持对控件自身进行模糊,这并不符合 Treeland 的需求。

Treeland 模糊控件

Treeland 重新实现了模糊组件,能从显存里获取组件下方图像数据,再使用融合的模糊算法优化性能。

阴影

Qt Quick 有一个 BorderImage 组件,它能以九宫格的方式,四个角保持不变,四边和中间的部分拉伸,来达到在组件底部充当装饰的效果。并通过 ImageProvider 的机制,手动控制图片资源的创建。

Treeland 使用 BorderImage 作为窗口阴影贴图,通过 ImageProvider 手动创建贴图材质,在相同大小下可复用同一份材质。

动画

Treeland 直接使用 QtQuick 提供的动画组件,来为界面提供动画效果。

使用 State 和 Transition 为组件定义属性变化,例如窗口最大化和还原,两个 State 切换会触发不同的 Transition 执行属性变化,在属性变化时,使用 QtQuick 的动画组件完成动画播放。

多用户

Treeland 作为解决方案的一部分,目的之一就是多用户共用合成器。在经典模式下,不同用户的切换需要在 tty 层面前端程序转移控制权,每个用户独占一个 tty 进行画面上屏。但切换tty所需的工作量不小,这导致切换时屏幕的缓冲区被不同的程序覆盖,给人的观感就是屏幕闪烁了一下,甚至是黑屏一会儿。

DDM

通过上图可以看出,LightDM模式下,每个用户拥有完整的一套进程组,都需要运行窗管、任务栏、文件管理器等。不同的用户会单独占用一个 tty,那么用户切换时,必然伴随着底层 DRM 以及显卡驱动等操作的切换,带来的结果就是会看到闪黑屏,而且两个用户都要跑一个锁屏界面来维持”假装是同一个界面“,也带来了跨用户进程的信息同步难题。

而 DDM 和 Treeland 重新设计了工作流程,将 Treeland 单独抽离出来,每个用户都通过相同的一套机制将窗口画面发送给 Treeland,而 Treeland 负责最终的画面合成以及上屏。

带来的好处显而易见,内存方面节省了窗管、锁屏等进程,切换用户也不会有黑屏闪烁,状态也不用想办法同步了。

一个简化的 DDM 与 Treeland 的多用户登录流程

与 systemd 的集成

DDE 的每一个用户会话,都已切换至 systemd 服务,而非所有进程都挂载到会话入口的服务上。这样做有很多好处,包括快速重启桌面环境,而非注销再登录。远程桌面的铺垫,会话的启动不再局限于本地会话。

在 Treeland 模式下,DDE 会加载一个单独的服务,用于为用户会话注入显示环境变量。该服务使用 systemd 提供的 socket 机制实行懒加载,当 DDE 需要显示窗口时,即时向 Treeland 注册,完成用户显示服务的初始化。当 Treeland 崩溃重启时,该服务也会等待 Treeland 启动完成,并再次连接回 Treeland,确保用户侧的窗口能正常显示。

多用户登录时的基本流程

总结

本文介绍了深度操作系统(DDE)在窗口管理器方面的演进,从早期使用Mutter和Metacity,到后来采用KWin,最终决定开发自己的窗口管理器Treeland。Treeland基于wlroots和Qt技术栈,实现了更好的性能和更统一的技术框架。

本文概述了 Treeland 的技术架构、界面效果优化(如圆角、模糊、阴影等),以及其在多用户场景下的优势。此外,还介绍了Treeland与systemd的集成,展示了DDE在系统架构和用户体验方面的持续创新和改进。