QtShell Compositor
QtShell Compositorでは、QtShell シェル拡張機能の使用方法を示しています。
QtShell Compositorは、QtShell と呼ばれる専用のシェル拡張プロトコルを使用する完全なQt Wayland Compositor を実装した、デスクトップスタイルのWaylandコンポジターのサンプルです。

このコンポジターは、Qt Quick およびQMLを用いて実装されています。
接続の確立
このサンプルでは、WaylandCompositor オブジェクトに対する唯一の拡張機能としてQtShell が指定されています。これは、サーバーに接続するクライアントもこの拡張機能をサポートしている必要があることを意味します。したがって、クライアントはコンポジターと同じバージョンのQtで動作するQtアプリケーションである必要があります。
QtShell {
onQtShellSurfaceCreated: (qtShellSurface) => screen.handleShellSurface(qtShellSurface)
}クライアントがQtShell インターフェースに接続すると、QtShellSurface が作成されます。これにより、qtShellSurfaceCreated シグナルがエミッションされ、コンポジターに通知されます。その後、この例では、後で簡単にアクセスできるように、シェルサーフェスをListModel に追加します。
property ListModel shellSurfaces: ListModel {}
function handleShellSurface(shellSurface) {
shellSurfaces.append({shellSurface: shellSurface});
}ListModel は、クライアントのコンテンツを画面に表示するために必要なQt Quick 項目を作成するRepeater のモデルとして使用されます。
Repeater {
id: chromeRepeater
model: output.shellSurfaces
// Chrome displays a shell surface on the screen (See Chrome.qml)
Chrome {
shellSurface: modelData
onShellSurfaceChanged: {
if (!shellSurface)
output.shellSurfaces.remove(index)
}
}
}ここでは、ウィンドウの状態や装飾を処理するローカルなChrome 型が使用されます。
Chrome
Chrome は、クライアントコンテンツが確実に表示されるようにし、ウィンドウの状態、位置、サイズなどを処理するタイプです。これは、ウィンドウの状態(最大化、最小化、フルスクリーン)やウィンドウのアクティブ化(一度に 1 つのウィンドウのみがアクティブになるようにする)を自動的に処理する、組み込みのQtShellChrome をベースにしています。
その動作はある程度カスタマイズ可能ですが、基本的なItem 型を基に、Chrome の機能を一から実装することも可能です。QtShellChrome は、典型的なコンポジターの動作を提供する利便性向上のためのクラスであり、この例ではこのロジックを実装する手間を省いてくれます。
Chrome がどのように記述されるにせよ、クライアントのコンテンツを保持するためのShellSurfaceItem を持つ必要があります。
ShellSurfaceItem {
id: shellSurfaceItemId
anchors.top: titleBar.bottom
anchors.bottom: bottomResizeHandle.top
anchors.left: leftResizeHandle.right
anchors.right: rightResizeHandle.left
moveItem: chrome
staysOnBottom: shellSurface.windowFlags & Qt.WindowStaysOnBottomHint
staysOnTop: !staysOnBottom && shellSurface.windowFlags & Qt.WindowStaysOnTopHint
}
shellSurfaceItem: shellSurfaceItemIdShellSurfaceItem は、Qt Quick シーンにおけるクライアントコンテンツの視覚的表現です。そのサイズは通常、クライアントのバッファのサイズと一致している必要があります。そうしないと、コンテンツが引き伸ばされたり、圧縮されたりして見える可能性があります。QtShellChrome は、QtShellSurface のwindowGeometry (クライアントのバッファのサイズにフレームのマージンのサイズを加えたもの)に合わせて自動的にサイズ調整されます。 フレームマージンとは、Chrome の側面に確保された領域であり、ウィンドウの装飾を配置するために使用できます。
したがって、ShellSurfaceItem は、クライアントバッファ用に確保された領域を埋めるように、ウィンドウ装飾にアンカーされます。
ウィンドウ装飾
ウィンドウ装飾は通常、クライアントのコンテンツを囲む枠であり、情報(ウィンドウタイトルなど)を追加したり、ユーザーによる操作(ウィンドウのサイズ変更、閉じる、移動など)を可能にしたりするものです。
QtShell を使用すると、ウィンドウ装飾は常にコンポジターによって描画され、クライアントによって描画されることはありません。サイズや位置が正しく伝達されるためには、QtShell も、ウィンドウのどの部分がこれらの装飾のために確保されているかを知る必要があります。これは、QtShellChrome によって自動的に処理されるか、frameMarginLeft 、frameMarginRight 、frameMarginTop 、frameMarginBottom を設定することで手動で処理することができます。
ウィンドウの周囲にサイズ変更ハンドルがあり、上部にタイトルバーがあるという一般的なケースでは、デフォルトのフレームマージンを使用するのが便利です。QtShell のCompositorサンプルでは、この方法を採用しています。
まず、ウィンドウの装飾の各部分を表すQt Quick アイテムを作成します。例えば、左側には、ユーザーがウィンドウのサイズを変更するために掴んでドラッグできるサイズ変更ハンドルが必要です。
Rectangle {
id: leftResizeHandle
color: "gray"
width: visible ? 5 : 0
anchors.topMargin: 5
anchors.bottomMargin: 5
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
}この例では、これを単に幅5ピクセルの長方形として作成し、Chrome の上部、下部、左側に固定します。
同様に、右、上、下、左上、右上、左下、右下の各サイズ変更ハンドルを表すQt Quick アイテムを追加します。また、タイトルバーも追加します。装飾が作成され、Chrome の各辺に正しく固定されたら、QtShellChrome で対応するプロパティを設定します。
leftResizeHandle: leftResizeHandle
rightResizeHandle: rightResizeHandle
topResizeHandle: topResizeHandle
bottomResizeHandle: bottomResizeHandle
bottomLeftResizeHandle: bottomLeftResizeHandle
bottomRightResizeHandle: bottomRightResizeHandle
topLeftResizeHandle: topLeftResizeHandle
topRightResizeHandle: topRightResizeHandle
titleBar: titleBar装飾のプロパティが設定されると、デフォルトのサイズ変更および位置変更の挙動が自動的に追加されます。 ユーザーは、サイズ変更ハンドルを操作してウィンドウのサイズを変更したり、タイトルバーをドラッグしてウィンドウの位置を変更したりできるようになります。また、装飾のサイズを考慮して、QtShellSurface のフレームマージンも自動的に設定されます(フレームマージンのプロパティが明示的に設定されていない場合に限ります)。
装飾の表示/非表示は、QtShellSurface のウィンドウフラグに基づいて、QtShellChrome によって自動的に処理されます。
ウィンドウ管理
装飾の一部として、ウィンドウの状態やライフサイクルを管理するツールボタンが設けられることが一般的です。この例では、これらはタイトルバーに追加されています。
RowLayout {
id: rowLayout
anchors.right: parent.right
anchors.rightMargin: 5
ToolButton {
text: "-"
Layout.margins: 5
visible: (chrome.windowFlags & Qt.WindowMinimizeButtonHint) != 0
onClicked: {
chrome.toggleMinimized()
}
}
ToolButton {
text: "+"
Layout.margins: 5
visible: (chrome.windowFlags & Qt.WindowMaximizeButtonHint) != 0
onClicked: {
chrome.toggleMaximized()
}
}
ToolButton {
id: xButton
text: "X"
Layout.margins: 5
visible: (chrome.windowFlags & Qt.WindowCloseButtonHint) != 0
onClicked: shellSurface.sendClose()
}
}各ボタンの表示/非表示は、そのボタンに対応するウィンドウフラグによって決定され、各ボタンがクリックされると、単にQtShellChrome の対応するメソッドを呼び出します。例外は「閉じる」ボタンで、これはQtShellSurface 内のsendClose()メソッドを呼び出します。これにより、クライアントに自身を閉じるよう指示し、アプリケーションの正常な終了が保証されます。
Row {
id: taskbar
height: 40
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
Repeater {
anchors.fill: parent
model: output.shellSurfaces
ToolButton {
anchors.verticalCenter: parent.verticalCenter
text: modelData.windowTitle
onClicked: {
var item = chromeRepeater.itemAt(index)
if ((item.windowState & Qt.WindowMinimized) != 0)
item.toggleMinimized()
chromeRepeater.itemAt(index).activate()
}
}
}
}追加のウィンドウ管理ツールとして、このサンプルには「タスクバー」が備わっています。これは、ウィンドウのタイトルと共に画面下部に並ぶ一列のツールボタンです。他のウィンドウに隠れてしまったアプリケーションを、これらのボタンをクリックすることで最小化を解除し、最前面に表示させることができます。Chrome と同様に、ツールボタンの作成にはRepeater を使用し、そのモデルとしてシェルサーフェスリストを採用しています。簡略化のため、このサンプルではオーバーフロー(タスクバーに収まりきらないほど多くのアプリケーションが存在する場合)への対応は行っていませんが、適切なコンポジターでは、この点についても考慮する必要があります。
最後に、最大化されたアプリケーションがタスクバーが占める領域まで拡大して表示されるのを防ぐため、クライアントウィンドウが利用可能なWaylandOutput の領域を管理する特別な項目を作成します。
Item {
id: usableArea
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: taskbar.top
}これは単にWaylandOutput の両端にアンカーされているだけですが、その下部のアンカーはタスクバーの上端にあります。
Chrome では、この領域を使用してウィンドウのmaximizedRect を定義します。
maximizedRect: Qt.rect(usableArea.x,
usableArea.y,
usableArea.width,
usableArea.height)デフォルトでは、このプロパティはWaylandOutput 全体と一致します。しかし、このケースでは、利用可能な領域にタスクバーを含めたくないため、デフォルト値を上書きします。
© 2026 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.