服务器端装饰合成器

服务器端装饰合成器是一个简单的示例,用于演示 xdg-shell 上的服务器端窗口装饰。

简介

服务器端装饰合成器是一个实现服务器端窗口装饰的桌面风格 Wayland 合成器示例。

有关使用 Qt 创建 Qt Wayland Compositor基本原理,请参阅Minimal QML 示例

装饰

窗口装饰指的是窗口系统中大多数窗口的附加用户界面。例如

  • 窗口表面周围的图形框架,用户可以点击并拖动它来调整窗口大小。
  • 窗口标题栏,可用于移动窗口。
  • 系统工具按钮,用于最大化、最小化和关闭窗口。

在 Wayland 中,呈现这些装饰一直是客户端的任务。与此同时,窗口的位置、大小和状态则由合成器负责。某些shell 扩展可选择支持服务器端装饰。这样,合成器就能向客户端说明,他们不应绘制自己的窗口装饰。相反,合成器负责绘制窗口装饰。这与其他窗口系统(如 macOS、Windows 和 X11)处理装饰的方式一致。值得注意的是,某些客户端可能完全不支持这种做法。如果系统要运行此类应用程序,则也应考虑到这一点。

服务器端装饰的好处:

  • 客户端无需在 Wayland 缓冲区为系统用户界面预留空间。
  • Qt Quick 客户端和基于 OpenGL 的客户端无需将内容渲染到单独的 FBO 并复制到 Wayland 缓冲区。
  • 无论使用哪种用户界面工具包,客户端窗口都将拥有一致的外观。
  • 系统功能(如调整大小、关闭和更改窗口状态)集中在服务器上,而不是在服务器和客户端之间共享。

代码

示例合成器仅支持XdgShell 扩展。它以常规方式初始化扩展,并将曲面添加到ListModel ,以便稍后访问。

XdgShell {
    onToplevelCreated: (toplevel, xdgSurface) => shellSurfaces.append({shellSurface: xdgSurface});
}
XdgDecorationManagerV1 {
    preferredMode: XdgToplevel.ServerSideDecoration
}

此外,示例还初始化了XdgDecorationManagerV1 扩展。这样,它就可以向客户端传达它更喜欢服务器端装饰的信息。

由于该接口是可选的,客户端可能不支持它,而总是绘制自己的装饰。因此,该模式只是 "首选 "模式,我们需要在装饰顶层窗口之前检查其实际模式。

Column {
    id: chrome
    width: shellSurfaceItem.implicitWidth
    Rectangle {
        visible: modelData.toplevel.decorationMode === XdgToplevel.ServerSideDecoration
        width: parent.width
        height: 30
        gradient: "HeavyRain";
        Text {
            text: modelData.toplevel.title
            anchors.centerIn: parent
        }
        Item {
            anchors.right: parent.right
            width: 30
            height: 30
            Text { text: "X"; anchors.centerIn: parent }
            TapHandler {
                onTapped: modelData.toplevel.sendClose()
            }
        }
        DragHandler {
            target: chrome
        }
    }
    ShellSurfaceItem {
        id: shellSurfaceItem
        moveItem: parent
        shellSurface: modelData
        onSurfaceDestroyed: shellSurfaces.remove(index)
    }
}

我们在每个窗口上方创建一个简单的标题栏。标题栏有一个渐变效果、一些文本、一个管理其位置的DragHandler 和一个关闭按钮。

图片左上方显示的是支持装饰管理器扩展的客户端,右下方显示的是带有客户端装饰的客户端。

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.