KWayland

connection_thread.h
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #ifndef WAYLAND_CONNECTION_THREAD_H
7 #define WAYLAND_CONNECTION_THREAD_H
8 
9 #include <QObject>
10 #include <QVector>
11 
12 #include <KWayland/Client/kwaylandclient_export.h>
13 
14 struct wl_display;
15 
16 namespace KWayland
17 {
18 /**
19  * @short KWayland Client.
20  *
21  * This namespace groups all classes related to the Client module.
22  *
23  * The main entry point into the KWayland::Client API is the ConnectionThread class.
24  * It allows to create a Wayland client connection either in a native way or wrap a
25  * connection created by the QtWayland QPA plugin.
26  *
27  * KWayland::Client provides one the one hand a low-level API to interact with the
28  * Wayland API, on the other hand an easy to use convenience API. Each class directly
29  * relates to a low-level Wayland type and allows direct casting into the type.
30  *
31  * On the convenience side KWayland::Client allows easy creation of objects, signals
32  * emitted for Wayland events and easy conversion from Qt to Wayland types.
33  *
34  * Once one has a ConnectionThread created, it's possible to setup a Registry to
35  * get a listing of all registered globals. For each global the Registry provides a convenience
36  * method to create the resource.
37  *
38  * @see ConnectionThread
39  * @see Registry
40  **/
41 namespace Client
42 {
43 /**
44  * @short Creates and manages the connection to a Wayland server.
45  *
46  * The purpose of this class is to create the connection to a Wayland server
47  * and to manage it. As the name suggests it's intended to move instances of
48  * this class into a dedicated thread. This also means that this class doesn't
49  * inherit QThread. In order to use it in a threaded way one needs to create a
50  * QThread and move the object there:
51  *
52  * @code
53  * ConnectionThread *connection = new ConnectionThread;
54  * QThread *thread = new QThread;
55  * connection->moveToThread(thread);
56  * thread->start();
57  * @endcode
58  *
59  * To finalize the initialization of the connection one needs to call @link ::initConnection @endlink.
60  * This starts an asynchronous connection initialization. In case the initialization
61  * succeeds the signal @link ::connected @endlink will be emitted, otherwise @link ::failed @endlink will
62  * be emitted:
63  *
64  * @code
65  * connect(connection, &ConnectionThread::connected, [connection] {
66  * qDebug() << "Successfully connected to Wayland server at socket:" << connection->socketName();
67  * });
68  * connect(connection, &ConnectionThread::failed, [connection] {
69  * qDebug() << "Failed to connect to Wayland server at socket:" << connection->socketName();
70  * });
71  * connection->initConnection();
72  * @endcode
73  *
74  * This class is also responsible for dispatching events. Whenever new data is available on
75  * the Wayland socket, it will be dispatched and the signal @link ::eventsRead @endlink is emitted.
76  * This allows further event queues in other threads to also dispatch their events.
77  *
78  * Furthermore this class flushes the Wayland connection whenever the QAbstractEventDispatcher
79  * is about to block.
80  *
81  * To disconnect the connection to the Wayland server one should delete the instance of this
82  * class and quit the dedicated thread:
83  *
84  * @code
85  * connection->deleteLater();
86  * thread->quit();
87  * thread->wait();
88  * @endcode
89  *
90  * In addition the ConnectionThread provides integration with QtWayland QPA plugin. For that
91  * it provides a static factory method:
92  *
93  * @code
94  * auto connection = ConnectionThread::fromApplication();
95  * @endcode
96  *
97  * The semantics of the ConnectionThread are slightly changed if it's integrated with QtWayland.
98  * The ConnectionThread does not hold the connection, does not emit connected or released signals
99  * (one can safely assume that the connection is valid when integrating with the Qt application),
100  * does not dispatch events. Given that the use case of the ConnectionThread is rather limited to
101  * a convenient API around wl_display to allow easily setup an own Registry in a QtWayland powered
102  * application. Also moving the ConnectionThread to a different thread is not necessarily recommended
103  * in that case as QtWayland holds it's connection in an own thread anyway.
104  *
105  **/
106 class KWAYLANDCLIENT_EXPORT ConnectionThread : public QObject
107 {
108  Q_OBJECT
109 public:
110  explicit ConnectionThread(QObject *parent = nullptr);
111  virtual ~ConnectionThread();
112 
113  /**
114  * Creates a ConnectionThread for the used QGuiApplication.
115  * This is an integration feature for QtWayland. On non-wayland platforms this method returns
116  * @c nullptr.
117  *
118  * The returned ConnectionThread will be fully setup, which means it manages a wl_display.
119  * There is no need to initConnection and the connected or failed signals won't be emitted.
120  * When the created ConnectionThread gets destroyed the managed wl_display won't be disconnected
121  * as that's managed by Qt.
122  *
123  * The returned ConnectionThread is not able to detect (protocol) error. The signal
124  * {@link errorOccurred} won't be emitted, {@link hasError} will return @c false, even if the
125  * actual connection held by QtWayland is on error. The behavior of QtWayland is to exit the
126  * application on error.
127  *
128  * @since 5.4
129  **/
130  static ConnectionThread *fromApplication(QObject *parent = nullptr);
131 
132  /**
133  * The display this ConnectionThread is connected to.
134  * As long as there is no connection this method returns @c null.
135  * @see initConnection
136  **/
137  wl_display *display();
138  /**
139  * @returns the name of the socket it connects to.
140  **/
141  QString socketName() const;
142  /**
143  * Sets the @p socketName to connect to.
144  * Only applies if called before calling initConnection.
145  * The default socket name is derived from environment variable WAYLAND_DISPLAY
146  * and if not set is hard coded to "wayland-0".
147  *
148  * The socket name will be ignored if a file descriptor has been set through @link setSocketFd @endlink.
149  *
150  * @see setSocketFd
151  **/
152  void setSocketName(const QString &socketName);
153  /**
154  * Sets the socket @p fd to connect to.
155  * Only applies if called before calling initConnection.
156  * If this method is invoked, the connection will be created on the file descriptor
157  * and not on the socket name passed through @link setSocketName @endlink or through the
158  * default environment variable WAYLAND_DISPLAY.
159  * @see setSocketName
160  **/
161  void setSocketFd(int fd);
162 
163  /**
164  * Trigger a blocking roundtrip to the Wayland server. Ensures that all events are processed
165  * before returning to the event loop.
166  *
167  * @since 5.4
168  **/
169  void roundtrip();
170 
171  /**
172  * @returns whether the Wayland connection experienced an error
173  * @see errorCode
174  * @see errorOccurred
175  * @since 5.23
176  **/
177  bool hasError() const;
178 
179  /**
180  * @returns the error code of the last occurred error or @c 0 if the connection doesn't have an error
181  * @see hasError
182  * @see errorOccurred
183  * @since 5.23
184  **/
185  int errorCode() const;
186 
187  /**
188  * @returns all connections created in this application
189  * @since 5.37
190  **/
191  static QVector<ConnectionThread *> connections();
192 
193 public Q_SLOTS:
194  /**
195  * Initializes the connection in an asynchronous way.
196  * In case the connection gets established the signal @link ::connected @endlink will be
197  * emitted, on failure the signal @link ::failed @endlink will be emitted.
198  *
199  * @see connected
200  * @see failed
201  **/
202  void initConnection();
203 
204  /**
205  * Explicitly flush the Wayland display.
206  * @since 5.3
207  **/
208  void flush();
209 
210 Q_SIGNALS:
211  /**
212  * Emitted once a connection to a Wayland server is established.
213  * Normally emitted after invoking initConnection(), but might also be
214  * emitted after re-connecting to another server.
215  **/
216  void connected();
217  /**
218  * Emitted if connecting to a Wayland server failed.
219  **/
220  void failed();
221  /**
222  * Emitted whenever new events are ready to be read.
223  **/
224  void eventsRead();
225  /**
226  * Emitted if the Wayland server connection dies.
227  * If the socket reappears, it is tried to reconnect.
228  **/
229  void connectionDied();
230  /**
231  * The Wayland connection experienced a fatal error.
232  * The ConnectionThread is no longer valid, no requests may be sent.
233  * This has the same effects as {@link connectionDied}.
234  *
235  * @see hasError
236  * @see errorCode
237  * @since 5.23
238  **/
239  void errorOccurred();
240 
241 protected:
242  /*
243  * Creates a connection thread from an existing wl_display object
244  * @see ConnectionThread::fromApplication
245  */
246  explicit ConnectionThread(wl_display *display, QObject *parent);
247 
248 private Q_SLOTS:
249  /**
250  * @internal
251  **/
252  void doInitConnection();
253 
254 private:
255  class Private;
257 };
258 }
259 }
260 
261 #endif
Creates and manages the connection to a Wayland server.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:52:00 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.