README.md
1# Wrapland
2
3Wrapland is a Qt/C++ library that wraps and mediates the libwayland client and server API for its
4consumers. Wrapland is an independent part of the [KWinFT project][kwinft-project] with the KWinFT
5window manager being Wrapland's first and most prominent user.
6
7## Introduction
8
9Wrapland provides two libraries:
10
11- Wrapland::Client
12- Wrapland::Server
13
14As the names suggest they implement a Client respectively a Server API for the Wayland
15protocol. The API is Qt-styled removing the needs to interact with a for a Qt developer
16uncomfortable low-level C-API. For example the callback mechanism from the Wayland API
17is replaced by signals; data types are adjusted to be what a Qt developer expects, e.g.
18two arguments of int are represented by a QPoint or a QSize.
19
20## Wrapland Server
21
22### Head-less API
23
24The server library can be used to implement a Wayland server with Qt. The API is head-less
25meaning it does not perform any output and does not restrict on the way how one wants to
26render. This allows to easily integrate in existing rendering code based on e.g. OpenGL or
27QPainter. Applications built on top of Wrapland Server integrated the graphics with the
28following technologies:
29
30- OpenGL over DRM/KMS
31- OpenGL over X11
32- OpenGL over Wayland
33- OpenGL over Android's hwcomposer enabled through libhybris
34- QPainter over DRM/KMs
35- QPainter over fbdev
36- QPainter over X11
37- QPainter over Wayland
38- QWidget
39- QtQuick
40
41Although the library does not perform any output, it makes it very easy to enable rendering.
42The representation for a [Buffer](@ref Wrapland::Server::BufferInterface) allows easy conversion
43to a (memory-shared) QImage in case the buffer represents a shared memory buffer. This QImage
44can be used for rendering in a QPainter based API or to generate an OpenGL texture.
45
46### Easy usage of Wayland API
47
48The library hides many Wayland implementation details. For all Wayland interfaces which have
49double buffered state the classes always only provide access to the committed state. The pending
50state is an internal detail. On commit of the pending state Qt signals are emitted about what
51changed.
52
53Buffers are ref-counted and automatically released if it is no longer referenced allowing the
54client to reuse it. This happens fully automatically when a surface no longer references a buffer.
55As long as a buffer is attached surface, the surface has it referenced and the user of the API can
56access the buffer without needing to care about referencing it.
57
58The API of Wrapland is hand-crafted to make usage easier. The representation of a
59[Surface](@ref Wrapland::Server::SurfaceInterface) combines multiple aspects about a Surface even
60if in Wayland API it is added to other elements. E.g. a Surface contains all
61[SubSurfaces](@ref Wrapland::Server::SubSurfaceInterface) attached to it instead of the user
62having to monitor for which Surface a SubSurface got created.
63
64Similar the representation of a [Seat](@ref Wrapland::Server::SeatInterface) combines all aspects of
65the Seat. A user of the API only needs to interact with the Seat, there is no need to track all the
66created [keyboards](@ref Wrapland::Server::KeyboardInterface), [pointers](@ref Wrapland::Server::PointerInterface), etc. The
67representation of Seat tracks which keyboards are generated and is able to forward events to the
68proper focus surface, send enter and leave notifications when needed without the user of the API
69to care about it.
70
71### Handling input events
72
73Just like with output the server API does not restrict on how to get input events. This allows to
74integrate with existing input handlers and also allows to easily filter the input before it is passed
75to the server and from there delegated to the client. By that one can filter out e.g. global touch
76gestures or keyboard shortcuts without having to implement handlers inside Wrapland. The SeatInterface
77provides a very easy to use API to forward events which can be easily integrated with Qt's own
78input event system, e.g. there is a mapping from Qt::MouseButton to the Linux input code.
79
80Applications built on top of Wrapland Server integrated input events with the following technologies:
81
82- libinput
83- X11
84- Wayland
85- Android's inputstack enabled through libhybris
86- QInputEvent
87
88### Private IPC with child processes
89
90Wrapland Server is well suited for having a private IPC with child processes. The [Display](@ref Wrapland::Server::Display) can be
91setup in a way that it doesn't create a public socket but only allows connections through socket
92pairs. This allows to create a socketpair, pass one file descriptor to Wrapland server and the other
93to the forked process, e.g. through the WAYLAND_SOCKET environment variable. Thus a dedicated IPC
94is created which can be used even for running your own custom protocol. For example KDE Plasma uses
95such a dedicated parent-child Wayland server in it's screen locker architecture.
96
97Of course private sockets can be added at any time in addition to a publicly available socket. This
98can be used to recognize specific clients and to restrict access to interfaces for only some dedicated
99clients.
100
101## Wrapland Client
102
103The idea around Wrapland Client is to provide a drop-in API for the Wayland client library which at
104the same time provides convenience Qt-style API. It is not intended to be used as a replacement for
105the QtWayland QPA plugin, but rather as a way to interact with Wayland in case one needs Qt to use
106a different QPA plugin or in combination with QtWayland to allow a more low-level interaction without
107requiring to write C code.
108
109### Convenience API
110
111The convenience API in Wrapland Client provides one class wrapping a Wayland object. Each class can
112be casted into the wrapped Wayland type. The API represents events as signals and provides simple
113method calls for requests.
114
115Classes representing global Wayland resources can be created through the [Registry](@ref Wrapland::Client::Registry). This class eases
116the interaction with the Wayland registry and emits signals whenever a new global is announced or gets
117removed. The Registry has a list of known interfaces (e.g. common Wayland protocols like `wl_compositor`
118or `wl_shell`) which have dedicated announce/removed signals and objects can be factored by the Registry
119for those globals.
120
121Many globals function as a factory for further resources. E.g. the Compositor has a factory method for
122Surfaces. All objects can also be created in a low-level way interacting directly with the Wayland API,
123but provide convenience factory methods in addition. This allows both an easy usage or a more low level
124control of the Wayland API if needed.
125
126### Integration with QtWayland QPA
127
128If the QGuiApplication uses the QtWayland QPA, Wrapland allows to integrate with it. That is one does
129not need to create a new connection to the Wayland server, but can reuse the one used by Qt. If there
130is a way to get a Wayland object from Qt, the respective class provides a static method normally called
131`fromApplication`. In addition the API allows to get the Surface from a QWindow.
132
133## Using Wrapland in your application
134
135> :warning: There is for the forseeable future no API/ABI-stability guarantee. You need to align
136> your releases with Wrapland's release schedule and track breaking changes (announced in the
137> changelog).
138
139Wrapland releases are aligned with Plasma releases. See the [Plasma schedule][plasma-schedule] for
140information on when the next new major version is released from master branch or a minor release
141with changes from one of the bug-fix branches.
142
143### With CMake
144
145Wrapland installs a CMake Config file which allows to use Wrapland as imported targets. There is
146one library for Client and one for Server.
147
148To find the package use for example:
149
150 find_package(Wrapland CONFIG)
151 set_package_properties(Wrapland PROPERTIES TYPE OPTIONAL )
152 add_feature_info("Wrapland" Wrapland_FOUND "Required for my Wayland app")
153
154Now to link against the Client library use:
155
156 add_executable(exampleApp example.cpp)
157 target_link_libraries(exampleApp Wrapland::Client)
158
159To link against the Server library use:
160
161 add_executable(exampleServer exampleServer.cpp)
162 target_link_libraries(exampleServer Wrapland::Server)
163
164### With QMake
165
166Wrapland installs .pri files for the Client and Server library allowing easy usage in QMake based
167applications.
168
169Just use:
170
171 QT += Wrapland::Client
172
173Respectively:
174
175 QT += Wrapland::Server
176
177Please make sure that your project is configured with C++11 support:
178
179 CONFIG += c++11
180
181[kwinft-project]: https://gitlab.com/kwinft
182[plasma-schedule]: https://community.kde.org/Schedules/Plasma_5
183