サーバーサイド装飾コンポジター

Server Side Decoration Compositor は、xdg-shell におけるサーバーサイドのウィンドウ装飾を示す簡単なサンプルです。

はじめに

Server Side Decoration Compositorはサーバーサイドのウィンドウ装飾を実装したデスクトップスタイルのWaylandコンポジターの例です。

QtでQt Wayland Compositorを作成するための基本原則については、Minimal QML exampleを参照してください。

装飾

ウィンドウの装飾とは、ウィンドウ・システムのほとんどのウィンドウに付随する追加のUIを指します。例えば、以下のようなものがあります:

  • ウィンドウの表面を囲むグラフィカルな枠。ユーザーがクリックしてドラッグすることで、ウィンドウのサイズを変更することができます。
  • ウィンドウのタイトルバー。ウィンドウを移動するために使われる。
  • ウィンドウを最大化、最小化、閉じるためのシステム・ツール・ボタン。

伝統的にWaylandでは、これらの装飾をレンダリングするのはクライアントの仕事でした。同時に、ウィンドウの位置、サイズ、状態はコンポジターの領域です。いくつかのシェル拡張はオプションでサーバーサイドの装飾をサポートします。これにより、コンポジターはクライアントにウィンドウの装飾を描画すべきではないことを伝えることができます。代わりに、コンポジターがウィンドウ装飾の描画を担当する。これは、macOS、Windows、X11などの他のウィンドウシステムで装飾がどのように処理されるかに対応しています。ある種のクライアントはこれをまったくサポートしていない可能性があることは注目に値する。システムがそのようなアプリケーションを実行することを想定している場合は、この点も考慮する必要があります。

サーバーサイドの装飾の利点:

  • クライアントはWaylandバッファにシステムUI用のスペースを確保する必要がありません。
  • Qt QuickやOpenGLベースのクライアントは、別個のFBOにレンダリングしてコンテンツをWaylandバッファにコピーする必要がありません。
  • クライアントのウィンドウは、どのUIツールキットが使用されているかに関係なく、一貫した外観を持ちます。
  • リサイズ、クローズ、ウィンドウの状態変更などのシステム機能は、サーバーとクライアントで共有するのではなく、サーバーに一元化されます。

コード

サンプルのコンポジターは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

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。