1 | /* |
2 | SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
5 | */ |
6 | #ifndef WAYLAND_SHELL_H |
7 | #define WAYLAND_SHELL_H |
8 | |
9 | #include <QObject> |
10 | #include <QPoint> |
11 | #include <QSize> |
12 | #include <QWindow> |
13 | |
14 | #include "KWayland/Client/kwaylandclient_export.h" |
15 | |
16 | struct wl_surface; |
17 | struct wl_shell; |
18 | struct wl_shell_surface; |
19 | |
20 | namespace KWayland |
21 | { |
22 | namespace Client |
23 | { |
24 | class EventQueue; |
25 | class ShellSurface; |
26 | class Output; |
27 | class Seat; |
28 | class Surface; |
29 | |
30 | /** |
31 | * @short Wrapper for the wl_shell interface. |
32 | * |
33 | * This class provides a convenient wrapper for the wl_shell interface. |
34 | * It's main purpose is to create a ShellSurface. |
35 | * |
36 | * To use this class one needs to interact with the Registry. There are two |
37 | * possible ways to create the Shell interface: |
38 | * @code |
39 | * Shell *s = registry->createShell(name, version); |
40 | * @endcode |
41 | * |
42 | * This creates the Shell and sets it up directly. As an alternative this |
43 | * can also be done in a more low level way: |
44 | * @code |
45 | * Shell *s = new Shell; |
46 | * s->setup(registry->bindShell(name, version)); |
47 | * @endcode |
48 | * |
49 | * The Shell can be used as a drop-in replacement for any wl_shell |
50 | * pointer as it provides matching cast operators. |
51 | * |
52 | * @see Registry |
53 | * @see ShellSurface |
54 | **/ |
55 | class KWAYLANDCLIENT_EXPORT Shell : public QObject |
56 | { |
57 | Q_OBJECT |
58 | public: |
59 | explicit Shell(QObject *parent = nullptr); |
60 | ~Shell() override; |
61 | |
62 | /** |
63 | * @returns @c true if managing a wl_shell. |
64 | **/ |
65 | bool isValid() const; |
66 | /** |
67 | * Releases the wl_shell interface. |
68 | * After the interface has been released the Shell instance is no |
69 | * longer valid and can be setup with another wl_shell interface. |
70 | * |
71 | * Right before the interface is released the signal interfaceAboutToBeReleased is emitted. |
72 | * @see interfaceAboutToBeReleased |
73 | **/ |
74 | void release(); |
75 | /** |
76 | * Destroys the data held by this Shell. |
77 | * This method is supposed to be used when the connection to the Wayland |
78 | * server goes away. Once the connection becomes invalid, it's not |
79 | * possible to call release anymore as that calls into the Wayland |
80 | * connection and the call would fail. This method cleans up the data, so |
81 | * that the instance can be deleted or set up to a new wl_shell interface |
82 | * once there is a new connection available. |
83 | * |
84 | * It is suggested to connect this method to ConnectionThread::connectionDied: |
85 | * @code |
86 | * connect(connection, &ConnectionThread::connectionDied, shell, &Shell::destroy); |
87 | * @endcode |
88 | * |
89 | * Right before the data is destroyed, the signal interfaceAboutToBeDestroyed is emitted. |
90 | * |
91 | * @see release |
92 | * @see interfaceAboutToBeDestroyed |
93 | **/ |
94 | void destroy(); |
95 | /** |
96 | * Setup this Shell to manage the @p shell. |
97 | * When using Registry::createShell there is no need to call this |
98 | * method. |
99 | **/ |
100 | void setup(wl_shell *shell); |
101 | |
102 | /** |
103 | * Sets the @p queue to use for creating a Surface. |
104 | **/ |
105 | void setEventQueue(EventQueue *queue); |
106 | /** |
107 | * @returns The event queue to use for creating a Surface. |
108 | **/ |
109 | EventQueue *eventQueue(); |
110 | |
111 | /** |
112 | * Creates a ShellSurface for the given @p surface and sets it up. |
113 | * |
114 | * @param surface The native surface to create the ShellSurface for |
115 | * @param parent The parent to use for the ShellSurface |
116 | * @returns created ShellSurface |
117 | **/ |
118 | ShellSurface *createSurface(wl_surface *surface, QObject *parent = nullptr); |
119 | /** |
120 | * Creates a ShellSurface for the given @p surface and sets it up. |
121 | * |
122 | * @param surface The Surface to create the ShellSurface for |
123 | * @param parent The parent to use for the ShellSurface |
124 | * @returns created ShellSurface |
125 | **/ |
126 | ShellSurface *createSurface(Surface *surface, QObject *parent = nullptr); |
127 | |
128 | operator wl_shell *(); |
129 | operator wl_shell *() const; |
130 | |
131 | Q_SIGNALS: |
132 | /** |
133 | * This signal is emitted right before the interface is released. |
134 | **/ |
135 | void interfaceAboutToBeReleased(); |
136 | /** |
137 | * This signal is emitted right before the data is destroyed. |
138 | **/ |
139 | void interfaceAboutToBeDestroyed(); |
140 | |
141 | /** |
142 | * The corresponding global for this interface on the Registry got removed. |
143 | * |
144 | * This signal gets only emitted if the Compositor got created by |
145 | * Registry::createShell |
146 | * |
147 | * @since 5.5 |
148 | **/ |
149 | void removed(); |
150 | |
151 | private: |
152 | class Private; |
153 | QScopedPointer<Private> d; |
154 | }; |
155 | |
156 | /** |
157 | * @short Wrapper for the wl_shell_surface interface. |
158 | * |
159 | * This class is a convenient wrapper for the wl_shell_surface interface. |
160 | * |
161 | * To create an instance use Shell::createSurface. |
162 | * |
163 | * @see Shell |
164 | * @see Surface |
165 | **/ |
166 | class KWAYLANDCLIENT_EXPORT ShellSurface : public QObject |
167 | { |
168 | Q_OBJECT |
169 | /** |
170 | * The size of the ShellSurface. |
171 | **/ |
172 | Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged) |
173 | public: |
174 | explicit ShellSurface(QObject *parent); |
175 | ~ShellSurface() override; |
176 | |
177 | /** |
178 | * Releases the wl_shell_surface interface. |
179 | * After the interface has been released the ShellSurface instance is no |
180 | * longer valid and can be setup with another wl_shell_surface interface. |
181 | * |
182 | * This method is automatically invoked when the Shell which created this |
183 | * ShellSurface gets released. |
184 | **/ |
185 | void release(); |
186 | /** |
187 | * Destroys the data held by this ShellSurface. |
188 | * This method is supposed to be used when the connection to the Wayland |
189 | * server goes away. If the connection is not valid anymore, it's not |
190 | * possible to call release anymore as that calls into the Wayland |
191 | * connection and the call would fail. This method cleans up the data, so |
192 | * that the instance can be deleted or set up to a new wl_shell_surface interface |
193 | * once there is a new connection available. |
194 | * |
195 | * This method is automatically invoked when the Shell which created this |
196 | * ShellSurface gets destroyed. |
197 | * |
198 | * @see release |
199 | **/ |
200 | void destroy(); |
201 | /** |
202 | * Setup this ShellSurface to manage the @p surface. |
203 | * There is normally no need to call this method as it's invoked by |
204 | * Shell::createSurface. |
205 | **/ |
206 | void setup(wl_shell_surface *surface); |
207 | QSize size() const; |
208 | void setSize(const QSize &size); |
209 | |
210 | /** |
211 | * Sets the ShellSurface fullscreen on @p output. |
212 | **/ |
213 | void setFullscreen(Output *output = nullptr); |
214 | void setMaximized(Output *output = nullptr); |
215 | void setToplevel(); |
216 | /** |
217 | * Flags which can be passed to a transient surface. |
218 | * @see setTransient |
219 | * @since 5.5 |
220 | **/ |
221 | enum class TransientFlag { |
222 | Default = 0x0, ///< Default: transient surface accepts keyboard focus |
223 | NoFocus = 0x1, ///< Transient surface does not accept keyboard focus |
224 | }; |
225 | Q_DECLARE_FLAGS(TransientFlags, TransientFlag) |
226 | /** |
227 | * Sets this Surface as a transient for @p parent. |
228 | * |
229 | * @param parent The parent Surface of this surface |
230 | * @param offset The offset of this Surface in the parent coordinate system |
231 | * @param flags The flags for the transient |
232 | * @since 5.5 |
233 | **/ |
234 | void setTransient(Surface *parent, const QPoint &offset = QPoint(), TransientFlags flags = TransientFlag::Default); |
235 | |
236 | /** |
237 | * Sets this Surface as a popup transient for @p parent. |
238 | * |
239 | * A popup is a transient with an added pointer grab on the @p grabbedSeat. |
240 | * |
241 | * The popup grab can be created if the client has an implicit grab (e.g. button press) |
242 | * on the @p grabbedSeat. It needs to pass the @p grabSerial indicating the implicit grab |
243 | * to the request for setting the surface. The implicit grab is turned into a popup grab |
244 | * which will persist after the implicit grab ends. The popup grab ends when the ShellSurface |
245 | * gets destroyed or when the compositor breaks the grab through the {@link popupDone} signal. |
246 | * |
247 | * @param parent The parent Surface of this ShellSurface |
248 | * @param grabbedSeat The Seat on which an implicit grab exists |
249 | * @param grabSerial The serial of the implicit grab |
250 | * @param offset The offset of this Surface in the parent coordinate system |
251 | * @param flags The flags for the transient |
252 | * @since 5.33 |
253 | **/ |
254 | void |
255 | setTransientPopup(Surface *parent, Seat *grabbedSeat, quint32 grabSerial, const QPoint &offset = QPoint(), TransientFlags flags = TransientFlag::Default); |
256 | |
257 | bool isValid() const; |
258 | |
259 | /** |
260 | * Requests a move on the given @p seat after the pointer button press with the given @p serial. |
261 | * |
262 | * @param seat The seat on which to move the window |
263 | * @param serial The serial of the pointer button press which should trigger the move |
264 | * @since 5.5 |
265 | **/ |
266 | void requestMove(Seat *seat, quint32 serial); |
267 | |
268 | /** |
269 | * Requests a resize on the given @p seat after the pointer button press with the given @p serial. |
270 | * |
271 | * @param seat The seat on which to resize the window |
272 | * @param serial The serial of the pointer button press which should trigger the resize |
273 | * @param edges A hint for the compositor to set e.g. an appropriate cursor image |
274 | * @since 5.5 |
275 | **/ |
276 | void requestResize(Seat *seat, quint32 serial, Qt::Edges edges); |
277 | |
278 | /** |
279 | * Sets a short title for the surface. |
280 | * |
281 | * This string may be used to identify the surface in a task bar, window list, or other user |
282 | * interface elements provided by the compositor. |
283 | * |
284 | * @since 5.55 |
285 | **/ |
286 | void setTitle(const QString &title); |
287 | |
288 | /** |
289 | * Sets a window class for the surface. |
290 | * |
291 | * The surface class identifies the general class of applications to which the surface belongs. |
292 | * A common convention is to use the file name (or the full path if it is a non-standard location) |
293 | * of the application's .desktop file as the class. |
294 | * |
295 | * @since 5.55 |
296 | **/ |
297 | void setWindowClass(const QByteArray &windowClass); |
298 | |
299 | /** |
300 | * Creates a ShellSurface for the given @p window. |
301 | * This is an integration feature for QtWayland. On non-wayland platforms this method returns |
302 | * @c nullptr as well as for not created QWindows. |
303 | * |
304 | * The returned ShellSurface will be fully setup, but won't be released. It gets automatically |
305 | * destroyed together with the @p window. |
306 | * @since 5.28 |
307 | **/ |
308 | static ShellSurface *fromWindow(QWindow *window); |
309 | |
310 | /** |
311 | * Creates a ShellSurface for the given @p winId. |
312 | * This is an integration feature for QtWayland. On non-wayland platforms this method returns |
313 | * @c nullptr as well as for not created QWindows. |
314 | * |
315 | * The returned ShellSurface will be fully setup, but won't be released. It gets automatically |
316 | * destroyed together with the QWindow corresponding |
317 | * the @p wid. |
318 | * @since 5.28 |
319 | **/ |
320 | static ShellSurface *fromQtWinId(WId wid); |
321 | |
322 | /** |
323 | * @returns The Surface referencing the @p native wl_surface or @c null if there is no such Surface. |
324 | * @since 5.28 |
325 | **/ |
326 | static ShellSurface *get(wl_shell_surface *native); |
327 | |
328 | operator wl_shell_surface *(); |
329 | operator wl_shell_surface *() const; |
330 | |
331 | Q_SIGNALS: |
332 | /** |
333 | * Signal is emitted when the ShellSurface received a ping request. |
334 | * The ShellSurface automatically responds to the ping. |
335 | **/ |
336 | void pinged(); |
337 | void sizeChanged(const QSize &); |
338 | |
339 | /** |
340 | * The popupDone signal is sent out when a popup grab is broken, that is, |
341 | * when the user clicks a surface that doesn't belong to the client owning |
342 | * the popup surface. |
343 | * @see setTransientPopup |
344 | * @since 5.33 |
345 | **/ |
346 | void popupDone(); |
347 | |
348 | private: |
349 | class Private; |
350 | QScopedPointer<Private> d; |
351 | }; |
352 | |
353 | } |
354 | } |
355 | |
356 | Q_DECLARE_METATYPE(KWayland::Client::ShellSurface::TransientFlag) |
357 | Q_DECLARE_METATYPE(KWayland::Client::ShellSurface::TransientFlags) |
358 | |
359 | #endif |
360 | |