最小QML

最小QML是一个简单的示例,展示了如何在QML中编写Wayland组合器。

最小QML是一个桌面式Wayland组合器示例,使用尽可能少的代码实现完整的Qt Wayland组合器。组合器是用Qt Quick和QML实现的。

WaylandCompositor 对象

组合器的顶级项目是一个 WaylandCompositor。这代表着Wayland服务器本身,并管理客户端的连接。

默认情况下,服务器支持核心Wayland协议与客户端通信。不过,您可能还想支持一个或多个协议扩展。这给客户端提供了更多工具来影响其在窗口系统中的作用。

Qt支持几个标准和常用扩展。此外,只要支持可以在客户端和服务器代码中添加,就很容易创建和提供自定义扩展。

Shell 扩展

通常,组合器将支持至少一个 shell 扩展。通过将它们作为 WaylandCompositor 对象的直接子项实例化,来添加扩展到组合器中。当它们连接时,将自动添加到其 extensions 属性中,并广播到客户端。

WlShell {
    onWlShellSurfaceCreated: (shellSurface) => shellSurfaces.append({shellSurface: shellSurface});
}
XdgShell {
    onToplevelCreated: (toplevel, xdgSurface) => shellSurfaces.append({shellSurface: xdgSurface});
}
IviApplication {
    onIviSurfaceCreated: (iviSurface) => shellSurfaces.append({shellSurface: iviSurface});
}

最小QML 示例支持三种不同的shell:WlShellXdgShellIviApplication

客户端可以连接到其中的任何一个,它将用于在客户端和组合器之间进行某些通信,例如创建新窗口、协商大小等。

当客户端创建一个新的surface时,其活动的扩展将接收到一个信号。该信号包含一个 ShellSurface 参数。根据接收信号的扩展类型,该参数将是 ShellSurface 的子类:分别对应 WlShellSurfaceXdgSurfaceIviSurface

ShellSurface 可以用来访问特定surface的shell扩展的功能。在 最小QML 示例中,我们只想将客户端添加到我们的场景中。为了记录新窗口的存在,我们将其添加到一个简单的 ListModel 中以保留。

ListModel { id: shellSurfaces }

创建场景

大部分必要的合成器代码已经准备好了。最后一步是确保应用程序实际上可见在屏幕上。

对于所有合成器,我们必须定义至少一个输出。这是通过将一个 WaylandOutput 对象作为 WaylandCompositor 的直接子对象来完成的。如果只有一个输出,它将代表系统上的主屏幕。(您也可以创建多个 WaylandOutput 对象来处理多个屏幕,如果可用。有关此内容的更多详细信息,请参阅 多屏幕示例。)

WaylandOutput {
    sizeFollowsWindow: true
    window: Window {
        width: 1024
        height: 768
        visible: true

WaylandOutput 内部,我们创建一个 Window,该窗口作为场景的容器。在示例中,我们给它指定了一个大小。如果合成器作为其他支持自定义窗口大小的窗口系统的应用程序运行,将使用此大小。在一个典型的嵌入式设备上,其中合成器是唯一运行的显示服务器,它可能在全屏平台插件(如 eglfs)上运行,这里设置的大小将无关紧要。

最后一步是为已创建的每个 ShellSurface 对象创建项目。为此,我们可以使用 ShellSurfaceItem 类。

Repeater {
    model: shellSurfaces
    // ShellSurfaceItem handles displaying a shell surface.
    // It has implementations for things like interactive
    // resize/move, and forwarding of mouse and keyboard
    // events to the client process.
    ShellSurfaceItem {
        shellSurface: modelData
        onSurfaceDestroyed: shellSurfaces.remove(index)
    }
}

我们在模型中的每个shell表面处创建一个 ShellSurfaceItem,并将它们分配给 shellSurface 属性。此外,我们确保在shell表面被销毁时更新模型。这可能发生在客户端手动关闭窗口时,如果它退出或崩溃。

这就是使用 Qt Quick 和 QML 创建功能-rich Wayland 合成器所需的所有代码。对于另一个用 QML 编写的合成器(但具有更多功能)的示例,请参阅 高级合成器示例

项目示例 @ code.qt.io

© 2024 Qt 公司。此处包含的文档贡献的版权属于其各自的所有者。此文档的提供受 GNU 自由文档许可证版本 1.3 的条款约束,该许可证由自由软件基金会发布。Qt 和相应的徽标是芬兰以及全世界上其他地区的 The Qt Company Ltd 的商标。所有其他商标均为其各自所有者的财产。