New Compositor API for Qt Wayland

As part of the forthcoming Qt 5.7, we are happy to be releasing a tech preview of the new Qt Wayland Compositor API. In this post, I'll give you an overview of the functionality along with few examples on how to create your own compositors with it.

Wayland is a light-weight display server protocol, designed to replace the X Window System. It is particularly relevant for embedded and mobile systems. Wayland support in Qt makes it possible to split your UI into different processes, increasing robustness and reliability. The compositor API allows you to create a truly custom UI for the display server. You can precisely control how to display information from the other processes, and also add your own GUI elements.

Qt Wayland has included a compositor API since the beginning, but this API has never been officially released. Now we have rewritten the API, making it more powerful and much easier to use.

Here’s a snapshot of a demo that we showed at Embedded World: it is a compositor containing a launcher and a tiling window manager, written purely in QML.

embedded

We will keep source and binary compatibility for all the 5.7.x patch releases, but since this is a tech preview, we will be adding non-compatible improvements to the API before the final release. The Qt Wayland Compositor API is actively developed in the dev branch of the Qt git repository.

The Qt Wayland Compositor tech preview will be included in the Qt for Device Creation packages. It is not part of the Qt for Application Development binary packages, but when compiling Qt from source, it is built by default, as long as Wayland 1.6 is installed.

What is new?

  • It is now possible to write an entire compositor in pure QML.
  • Improved API: Easier to understand, less code to write - both QML and C++ APIs
  • Completely reworked extension support: Extensions can be added with just a few lines of QML, and there’s a powerful, easy-to-use C++ API for writing your own extensions.
  • Multi-screen support
  • XDG-Shell support: Accept connections from non-Qt clients.
  • And finally, a change that is not visible in the API, but should make our lives easier as developers: We have streamlined the implementation and Qt Wayland now follows the standard Qt PIMPL(Q_DECLARE_PRIVATE) pattern

Take a look at the API documentation for more details.

Examples

Here is a complete, fully functional (but minimalistic) compositor, written purely in QML:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtWayland.Compositor 1.0

WaylandCompositor { id: wlcompositor // The output defines the screen. WaylandOutput { compositor: wlcompositor window: Window { visible: true WaylandMouseTracker { anchors.fill: parent enableWSCursor: true Rectangle { id: surfaceArea color: "#1337af" anchors.fill: parent } } } } // The chrome defines the window look and behavior. // Here we use the built-in ShellSurfaceItem. Component { id: chromeComponent ShellSurfaceItem { onSurfaceDestroyed: destroy() } } // Extensions are additions to the core Wayland // protocol. We choose to support two different // shells (window management protocols). When the // client creates a new window, we instantiate a // chromeComponent on the output. extensions: [ WlShell { onShellSurfaceCreated: chromeComponent.createObject(surfaceArea, { "shellSurface": shellSurface } ); }, XdgShell { onXdgSurfaceCreated: chromeComponent.createObject(surfaceArea, { "shellSurface": xdgSurface } ); } ] }

This is a stripped down version of the pure-qml example from the tech preview. And it really is a complete compositor: if you have built the tech preview, you can copy the text above, save it to a file, and run it through qmlscene:
minimalcompositor

These are the commands I used to create the scene above:

./bin/qmlscene foo.qml &
./examples/widgets/widgets/wiggly/wiggly -platform wayland &
weston-terminal &
./examples/opengl/qopenglwindow/qopenglwindow -platform wayland &

The Qt Wayland Compositor API can of course also be used for the desktop. The Grefsen compositor (https://github.com/ec1oud/grefsen) started out as a hackathon project here at the Qt Company, and Shawn has continued developing it afterwards:

grefsen

C++ API

The C++ API is a little bit more verbose. The minimal-cpp example included in the tech preview clocks in at 195 lines, excluding comments and whitespace. That does not get you mouse or keyboard input. The qwindow-compositor example is currently 743 lines, implementing window move/resize, drag and drop, popup support, and mouse cursors.

This complexity gives you the opportunity to define completely new interaction models. We found the time to port everyone’s favourite compositor to the new API:

mazecompositor

This is perhaps not the best introduction to writing a compositor with Qt, but the code is available:
git clone https://github.com/paulolav/mazecompositor.git

What remains to be done?

The main parts of the API are finished, but we expect some adjustments based on feedback from the tech preview.

There are still some known issues, detailed in QTBUG-48646 and on our Trello board.

The main unresolved API question is input handling.

How you can help

Try it out! Read the documentation, run the examples, play around with it, try it in your own projects, and give us feedback on anything that can be improved. You can find us on #qt-lighthouse on Freenode.


Blog Topics:

Comments