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
16struct wl_surface;
17struct wl_shell;
18struct wl_shell_surface;
19
20namespace KWayland
21{
22namespace Client
23{
24class EventQueue;
25class ShellSurface;
26class Output;
27class Seat;
28class 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 **/
55class KWAYLANDCLIENT_EXPORT Shell : public QObject
56{
57 Q_OBJECT
58public:
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
131Q_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
151private:
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 **/
166class 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)
173public:
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
331Q_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
348private:
349 class Private;
350 QScopedPointer<Private> d;
351};
352
353}
354}
355
356Q_DECLARE_METATYPE(KWayland::Client::ShellSurface::TransientFlag)
357Q_DECLARE_METATYPE(KWayland::Client::ShellSurface::TransientFlags)
358
359#endif
360

source code of kwayland/src/client/shell.h