Sur cette page

QML minimal

Minimal QML est un exemple simple qui montre comment écrire un compositeur Wayland en QML.

QML minimal est un exemple de compositeur Wayland de type bureau qui met en œuvre une interface utilisateur complète ( Qt Wayland Compositor ) avec le moins de code possible. Le compositeur est implémenté à l'aide d'Qt Quick et de QML.

Compositeur QML minimal avec fenêtre client

L’objet WaylandCompositor

L'élément de niveau supérieur du compositeur est un ` WaylandCompositor`. Celui-ci représente le serveur Wayland lui-même et gère les connexions des clients à mesure qu'elles arrivent.

Par défaut, le serveur prend en charge le protocole Wayland de base pour communiquer avec les clients. Cependant, vous souhaiterez généralement prendre en charge une ou plusieurs extensions de ce protocole. Cela offre au client davantage d’outils pour influencer son rôle au sein du système de fenêtrage.

Qt prend en charge plusieurs extensions standard et courantes. De plus, il est facile de créer et de prendre en charge des extensions personnalisées, à condition que cette prise en charge puisse être intégrée à la fois dans le code client et dans le code serveur.

Extensions de shell

En règle générale, un compositeur prendra en charge au moins une extension de shell. Les extensions sont ajoutées au compositeur en les instanciant en tant qu’enfants directs de l’objet ` WaylandCompositor `. Elles seront automatiquement ajoutées à sa propriété ` extensions ` et diffusées aux clients lors de leur connexion.

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

L’exemple Minimal QML prend en charge trois shells différents : WlShell, XdgShell et IviApplication.

Un client peut se connecter à l’un ou l’autre de ces shells, qui servira alors de canal de communication entre le client et le compositeur pour certaines opérations, telles que la création de nouvelles fenêtres, la négociation de la taille, etc.

Lorsqu’un client crée une nouvelle surface, son extension active reçoit un signal à cet effet. Ce signal contient un argument ShellSurface. Selon l’extension qui a reçu le signal, cet argument sera une sous-classe de ShellSurface: respectivement WlShellSurface, XdgSurface ou IviSurface.

L’objet ` ShellSurface ` permet d’accéder aux fonctionnalités de l’extension du shell pour la surface spécifique. Dans l’exemple Minimal QML, nous souhaitons simplement ajouter le client à notre scène. Pour enregistrer l’existence de la nouvelle fenêtre, nous l’ajoutons à un simple ` ListModel ` à des fins de sauvegarde.

ListModel { id: shellSurfaces }

Création de la scène

La majeure partie du code nécessaire au compositeur est déjà prête. La dernière étape consiste à s’assurer que les applications sont bien visibles à l’écran.

Pour tous les compositeurs, nous devons définir au moins une sortie. Pour ce faire, nous instancions un objet ` WaylandOutput ` en tant qu’enfant direct de ` WaylandCompositor`. S’il n’y a qu’une seule sortie, celle-ci représentera l’écran principal du système. (Vous pouvez également créer plusieurs objets ` WaylandOutput ` pour gérer plusieurs écrans s’ils sont disponibles. Consultez l’exemple « Multi Screen » pour plus de détails à ce sujet.)

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

À l’intérieur de l’ WaylandOutput, nous créons une fenêtre (Window) qui sert de conteneur à notre scène. Dans l’exemple, nous lui attribuons une taille. Cette taille est utilisée si le compositeur s’exécute en tant qu’application au sein d’un autre système de fenêtrage prenant en charge les fenêtres de taille personnalisée. Dans un cas d’utilisation classique sur un appareil embarqué, où le compositeur est le seul serveur d’affichage en cours d’exécution, celui-ci fonctionnera probablement sur un plugin de plateforme en plein écran (tel que eglfs) et la taille définie ici n’aura aucune importance.

La dernière étape consiste à créer des éléments pour chacun des objets ` ShellSurface ` qui ont été créés. Pour cela, nous pouvons utiliser la classe ` 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)
    }
}

Nous créons un ` ShellSurfaceItem ` pour chacune des surfaces de coque de notre modèle, et nous les attribuons à la propriété ` shellSurface `. De plus, nous veillons à ce que le modèle soit mis à jour lorsque la surface de coque est détruite. Cela peut se produire lorsqu’un client ferme manuellement une fenêtre, ou si celui-ci se déconnecte ou plante.

Et voilà tout le code nécessaire pour créer un compositeur Wayland fonctionnel à l’aide d’ Qt Quick et de QML. Pour découvrir un autre exemple de compositeur écrit en QML mais dotant de quelques fonctionnalités supplémentaires, jetez un œil à l’exemple Fancy Compositor.

Projet d’exemple sur code.qt.io

© 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.