En esta página

QML mínimo

Minimal QML es un ejemplo simple que demuestra cómo escribir un compositor Wayland en QML.

Minimal QML es un ejemplo de compositor Wayland de escritorio que implementa un Qt Wayland Compositor completo con la menor cantidad de código posible. El compositor se implementa con Qt Quick y QML.

El objeto WaylandCompositor

El objeto de nivel superior del compositor es un WaylandCompositor. Este representa el propio servidor Wayland y gestiona las conexiones con los clientes a medida que entran.

Por defecto, el servidor soporta el protocolo básico de Wayland para comunicarse con los clientes. Normalmente, sin embargo, también querrás soportar una o más extensiones del protocolo. Esto da al cliente más herramientas para influir en su papel en el sistema de ventanas.

Qt soporta varias extensiones estándar y comunes. Además, es fácil crear y soportar extensiones personalizadas, siempre que se pueda añadir soporte tanto en el código del cliente como en el del servidor.

Extensiones Shell

Normalmente, un compositor soportará al menos una extensión shell. Las extensiones se añaden al compositor instanciándolas como hijas directas del objeto WaylandCompositor. Se añadirán automáticamente a su propiedad extensions y se transmitirán a los clientes cuando se conecten.

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

El ejemplo Minimal QML admite tres conchas diferentes: WlShell XdgShell y IviApplication.

Un cliente puede conectarse a cualquiera de ellas y se utilizará como canal para comunicar ciertas cosas entre el cliente y el compositor, como la creación de nuevas ventanas, la negociación del tamaño, etc.

Cuando un cliente crea una nueva superficie, su extensión activa recibirá una señal de esto. La señal contiene un argumento ShellSurface. Dependiendo de la extensión que haya recibido la señal, este argumento será de una subclase de ShellSurface: WlShellSurface, XdgSurface o IviSurface respectivamente.

El ShellSurface se puede utilizar para acceder a las características de la extensión del shell para la superficie específica. En el ejemplo de Minimal QML, simplemente queremos añadir el cliente a nuestra escena. Para registrar la existencia de la nueva ventana, la añadimos a un simple ListModel para guardarla.

ListModel { id: shellSurfaces }

Creación de la escena

La mayor parte del código compositor necesario ya está listo. El paso final es asegurarse de que las aplicaciones son realmente visibles en la pantalla.

Para todos los compositores, tenemos que definir al menos una salida. Esto se hace instanciando un objeto WaylandOutput como hijo directo de WaylandCompositor. Si sólo hay una única salida, ésta representará la pantalla principal del sistema. (También puede crear varios objetos WaylandOutput para dirigirse a varias pantallas si están disponibles. Vea el ejemplo Multipantalla para más detalles sobre esto).

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

Dentro de WaylandOutput, creamos una Ventana que sirve como contenedor para nuestra escena. En el ejemplo, le damos un tamaño. El tamaño se utiliza si el compositor se está ejecutando como una aplicación dentro de otro sistema de ventanas que soporta ventanas de tamaño personalizado. En un caso de uso típico en un dispositivo integrado, donde el compositor es el único servidor de visualización en ejecución, probablemente se ejecutará en un plugin de plataforma de pantalla completa (como eglfs) y el tamaño establecido aquí no importará.

El último paso es crear elementos para cada uno de los objetos ShellSurface que se han creado. Para ello, podemos utilizar la clase 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)
    }
}

Creamos un ShellSurfaceItem para cada una de las superficies de la cáscara en nuestro modelo, y les asignamos a la propiedad shellSurface. Además, nos aseguramos de que el modelo se actualiza cuando se destruye la superficie de la carcasa. Esto puede suceder cuando un cliente cierra manualmente una ventana, y si sale o se bloquea.

Y este es todo el código necesario para crear un compositor Wayland funcional utilizando Qt Quick y QML. Para otro ejemplo de un compositor escrito en QML pero que tiene algunas características más, echa un vistazo al ejemplo Fancy Compositor.

Proyecto de ejemplo @ 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.