Sur cette page

QML minimal

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

Minimal QML est un exemple de compositeur Wayland de style bureautique qui implémente un Qt Wayland Compositor complet avec le moins de code possible. Le compositeur est implémenté avec Qt Quick et QML.

L'objet WaylandCompositor

L'élément de premier niveau du compositeur est un objet WaylandCompositor. Il représente le serveur Wayland lui-même et gère les connexions des clients à mesure qu'ils arrivent.

Par défaut, le serveur prend en charge le protocole principal de Wayland pour communiquer avec les clients. En général, vous voudrez également prendre en charge une ou plusieurs extensions du protocole. Cela donne au client plus d'outils pour influencer son rôle dans le système de fenêtrage.

Qt prend en charge plusieurs extensions standard et courantes. En outre, il est facile de créer et de prendre en charge des extensions personnalisées, à condition que la prise en charge puisse être ajoutée à la fois dans le code du client et dans celui du serveur.

Extensions du shell

En règle générale, un compositeur prend en charge au moins une extension 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 lorsqu'ils se connectent.

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

L'exemple QML minimal prend en charge trois shells différents : WlShell XdgShell et IviApplication.

Un client peut se connecter à l'un d'eux et il sera utilisé comme canal pour communiquer certaines choses entre le client et le compositeur, 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 de ce type. Le signal contient un argument ShellSurface. Selon l'extension qui a reçu le signal, cet argument sera d'une sous-classe de ShellSurface: WlShellSurface, XdgSurface ou IviSurface respectivement.

L'argument ShellSurface peut être utilisé pour accéder aux caractéristiques de l'extension shell pour la surface spécifique. Dans l'exemple QML minimal, nous voulons simplement ajouter le client à notre scène. Pour enregistrer l'existence de la nouvelle fenêtre, nous l'ajoutons à un simple ListModel pour la conserver.

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 effectivement visibles à l'écran.

Pour tous les compositeurs, nous devons définir au moins une sortie. Pour ce faire, il faut instancier un objet WaylandOutput en tant qu'enfant direct de l'objet WaylandCompositor. S'il n'y a qu'une seule sortie, elle représentera l'écran principal du système. (Vous pouvez également créer plusieurs objets WaylandOutput pour adresser plusieurs écrans s'ils sont disponibles. Voir 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'objet WaylandOutput, nous créons une fenêtre qui sert de conteneur à notre scène. Dans l'exemple, nous lui donnons une taille. La taille utilisée si le compositeur est exécuté en tant qu'application dans un autre système de fenêtrage qui prend en charge les fenêtres de taille personnalisée. Dans un cas d'utilisation typique sur un appareil embarqué, où le compositeur est le seul serveur d'affichage en cours d'exécution, il fonctionnera probablement sur un plugin de plateforme plein écran (tel que eglfs) et la taille définie ici n'aura pas d'importance.

La dernière étape consiste à créer des éléments pour chacun des objets ShellSurface qui ont été créés. Pour ce faire, 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 l'assignons à la propriété shellSurface. En outre, nous nous assurons que le modèle est mis à jour lorsque la surface de carapace est détruite. Cela peut se produire lorsqu'un client ferme manuellement une fenêtre, qu'il quitte ou qu'il se bloque.

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

Exemple de projet @ 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.