surface_interface.h 16.7 KB
Newer Older
1
2
/*
    SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
    SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
4

5
6
    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
7
8
#ifndef WAYLAND_SERVER_SURFACE_INTERFACE_H
#define WAYLAND_SERVER_SURFACE_INTERFACE_H
9
10
11

#include "output_interface.h"

12
#include <QMatrix4x4>
13
#include <QObject>
14
#include <QPointer>
15
16
#include <QRegion>

17
#include <KWaylandServer/kwaylandserver_export.h>
18

19
namespace KWaylandServer
20
{
Marco Martin's avatar
Marco Martin committed
21
class BlurInterface;
22
class BufferInterface;
23
class ConfinedPointerInterface;
24
class ContrastInterface;
25
class CompositorInterface;
26
class LockedPointerInterface;
Martin Flöser's avatar
Martin Flöser committed
27
class ShadowInterface;
Marco Martin's avatar
Marco Martin committed
28
class SlideInterface;
29
class SubSurfaceInterface;
30
class SurfaceInterfacePrivate;
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * @brief Resource representing a wl_surface.
 *
 * The SurfaceInterface gets created by the CompositorInterface. A SurfaceInterface normally
 * takes up a role by being "attached" to either a ShellSurfaceInterface, a SubSurfaceInterface
 * or a Cursor.
 *
 * The implementation of the SurfaceInterface does not only wrap the features exposed by wl_surface,
 * but goes further by integrating the information added to a SurfaceInterface by other interfaces.
 * This should make interacting from the server easier, it only needs to monitor the SurfaceInterface
 * and does not need to track each specific interface.
 *
 * The SurfaceInterface takes care of reference/unreferencing the BufferInterface attached to it.
 * As long as a BufferInterface is attached, the released signal won't be sent. If the BufferInterface
 * is no longer needed by the SurfaceInterface, it will get unreferenced and might be automatically
 * deleted (if it's no longer referenced).
 *
 * @see CompositorInterface
 * @see BufferInterface
 * @see SubSurfaceInterface
 * @see BlurInterface
 * @see ContrastInterface
 * @see ShadowInterface
 * @see SlideInterface
 **/
57
class KWAYLANDSERVER_EXPORT SurfaceInterface : public QObject
58
59
{
    Q_OBJECT
60
61
62
    /**
     * The current damage region.
     **/
63
    Q_PROPERTY(QRegion damage READ damage NOTIFY damaged)
64
65
66
    /**
     * The opaque region for a translucent buffer.
     **/
67
    Q_PROPERTY(QRegion opaque READ opaque NOTIFY opaqueChanged)
68
69
70
    /**
     * The current input region.
     **/
71
    Q_PROPERTY(QRegion input READ input NOTIFY inputChanged)
72
73
    Q_PROPERTY(qint32 bufferScale READ bufferScale NOTIFY bufferScaleChanged)
    Q_PROPERTY(KWaylandServer::OutputInterface::Transform bufferTransform READ bufferTransform NOTIFY bufferTransformChanged)
74
    Q_PROPERTY(QSize size READ size NOTIFY sizeChanged)
75
public:
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    explicit SurfaceInterface(CompositorInterface *compositor, wl_resource *resource);
    ~SurfaceInterface() override;

    /**
     * Returns the object id for this Wayland surface.
     */
    uint32_t id() const;
    /**
     * Returns the Wayland client that owns this SurfaceInterface.
     */
    ClientConnection *client() const;
    /**
     * Returns the Wayland resource corresponding to this SurfaceInterface.
     */
    wl_resource *resource() const;
    /**
     * Returns the compositor for this SurfaceInterface.
     */
    CompositorInterface *compositor() const;

    /**
     * Returns a list with all created Wayland surfaces.
     */
    static QList<SurfaceInterface *> surfaces();
100

101
102
103
104
105
106
107
    /**
     * Maps the specified @a point from the surface-local coordinates to buffer pixel coordinates.
     *
     * Note that there is no direct connection between points in the surface-local coordinates
     * and points in the buffer pixel coordinates. In order to map points between the two spaces,
     * one has to use mapToBuffer() and mapFromBuffer().
     *
108
109
110
     * The returned value will become invalid when the surfaceToBufferMatrixChanged() signal is emitted.
     *
     * @see surfaceToBufferMatrix(), surfaceToBufferMatrixChanged()
111
112
113
114
115
116
117
118
119
120
     * @since 5.20
     */
    QPointF mapToBuffer(const QPointF &point) const;
    /**
     * Maps the specified @a point from the buffer pixel coordinates to surface-local coordinates.
     *
     * Note that there is no direct connection between points in the surface-local coordinates
     * and points in the buffer pixel coordinates. In order to map points between the two spaces,
     * one has to use mapToBuffer() and mapFromBuffer().
     *
121
     * The returned value will become invalid when the surfaceToBufferMatrixChanged() signal is emitted.
122
     *
123
     * @see surfaceToBufferMatrix(), surfaceToBufferMatrixChanged()
124
125
     * @since 5.20
     */
126
    QPointF mapFromBuffer(const QPointF &point) const;
127
128
129
130
131
132
133
    /**
     * Maps the specified @a region from the surface-local coordinates to buffer pixel coordinates.
     *
     * Note that there is no direct connection between regions in the surface-local coordinates
     * and regions in the buffer pixel coordinates. In order to map regions between the two spaces,
     * one has to use mapToBuffer() and mapFromBuffer().
     *
134
135
136
     * The returned value will become invalid when the surfaceToBufferMatrixChanged() signal is emitted.
     *
     * @see surfaceToBufferMatrix(), surfaceToBufferMatrixChanged()
137
138
139
140
141
142
143
144
145
146
     * @since 5.20
     */
    QRegion mapToBuffer(const QRegion &region) const;
    /**
     * Maps the specified @a region from the buffer pixel coordinates to surface-local coordinates.
     *
     * Note that there is no direct connection between regions in the surface-local coordinates
     * and regions in the buffer pixel coordinates. In order to map regions between the two spaces,
     * one has to use mapToBuffer() and mapFromBuffer().
     *
147
148
149
     * The returned value will become invalid when the surfaceToBufferMatrixChanged() signal is emitted.
     *
     * @see surfaceToBufferMatrix(), surfaceToBufferMatrixChanged()
150
151
152
     * @since 5.20
     */
    QRegion mapFromBuffer(const QRegion &region) const;
153
154
155
156
157
158
159
    /**
     * Returns the projection matrix from the surface-local coordinates to buffer coordinates.
     *
     * @see surfaceToBufferMatrixChanged()
     * @since 5.20
     */
    QMatrix4x4 surfaceToBufferMatrix() const;
160

161
162
    void frameRendered(quint32 msec);

163
164
165
    QRegion damage() const;
    QRegion opaque() const;
    QRegion input() const;
166
    bool inputIsInfinite() const;
167
    qint32 bufferScale() const;
168
169
170
171
172
173
174
    /**
     * Returns the buffer transform that had been applied to the buffer to compensate for
     * output rotation.
     *
     * If the surface is on an output that is rotated 90 degrees clockwise, the buffer will
     * be rotated 90 degrees counter clockwise.
     */
175
    OutputInterface::Transform bufferTransform() const;
176
177
178
    /**
     * @returns the current BufferInterface, might be @c nullptr.
     **/
179
180
    BufferInterface *buffer();
    QPoint offset() const;
181
182
183
184
185
186
    /**
     * Returns the current size of the surface, in surface coordinates.
     *
     * Note that there is no direct relationship between the surface size and the buffer size.
     * In order to determine the size of the currently attached buffer, use buffer()->size().
     */
187
    QSize size() const;
188
189
190
191
192
193
194
195
    /**
     * Returns the rectangle that bounds this surface and all of its sub-surfaces.
     *
     * QPoint(0, 0) corresponds to the upper left corner of this surface.
     *
     * @since 5.69
     */
    QRect boundingRect() const;
196
197
198
199
200
201
    /**
     * Returns the size of the attached buffer, in device pixels.
     *
     * If no buffer is attached to this surface, an invalid QSize will be returned.
     */
    QSize bufferSize() const;
202

203
204
205
206
207
208
209
210
211
    /**
     * @returns The SubSurface for this Surface in case there is one.
     **/
    QPointer<SubSurfaceInterface> subSurface() const;
    /**
     * @returns Children in stacking order from bottom (first) to top (last).
     **/
    QList<QPointer<SubSurfaceInterface>> childSubSurfaces() const;

Martin Flöser's avatar
Martin Flöser committed
212
213
214
215
216
217
    /**
     * @returns The Shadow for this Surface.
     * @since 5.4
     **/
    QPointer<ShadowInterface> shadow() const;

Marco Martin's avatar
Marco Martin committed
218
219
220
221
222
223
    /**
     * @returns The Blur for this Surface.
     * @since 5.5
     **/
    QPointer<BlurInterface> blur() const;

Marco Martin's avatar
Marco Martin committed
224
225
226
227
228
229
    /**
     * @returns The Slide for this Surface.
     * @since 5.5
     **/
    QPointer<SlideInterface> slideOnShowHide() const;

230
231
232
233
234
235
    /**
     * @returns The Contrast for this Surface.
     * @since 5.5
     **/
    QPointer<ContrastInterface> contrast() const;

236
237
238
239
240
241
242
    /**
     * Whether the SurfaceInterface is currently considered to be mapped.
     * A SurfaceInterface is mapped if it has a non-null BufferInterface attached.
     * If the SurfaceInterface references a SubSurfaceInterface it is only considered
     * mapped if it has a BufferInterface attached and the parent SurfaceInterface is mapped.
     *
     * @returns Whether the SurfaceInterface is currently mapped
243
     * @since 5.22
244
245
246
     **/
    bool isMapped() const;

247
    /**
248
249
     * Returns the tracked damage since the last call to  {@link resetTrackedDamage}.
     * In contrast to {@link damage} this method does not reset the damage when
250
251
252
253
     * a new BufferInterface gets committed. This allows a compositor to properly
     * track the damage over multiple commits even if it didn't render each new
     * BufferInterface.
     *
254
     * The damage gets reset whenever {@link resetTrackedDamage} is called.
255
256
     * This allows a compositor to properly track the change in its rendering scene
     * for this SurfaceInterface. After it updates its internal state (e.g. by creating
257
     * an OpenGL texture from the BufferInterface) it can invoke {@link resetTrackedDamage}
258
259
260
261
262
     * and the damage tracker will start to track further damage changes.
     *
     * @returns Combined damage since last call to resetTrackedDamage
     * @see damage
     * @see resetTrackedDamage
263
     * @since 5.22
264
265
266
267
268
269
270
     **/
    QRegion trackedDamage() const;

    /**
     * Reset the damage tracking. The compositor should invoke this method once it updated
     * it's internal state and processed the current damage.
     * @see trackedDamage
271
     * @since 5.22
272
273
274
     **/
    void resetTrackedDamage();

275
276
277
278
279
280
281
282
283
284
    /**
     * Finds the SurfaceInterface at the given @p position in surface-local coordinates.
     * This can be either a descendant SurfaceInterface honoring the stacking order or
     * the SurfaceInterface itself if its geometry contains the given @p position.
     *
     * If no such SurfaceInterface is found, e.g. because the SurfaceInterface is unmapped,
     * @c nullptr is returned.
     *
     * @param position The position in surface-local coordinates
     * @returns Child surface at the given @p position or surface itself at the position, might be @c nullptr
285
     * @since 5.22
286
287
288
     **/
    SurfaceInterface *surfaceAt(const QPointF &position);

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
    /**
     * Finds the input receiving SurfaceInterface at the given @p position in surface-local coordinates.
     * This can be either a descendant SurfaceInterface honoring the stacking order or
     * the SurfaceInterface itself if its geometry contains the given @p position.
     *
     * If no such SurfaceInterface is found, e.g. because the SurfaceInterface is unmapped or there is no
     * input region containing the position,
     * @c nullptr is returned.
     *
     * @param position The position in surface-local coordinates
     * @returns Input receiving child surface at the given @p position or surface itself at the position, might be @c nullptr
     * @since 5.52
     **/
    SurfaceInterface *inputSurfaceAt(const QPointF &position);

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    /**
     * Sets the @p outputs this SurfaceInterface overlaps with, may be empty.
     *
     * The compositor should update whenever the SurfaceInterface becomes visible on
     * an OutputInterface by e.g. getting (un)mapped, resized, moved, etc.
     *
     * @see outputs
     * @since 5.27
     **/
    void setOutputs(const QVector<OutputInterface *> &outputs);

    /**
     * @returns All OutputInterfaces the SurfaceInterface is on.
     * @see setOutputs
     * @since 5.27
     **/
    QVector<OutputInterface *> outputs() const;

322
323
324
325
326
327
328
329
330
331
332
333
334
335
    /**
     * Pointer confinement installed on this SurfaceInterface.
     * @see pointerConstraintsChanged
     * @since 5.29
     **/
    QPointer<ConfinedPointerInterface> confinedPointer() const;

    /**
     * Pointer lock installed on this SurfaceInterface.
     * @see pointerConstraintsChanged
     * @since 5.29
     **/
    QPointer<LockedPointerInterface> lockedPointer() const;

336
337
338
339
340
341
342
    /**
     * @returns Whether this SurfaceInterface wants idle to be inhibited on the Output it is shown
     * @see inhibitsIdleChanged
     * @since 5.41
     **/
    bool inhibitsIdle() const;

343
344
345
    /**
     * @returns The SurfaceInterface for the @p native resource.
     **/
346
    static SurfaceInterface *get(wl_resource *native);
347
    /**
348
     * @returns The SurfaceInterface with given @p id for @p client, if it exists, otherwise @c nullptr.
349
350
     * @since 5.3
     **/
351
    static SurfaceInterface *get(quint32 id, const ClientConnection *client);
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
    /**
     * Set @p surface as a data proxy for this SurfaceInterface. This enables
     * the proxy to conduct drags on the surface's client behalf.
     *
     * Setting a data proxy is only allowed when the client owning this surface
     * has not created a data device itself.
     * @since 5.56
     **/
    void setDataProxy(SurfaceInterface *surface);
    /**
     * Returns the data proxy of this SurfaceInterface or null if there
     * is none set.
     * @since 5.56
     **/
    SurfaceInterface* dataProxy() const;

369
Q_SIGNALS:
370
    /**
371
372
373
374
375
376
377
     * This signal is emitted when the underlying wl_surface resource is about to be freed.
     *
     * The unbound() signal is emitted either when the client that owns the surface has been
     * destroyed or if the surface has been destroyed due to a destructor request.
     *
     * The SurfaceInterface object and the associated wl_surface resource are valid when this
     * signal is emitted.
378
     */
379
    void aboutToBeDestroyed();
380
381
382
383
384
385
386
387
    /**
     * This signal is emitted when the projection matrix from the surface-local coordinate space
     * to the buffer coordinate space has been changed.
     *
     * Note that the compositor will most likely need to re-compute the texture coordinates after
     * the surface-to-buffer matrix has been changed.
     */
    void surfaceToBufferMatrixChanged();
388
389
390
391
392
393
394
395
    /**
     * Emitted whenever the SurfaceInterface got damaged.
     * The signal is only emitted during the commit of state.
     * A damage means that a new BufferInterface got attached.
     *
     * @see buffer
     * @see damage
     **/
396
397
398
    void damaged(const QRegion&);
    void opaqueChanged(const QRegion&);
    void inputChanged(const QRegion&);
399
400
401
    /**
     * This signal is emitted when the scale of the attached buffer has changed.
     */
402
    void bufferScaleChanged(qint32);
403
404
405
    /**
     * This signal is emitted when the buffer transform has changed.
     */
406
    void bufferTransformChanged(KWaylandServer::OutputInterface::Transform);
407
408
409
410
    /**
     * This signal is emitted when the size of the attached buffer has changed.
     */
    void bufferSizeChanged();
411
412
413
414
    /**
     * Emitted when the Surface becomes visible, i.e. a non-null buffer has been attached.
     **/
    void mapped();
415
416
417
418
    /**
     * Emitted when the Surface removes its content
     **/
    void unmapped();
419
    /**
420
421
     * This signal is emitted when the surface size has changed.
     */
422
    void sizeChanged();
Martin Flöser's avatar
Martin Flöser committed
423
424
425
426
    /**
     * @since 5.4
     **/
    void shadowChanged();
Marco Martin's avatar
Marco Martin committed
427
428
429
430
    /**
     * @since 5.5
     **/
    void blurChanged();
Marco Martin's avatar
Marco Martin committed
431
432
433
434
    /**
     * @since 5.5
     **/
    void slideOnShowHideChanged();
435
436
437
438
    /**
     * @since 5.5
     **/
    void contrastChanged();
439
440
    /**
     * Emitted whenever the tree of sub-surfaces changes in a way which requires a repaint.
441
     * @since 5.22
442
443
     **/
    void subSurfaceTreeChanged();
444
445
446
447
448
449
450
451
452
453
    /**
     * Emitted whenever a new child sub-surface @p subSurface is added.
     * @since 5.70
     */
    void childSubSurfaceAdded(SubSurfaceInterface *subSurface);
    /**
     * Emitted whenver the child sub-surface @p subSurface is removed.
     * @since 5.70
     */
    void childSubSurfaceRemoved(SubSurfaceInterface *subSurface);
454

455
456
457
458
459
460
461
462
463
464
465
466
    /**
     * Emitted whenever a pointer constraint get (un)installed on this SurfaceInterface.
     *
     * The pointer constraint does not get activated, the compositor needs to activate
     * the lock/confinement.
     *
     * @see confinedPointer
     * @see lockedPointer
     * @since 5.29
     **/
    void pointerConstraintsChanged();

467
468
469
470
471
472
473
    /**
     * Emitted whenever the SurfaceInterface starts/ends to inhibit idle.
     * @see inhibitsIdle
     * @since 5.41
     **/
    void inhibitsIdleChanged();

474
475
476
477
478
479
480
481
482
    /**
     * Emitted when the Surface has been committed.
     *
     * This signal is emitted after all the relevant damage and xyzChanged signals
     * for this commit are emitted.
     * @since 5.54
     **/
    void committed();

483
private:
484
485
    QScopedPointer<SurfaceInterfacePrivate> d;
    friend class SurfaceInterfacePrivate;
486
487
488
489
};

}

490
Q_DECLARE_METATYPE(KWaylandServer::SurfaceInterface*)
491

492
#endif