Compositeur QtShell
QtShell Compositor montre comment utiliser l'extension shell QtShell.
QtShell Compositor est un exemple de compositeur Wayland de type bureau qui met en œuvre une version complète de Qt Wayland Compositor qui utilise le protocole d'extension shell spécialisé appelé QtShell.

Le compositeur est implémenté avec Qt Quick et QML.
Établir la connexion
L'exemple indique que QtShell est la seule extension de l'objet WaylandCompositor. Cela signifie que tout client se connectant au serveur doit également prendre en charge cette extension, et qu'il doit donc s'agir d'applications Qt fonctionnant avec la même version de Qt que le compositeur.
QtShell { onQtShellSurfaceCreated: (qtShellSurface) => screen.handleShellSurface(qtShellSurface) }
Lorsqu'un client se connecte à l'interface QtShell, il crée un objet QtShellSurface. Le compositeur en est informé par l'émission du signal qtShellSurfaceCreated. L'exemple ajoute ensuite la surface de la coquille à un ListModel pour faciliter l'accès ultérieur.
property ListModel shellSurfaces: ListModel {} function handleShellSurface(shellSurface) { shellSurfaces.append({shellSurface: shellSurface}); }
Le ListModel est utilisé comme modèle pour un Repeater qui crée les éléments Qt Quick nécessaires pour afficher le contenu du client à l'écran.
Repeater { id: chromeRepeater model: output.shellSurfaces // Chrome displays a shell surface on the screen (See Chrome.qml) Chrome { shellSurface: modelData onClientDestroyed: { output.shellSurfaces.remove(index) } } }
Il utilise le type local Chrome, qui gère les états et les décorations de la fenêtre.
Chrome
Le type Chrome garantit que le contenu du client est visible et gère également l'état de la fenêtre, la position, la taille, etc. Il utilise comme base le type intégré QtShellChrome, qui gère automatiquement l'état de la fenêtre (maximisée, minimisée, plein écran) et l'activation de la fenêtre (en veillant à ce qu'une seule fenêtre soit active à la fois).
Son comportement peut être personnalisé dans une certaine mesure, mais il est également possible d'écrire la fonctionnalité Chrome à partir de zéro, en construisant à la place un type de base Item. QtShellChrome est une classe de commodité qui fournit le comportement typique d'un compositeur, et nous évite d'avoir à implémenter cette logique dans l'exemple.
Quelle que soit la façon dont Chrome est écrit, il doit avoir un ShellSurfaceItem pour contenir le contenu du client.
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: shellSurfaceItemId
Le ShellSurfaceItem est la représentation visuelle du contenu du client dans la scène Qt Quick. Sa taille doit généralement correspondre à la taille de la mémoire tampon du client, sinon elle risque d'être étirée ou comprimée. QtShellChrome sera automatiquement dimensionné en fonction du windowGeometry de QtShellSurface, qui correspond à la taille de la mémoire tampon du client plus la taille des marges de la trame. Les marges du cadre sont des zones réservées sur les côtés de Chrome qui peuvent être utilisées pour contenir des décorations de fenêtre.
Le site ShellSurfaceItem est donc ancré aux décorations de la fenêtre pour remplir la zone réservée à la mémoire tampon du client.
Décorations de fenêtres
La décoration de fenêtre est généralement un cadre autour du contenu d'un client qui ajoute des informations (comme un titre de fenêtre) et la possibilité d'une interaction avec l'utilisateur (comme le redimensionnement, la fermeture, le déplacement de la fenêtre, etc.)
Avec QtShell, les décorations de fenêtre sont toujours dessinées par le compositeur et non par le client. Pour que les tailles et les positions soient communiquées correctement, QtShell doit également savoir quelle partie de la fenêtre est réservée à ces décorations. Cela peut être géré automatiquement par QtShellChrome, ou manuellement, en paramétrant frameMarginLeft, frameMarginRight, frameMarginTop et frameMarginBottom.
Dans les cas typiques où il y a des poignées de redimensionnement autour de la fenêtre et une barre de titre en haut, il est plus pratique de s'appuyer sur les marges de cadre par défaut. C'est ce que fait l'exemple du compositeur QtShell.
Tout d'abord, nous créons des éléments Qt Quick pour représenter les différentes parties des décorations de la fenêtre. Sur le côté gauche, par exemple, il doit y avoir une poignée de redimensionnement que l'utilisateur peut saisir et faire glisser pour redimensionner la fenêtre.
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 }
Dans l'exemple, il s'agit simplement d'un rectangle de cinq pixels de large, ancré en haut, en bas et sur le côté gauche de la page Chrome.
De même, nous ajoutons des éléments Qt Quick qui représentent les poignées de redimensionnement droite, supérieure, inférieure, supérieure-gauche, supérieure-droite, inférieure-gauche et inférieure-droite. Nous ajoutons également une barre de titre. Lorsque les décorations ont été créées et ancrées correctement sur les côtés de Chrome, nous définissons les propriétés correspondantes dans QtShellChrome.
leftResizeHandle: leftResizeHandle rightResizeHandle: rightResizeHandle topResizeHandle: topResizeHandle bottomResizeHandle: bottomResizeHandle bottomLeftResizeHandle: bottomLeftResizeHandle bottomRightResizeHandle: bottomRightResizeHandle topLeftResizeHandle: topLeftResizeHandle topRightResizeHandle: topRightResizeHandle titleBar: titleBar
Lorsque les propriétés des décorations sont définies, le comportement de redimensionnement et de repositionnement par défaut est ajouté automatiquement. L'utilisateur pourra interagir avec les poignées de redimensionnement pour redimensionner la fenêtre et faire glisser la barre de titre pour la repositionner. Les marges du cadre du site QtShellSurface seront également définies automatiquement pour tenir compte de la taille des décorations (à condition qu'aucune des propriétés de marge du cadre n'ait été définie explicitement).
La visibilité des décorations sera gérée automatiquement par QtShellChrome en fonction des drapeaux de fenêtre de QtShellSurface.
Gestion des fenêtres
Dans le cadre des décorations, il est courant d'avoir des boutons d'outils qui gèrent l'état et la durée de vie de la fenêtre. Dans l'exemple, ces boutons sont ajoutés à la barre de titre.
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() } }
La visibilité de chaque bouton est conditionnée par l'indicateur de fenêtre de ce bouton, et lorsque l'on clique sur l'un d'eux, on appelle simplement la méthode correspondante dans QtShellChrome. L'exception est le bouton "close", qui appelle la méthode sendClose() dans QtShellSurface. Cette méthode demande au client de se fermer, ce qui garantit un arrêt en douceur de l'application.
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() } } } }
Comme outil supplémentaire de gestion des fenêtres, l'exemple dispose d'une "barre des tâches". Il s'agit simplement d'une rangée de boutons d'outils en bas avec les titres des fenêtres. Il est possible de cliquer sur ces boutons pour réduire la taille des applications et les mettre en avant si elles sont masquées par d'autres fenêtres. Comme pour le site Chrome, nous utilisons un site Repeater pour créer les boutons d'outils et nous nous servons de la liste des surfaces de la coquille comme modèle. Pour des raisons de simplicité, l'exemple ne gère pas le débordement (lorsqu'il y a trop d'applications pour la barre des tâches), mais dans un compositeur approprié, c'est également un élément à prendre en compte.
Enfin, pour éviter que les applications maximisées ne remplissent la zone couverte par la barre des tâches, nous créons un élément spécial pour gérer les parties de la zone WaylandOutput qui sont disponibles pour les fenêtres clientes.
Item { id: usableArea anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right anchors.bottom: taskbar.top }
Il est simplement ancré sur les côtés de WaylandOutput, mais son ancrage inférieur se trouve en haut de la barre des tâches.
Dans Chrome, nous utilisons cette zone pour définir la maximizedRect de la fenêtre.
maximizedRect: Qt.rect(usableArea.x, usableArea.y, usableArea.width, usableArea.height)
Par défaut, cette propriété correspondra à l'intégralité de WaylandOutput. Dans notre cas, cependant, nous ne voulons pas inclure la barre des tâches dans la zone disponible, c'est pourquoi nous remplaçons la valeur par défaut.
© 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.