- Notifications
You must be signed in to change notification settings - Fork2
Qt/C++ library wrapping libwayland
License
winft/wrapland
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Wrapland is a Qt/C++ library that wraps and mediates the libwayland client and server API for itsconsumers. Wrapland is an independent part of theWinFT project withThe Compositor Modules being Wrapland's most prominent user.
Wrapland provides two libraries:
- Wrapland::Client
- Wrapland::Server
As the names suggest they implement a Client respectively a Server API for the Waylandprotocol. The API is Qt-styled removing the needs to interact with a for a Qt developeruncomfortable low-level C-API. For example the callback mechanism from the Wayland APIis replaced by signals; data types are adjusted to be what a Qt developer expects, e.g.two arguments of int are represented by a QPoint or a QSize.
The server library can be used to implement a Wayland server with Qt. The API is head-lessmeaning it does not perform any output and does not restrict on the way how one wants torender. This allows to easily integrate in existing rendering code based on e.g. OpenGL orQPainter. Applications built on top of Wrapland Server integrated the graphics with thefollowing technologies:
- OpenGL over DRM/KMS
- OpenGL over X11
- OpenGL over Wayland
- OpenGL over Android's hwcomposer enabled through libhybris
- QPainter over DRM/KMs
- QPainter over fbdev
- QPainter over X11
- QPainter over Wayland
- QWidget
- QtQuick
Although the library does not perform any output, it makes it very easy to enable rendering.The representation for a [Buffer](@ref Wrapland::Server::BufferInterface) allows easy conversionto a (memory-shared) QImage in case the buffer represents a shared memory buffer. This QImagecan be used for rendering in a QPainter based API or to generate an OpenGL texture.
The library hides many Wayland implementation details. For all Wayland interfaces which havedouble buffered state the classes always only provide access to the committed state. The pendingstate is an internal detail. On commit of the pending state Qt signals are emitted about whatchanged.
Buffers are ref-counted and automatically released if it is no longer referenced allowing theclient to reuse it. This happens fully automatically when a surface no longer references a buffer.As long as a buffer is attached surface, the surface has it referenced and the user of the API canaccess the buffer without needing to care about referencing it.
The API of Wrapland is hand-crafted to make usage easier. The representation of a[Surface](@ref Wrapland::Server::SurfaceInterface) combines multiple aspects about a Surface evenif in Wayland API it is added to other elements. E.g. a Surface contains all[SubSurfaces](@ref Wrapland::Server::SubSurfaceInterface) attached to it instead of the userhaving to monitor for which Surface a SubSurface got created.
Similar the representation of a [Seat](@ref Wrapland::Server::SeatInterface) combines all aspects ofthe Seat. A user of the API only needs to interact with the Seat, there is no need to track all thecreated [keyboards](@ref Wrapland::Server::KeyboardInterface), [pointers](@ref Wrapland::Server::PointerInterface), etc. Therepresentation of Seat tracks which keyboards are generated and is able to forward events to theproper focus surface, send enter and leave notifications when needed without the user of the APIto care about it.
Just like with output the server API does not restrict on how to get input events. This allows tointegrate with existing input handlers and also allows to easily filter the input before it is passedto the server and from there delegated to the client. By that one can filter out e.g. global touchgestures or keyboard shortcuts without having to implement handlers inside Wrapland. The SeatInterfaceprovides a very easy to use API to forward events which can be easily integrated with Qt's owninput event system, e.g. there is a mapping from Qt::MouseButton to the Linux input code.
Applications built on top of Wrapland Server integrated input events with the following technologies:
- libinput
- X11
- Wayland
- Android's inputstack enabled through libhybris
- QInputEvent
Wrapland Server is well suited for having a private IPC with child processes. The [Display](@ref Wrapland::Server::Display) can besetup in a way that it doesn't create a public socket but only allows connections through socketpairs. This allows to create a socketpair, pass one file descriptor to Wrapland server and the otherto the forked process, e.g. through the WAYLAND_SOCKET environment variable. Thus a dedicated IPCis created which can be used even for running your own custom protocol. For example KDE Plasma usessuch a dedicated parent-child Wayland server in it's screen locker architecture.
Of course private sockets can be added at any time in addition to a publicly available socket. Thiscan be used to recognize specific clients and to restrict access to interfaces for only some dedicatedclients.
The idea around Wrapland Client is to provide a drop-in API for the Wayland client library which atthe same time provides convenience Qt-style API. It is not intended to be used as a replacement forthe QtWayland QPA plugin, but rather as a way to interact with Wayland in case one needs Qt to usea different QPA plugin or in combination with QtWayland to allow a more low-level interaction withoutrequiring to write C code.
The convenience API in Wrapland Client provides one class wrapping a Wayland object. Each class canbe casted into the wrapped Wayland type. The API represents events as signals and provides simplemethod calls for requests.
Classes representing global Wayland resources can be created through the [Registry](@ref Wrapland::Client::Registry). This class easesthe interaction with the Wayland registry and emits signals whenever a new global is announced or getsremoved. The Registry has a list of known interfaces (e.g. common Wayland protocols likewl_compositor
orwl_shell
) which have dedicated announce/removed signals and objects can be factored by the Registryfor those globals.
Many globals function as a factory for further resources. E.g. the Compositor has a factory method forSurfaces. All objects can also be created in a low-level way interacting directly with the Wayland API,but provide convenience factory methods in addition. This allows both an easy usage or a more low levelcontrol of the Wayland API if needed.
If the QGuiApplication uses the QtWayland QPA, Wrapland allows to integrate with it. That is one doesnot need to create a new connection to the Wayland server, but can reuse the one used by Qt. If thereis a way to get a Wayland object from Qt, the respective class provides a static method normally calledfromApplication
. In addition the API allows to get the Surface from a QWindow.
⚠️ There is for the forseeable future no API/ABI-stability guarantee. You need to alignyour releases with Wrapland's release schedule and track breaking changes (announced in thechangelog).
Wrapland releases are aligned with Plasma releases. See thePlasma schedule forinformation on when the next new major version is released from master branch or a minor releasewith changes from one of the bug-fix branches.
Wrapland installs a CMake Config file which allows to use Wrapland as imported targets. There isone library for Client and one for Server.
To find the package use for example:
find_package(Wrapland CONFIG)set_package_properties(Wrapland PROPERTIES TYPE OPTIONAL )add_feature_info("Wrapland" Wrapland_FOUND "Required for my Wayland app")
Now to link against the Client library use:
add_executable(exampleApp example.cpp)target_link_libraries(exampleApp Wrapland::Client)
To link against the Server library use:
add_executable(exampleServer exampleServer.cpp)target_link_libraries(exampleServer Wrapland::Server)
Wrapland installs .pri files for the Client and Server library allowing easy usage in QMake basedapplications.
Just use:
QT += Wrapland::Client
Respectively:
QT += Wrapland::Server
Please make sure that your project is configured with C++11 support:
CONFIG += c++11
About
Qt/C++ library wrapping libwayland