| 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 | |