kwineffects.h 137 KB
Newer Older
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
1
2
3
/*
    KWin - the KDE window manager
    This file is part of the KDE project.
4

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
5
6
7
8
    SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
    SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
    SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
    SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
9

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
10
11
    SPDX-License-Identifier: GPL-2.0-or-later
*/
12

13
14
#ifndef KWINEFFECTS_H
#define KWINEFFECTS_H
15

16
#include <kwinconfig.h>
17
#include <kwineffects_export.h>
18
19
#include <kwinglobals.h>

20
#include <QEasingCurve>
21
#include <QIcon>
22
23
24
#include <QPair>
#include <QSet>
#include <QRect>
25
26
27
#include <QRegion>
#include <QVector2D>
#include <QVector3D>
28

29
#include <QVector>
30
#include <QLoggingCategory>
31
32
33
#include <QList>
#include <QHash>
#include <QStack>
34
#include <QScopedPointer>
35

36
#include <KPluginFactory>
37
#include <KSharedConfig>
Bernhard Loos's avatar
Bernhard Loos committed
38

Thomas Lübking's avatar
Thomas Lübking committed
39
#include <netwm.h>
40

41
#include <climits>
42
43
#include <functional>

44
class KConfigGroup;
Martin Flöser's avatar
Martin Flöser committed
45
class QFont;
46
class QGraphicsScale;
47
class QKeyEvent;
48
class QMatrix4x4;
49
class QAction;
50

51
52
53
/**
 * Logging category to be used inside the KWin effects.
 * Do not use in this library.
54
 */
Allen Winter's avatar
Allen Winter committed
55
Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
56

57
58
59
namespace KWaylandServer {
    class SurfaceInterface;
    class Display;
60
61
}

62
63
64
namespace KWin
{

65
class PaintDataPrivate;
66
class WindowPaintDataPrivate;
67

68
69
class EffectWindow;
class EffectWindowGroup;
70
class EffectFrame;
71
class EffectFramePrivate;
72
class EffectQuickView;
73
class Effect;
74
class WindowQuad;
75
class GLShader;
76
class XRenderPicture;
77
78
79
80
81
class WindowQuadList;
class WindowPrePaintData;
class WindowPaintData;
class ScreenPrePaintData;
class ScreenPaintData;
82
83

typedef QPair< QString, Effect* > EffectPair;
84
typedef QList< KWin::EffectWindow* > EffectWindowList;
85
86


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/** @defgroup kwineffects KWin effects library
 * KWin effects library contains necessary classes for creating new KWin
 * compositing effects.
 *
 * @section creating Creating new effects
 * This example will demonstrate the basics of creating an effect. We'll use
 *  CoolEffect as the class name, cooleffect as internal name and
 *  "Cool Effect" as user-visible name of the effect.
 *
 * This example doesn't demonstrate how to write the effect's code. For that,
 *  see the documentation of the Effect class.
 *
 * @subsection creating-class CoolEffect class
 * First you need to create CoolEffect class which has to be a subclass of
 *  @ref KWin::Effect. In that class you can reimplement various virtual
 *  methods to control how and where the windows are drawn.
 *
104
105
106
107
108
 * @subsection creating-macro KWIN_EFFECT_FACTORY macro
 * This library provides a specialized KPluginFactory subclass and macros to
 * create a sub class. This subclass of KPluginFactory has to be used, otherwise
 * KWin won't load the plugin. Use the @ref KWIN_EFFECT_FACTORY macro to create the
 * plugin factory.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
 *
 * @subsection creating-buildsystem Buildsystem
 * To build the effect, you can use the KWIN_ADD_EFFECT() cmake macro which
 *  can be found in effects/CMakeLists.txt file in KWin's source. First
 *  argument of the macro is the name of the library that will contain
 *  your effect. Although not strictly required, it is usually a good idea to
 *  use the same name as your effect's internal name there. Following arguments
 *  to the macro are the files containing your effect's source. If our effect's
 *  source is in cooleffect.cpp, we'd use following:
 * @code
 *  KWIN_ADD_EFFECT(cooleffect cooleffect.cpp)
 * @endcode
 *
 * This macro takes care of compiling your effect. You'll also need to install
 *  your effect's .desktop file, so the example CMakeLists.txt file would be
 *  as follows:
 * @code
 *  KWIN_ADD_EFFECT(cooleffect cooleffect.cpp)
 *  install( FILES cooleffect.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
 * @endcode
 *
 * @subsection creating-desktop Effect's .desktop file
 * You will also need to create .desktop file to set name, description, icon
 *  and other properties of your effect. Important fields of the .desktop file
 *  are:
 *  @li Name User-visible name of your effect
 *  @li Icon Name of the icon of the effect
 *  @li Comment Short description of the effect
 *  @li Type must be "Service"
 *  @li X-KDE-ServiceTypes must be "KWin/Effect"
 *  @li X-KDE-PluginInfo-Name effect's internal name as passed to the KWIN_EFFECT macro plus "kwin4_effect_" prefix
 *  @li X-KDE-PluginInfo-Category effect's category. Should be one of Appearance, Accessibility, Window Management, Demos, Tests, Misc
 *  @li X-KDE-PluginInfo-EnabledByDefault whether the effect should be enabled by default (use sparingly). Default is false
 *  @li X-KDE-Library name of the library containing the effect. This is the first argument passed to the KWIN_ADD_EFFECT macro in cmake file plus "kwin4_effect_" prefix.
 *
 * Example cooleffect.desktop file follows:
 * @code
[Desktop Entry]
Name=Cool Effect
Comment=The coolest effect you've ever seen
Icon=preferences-system-windows-effect-cooleffect

Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=My Name
X-KDE-PluginInfo-Email=my@email.here
X-KDE-PluginInfo-Name=kwin4_effect_cooleffect
X-KDE-PluginInfo-Category=Misc
X-KDE-Library=kwin4_effect_cooleffect
 * @endcode
 *
 *
 * @section accessing Accessing windows and workspace
 * Effects can gain access to the properties of windows and workspace via
 *  EffectWindow and EffectsHandler classes.
 *
 * There is one global EffectsHandler object which you can access using the
 *  @ref effects pointer.
 * For each window, there is an EffectWindow object which can be used to read
 *  window properties such as position and also to change them.
 *
 * For more information about this, see the documentation of the corresponding
 *  classes.
 *
 * @{
174
 */
175
176
177

#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
178
#define KWIN_EFFECT_API_VERSION_MINOR 231
179
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
180
        KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
181

182
enum WindowQuadType {
183
184
    WindowQuadError, // for the stupid default ctor
    WindowQuadContents,
185
    WindowQuadDecoration,
186
    // Shadow Quad types
Fredrik Höglund's avatar
Fredrik Höglund committed
187
    WindowQuadShadow,             // OpenGL only. The other shadow types are only used by Xrender
188
189
190
191
192
193
194
195
    WindowQuadShadowTop,
    WindowQuadShadowTopRight,
    WindowQuadShadowRight,
    WindowQuadShadowBottomRight,
    WindowQuadShadowBottom,
    WindowQuadShadowBottomLeft,
    WindowQuadShadowLeft,
    WindowQuadShadowTopLeft,
196
    EFFECT_QUAD_TYPE_START = 100 ///< @internal
197
};
198

199
200
201
/**
 * EffectWindow::setData() and EffectWindow::data() global roles.
 * All values between 0 and 999 are reserved for global roles.
202
 */
203
enum DataRole {
204
205
206
207
208
    // Grab roles are used to force all other animations to ignore the window.
    // The value of the data is set to the Effect's `this` value.
    WindowAddedGrabRole = 1,
    WindowClosedGrabRole,
    WindowMinimizedGrabRole,
209
    WindowUnminimizedGrabRole,
210
    WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
211
    WindowBlurBehindRole, ///< For single windows to blur behind
212
213
    WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
    WindowBackgroundContrastRole, ///< For single windows to enable Background contrast
214
    LanczosCacheRole
215
};
216

217
218
219
/**
 * Style types used by @ref EffectFrame.
 * @since 4.6
220
 */
221
enum EffectFrameStyle {
222
223
224
    EffectFrameNone, ///< Displays no frame around the contents.
    EffectFrameUnstyled, ///< Displays a basic box around the contents.
    EffectFrameStyled ///< Displays a Plasma-styled frame around the contents.
225
};
226

227
228
/**
 * Infinite region (i.e. a special region type saying that everything needs to be painted).
229
 */
230
KWINEFFECTS_EXPORT inline
231
QRect infiniteRegion()
232
233
234
235
{
    // INT_MIN / 2 because width/height is used (INT_MIN+INT_MAX==-1)
    return QRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX);
}
236

Rivo Laks's avatar
Rivo Laks committed
237
238
239
240
241
242
/**
 * @short Base class for all KWin effects
 *
 * This is the base class for all effects. By reimplementing virtual methods
 *  of this class, you can customize how the windows are painted.
 *
243
244
245
246
247
 * The virtual methods are used for painting and need to be implemented for
 * custom painting.
 *
 * In order to react to state changes (e.g. a window gets closed) the effect
 * should provide slots for the signals emitted by the EffectsHandler.
Rivo Laks's avatar
Rivo Laks committed
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
 *
 * @section Chaining
 * Most methods of this class are called in chain style. This means that when
 *  effects A and B area active then first e.g. A::paintWindow() is called and
 *  then from within that method B::paintWindow() is called (although
 *  indirectly). To achieve this, you need to make sure to call corresponding
 *  method in EffectsHandler class from each such method (using @ref effects
 *  pointer):
 * @code
 *  void MyEffect::postPaintScreen()
 *  {
 *      // Do your own processing here
 *      ...
 *      // Call corresponding EffectsHandler method
 *      effects->postPaintScreen();
 *  }
 * @endcode
 *
 * @section Effectsptr Effects pointer
 * @ref effects pointer points to the global EffectsHandler object that you can
 *  use to interact with the windows.
 *
 * @section painting Painting stages
 * Painting of windows is done in three stages:
 * @li First, the prepaint pass.<br>
 *  Here you can specify how the windows will be painted, e.g. that they will
 *  be translucent and transformed.
 * @li Second, the paint pass.<br>
 *  Here the actual painting takes place. You can change attributes such as
 *  opacity of windows as well as apply transformations to them. You can also
 *  paint something onto the screen yourself.
 * @li Finally, the postpaint pass.<br>
 *  Here you can mark windows, part of windows or even the entire screen for
 *  repainting to create animations.
 *
 * For each stage there are *Screen() and *Window() methods. The window method
 *  is called for every window which the screen method is usually called just
 *  once.
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
 *
 * @section OpenGL
 * Effects can use OpenGL if EffectsHandler::isOpenGLCompositing() returns @c true.
 * The OpenGL context may not always be current when code inside the effect is
 * executed. The framework ensures that the OpenGL context is current when the Effect
 * gets created, destroyed or reconfigured and during the painting stages. All virtual
 * methods which have the OpenGL context current are documented.
 *
 * If OpenGL code is going to be executed outside the painting stages, e.g. in reaction
 * to a global shortcut, it is the task of the Effect to make the OpenGL context current:
 * @code
 * effects->makeOpenGLContextCurrent();
 * @endcode
 *
 * There is in general no need to call the matching doneCurrent method.
301
 */
302
class KWINEFFECTS_EXPORT Effect : public QObject
303
{
304
    Q_OBJECT
305
306
307
308
public:
    /** Flags controlling how painting is done. */
    // TODO: is that ok here?
    enum {
Rivo Laks's avatar
Rivo Laks committed
309
        /**
310
         * Window (or at least part of it) will be painted opaque.
311
         */
312
        PAINT_WINDOW_OPAQUE         = 1 << 0,
Rivo Laks's avatar
Rivo Laks committed
313
        /**
314
         * Window (or at least part of it) will be painted translucent.
315
         */
316
        PAINT_WINDOW_TRANSLUCENT    = 1 << 1,
317
        /**
318
         * Window will be painted with transformed geometry.
319
         */
320
        PAINT_WINDOW_TRANSFORMED    = 1 << 2,
Rivo Laks's avatar
Rivo Laks committed
321
        /**
322
323
         * Paint only a region of the screen (can be optimized, cannot
         * be used together with TRANSFORMED flags).
324
         */
325
        PAINT_SCREEN_REGION         = 1 << 3,
Rivo Laks's avatar
Rivo Laks committed
326
        /**
327
328
         * The whole screen will be painted with transformed geometry.
         * Forces the entire screen to be painted.
329
         */
330
        PAINT_SCREEN_TRANSFORMED    = 1 << 4,
Rivo Laks's avatar
Rivo Laks committed
331
        /**
332
333
         * At least one window will be painted with transformed geometry.
         * Forces the entire screen to be painted.
334
         */
335
        PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
Rivo Laks's avatar
Rivo Laks committed
336
        /**
337
         * Clear whole background as the very first step, without optimizing it
338
         */
339
        PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
340
        // PAINT_DECORATION_ONLY = 1 << 7 has been deprecated
341
        /**
342
         * Window will be painted with a lanczos filter.
343
         */
Laurent Montel's avatar
Laurent Montel committed
344
        PAINT_WINDOW_LANCZOS = 1 << 8
345
        // PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS = 1 << 9 has been removed
346
    };
347

348
    enum Feature {
349
350
351
352
353
354
355
356
        Nothing = 0,
        Resize,
        GeometryTip,
        Outline, /**< @deprecated */
        ScreenInversion,
        Blur,
        Contrast,
        HighlightWindows
357
    };
358

359
360
    /**
     * Constructs new Effect object.
361
362
363
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when the Effect is constructed.
364
     */
365
366
367
    Effect();
    /**
     * Destructs the Effect object.
368
369
370
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when the Effect is destroyed.
371
     */
372
    ~Effect() override;
373
374
375

    /**
     * Flags describing which parts of configuration have changed.
376
     */
377
378
    enum ReconfigureFlag {
        ReconfigureAll = 1 << 0 /// Everything needs to be reconfigured.
379
    };
380
381
382
383
    Q_DECLARE_FLAGS(ReconfigureFlags, ReconfigureFlag)

    /**
     * Called when configuration changes (either the effect's or KWin's global).
384
385
386
387
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when the Effect is reconfigured. If this method is called from within the Effect it is
     * required to ensure that the context is current if the implementation does OpenGL calls.
388
     */
389
390
391
392
    virtual void reconfigure(ReconfigureFlags flags);

    /**
     * Called when another effect requests the proxy for this effect.
393
     */
394
395
396
397
398
399
400
401
402
    virtual void* proxy();

    /**
     * Called before starting to paint the screen.
     * In this method you can:
     * @li set whether the windows or the entire screen will be transformed
     * @li change the region of the screen that will be painted
     * @li do various housekeeping tasks such as initing your effect's variables
            for the upcoming paint pass or updating animation's progress
403
404
405
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
406
    */
407
408
409
410
411
412
413
    virtual void prePaintScreen(ScreenPrePaintData& data, int time);
    /**
     * In this method you can:
     * @li paint something on top of the windows (by painting after calling
     *      effects->paintScreen())
     * @li paint multiple desktops and/or multiple copies of the same desktop
     *      by calling effects->paintScreen() multiple times
414
415
416
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
417
     */
Albert Astals Cid's avatar
Albert Astals Cid committed
418
    virtual void paintScreen(int mask, const QRegion &region, ScreenPaintData& data);
419
420
421
422
423
    /**
     * Called after all the painting has been finished.
     * In this method you can:
     * @li schedule next repaint in case of animations
     * You shouldn't paint anything here.
424
425
426
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
427
     */
428
429
430
431
432
433
434
435
436
    virtual void postPaintScreen();

    /**
     * Called for every window before the actual paint pass
     * In this method you can:
     * @li enable or disable painting of the window (e.g. enable paiting of minimized window)
     * @li set window to be painted with translucency
     * @li set window to be transformed
     * @li request the window to be divided into multiple parts
437
438
439
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
440
     */
441
442
443
444
445
446
447
    virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
    /**
     * This is the main method for painting windows.
     * In this method you can:
     * @li do various transformations
     * @li change opacity of the window
     * @li change brightness and/or saturation, if it's supported
448
449
450
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
451
     */
452
453
454
455
456
457
    virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
    /**
     * Called for every window after all painting has been finished.
     * In this method you can:
     * @li schedule next repaint for individual window(s) in case of animations
     * You shouldn't paint anything here.
458
459
460
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
461
     */
462
463
464
465
466
467
468
469
470
471
472
    virtual void postPaintWindow(EffectWindow* w);

    /**
     * This method is called directly before painting an @ref EffectFrame.
     * You can implement this method if you need to bind a shader or perform
     * other operations before the frame is rendered.
     * @param frame The EffectFrame which will be rendered
     * @param region Region to restrict painting to
     * @param opacity Opacity of text/icon
     * @param frameOpacity Opacity of background
     * @since 4.6
473
474
475
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
476
     */
Albert Astals Cid's avatar
Albert Astals Cid committed
477
    virtual void paintEffectFrame(EffectFrame* frame, const QRegion &region, double opacity, double frameOpacity);
478
479
480

    /**
     * Called on Transparent resizes.
481
     * return true if your effect substitutes questioned feature
482
     */
483
484
    virtual bool provides(Feature);

485
486
487
488
489
490
491
492
493
494
    /**
     * Performs the @p feature with the @p arguments.
     *
     * This allows to have specific protocols between KWin core and an Effect.
     *
     * The method is supposed to return @c true if it performed the features,
     * @c false otherwise.
     *
     * The default implementation returns @c false.
     * @since 5.8
495
     */
496
497
    virtual bool perform(Feature feature, const QVariantList &arguments);

498
499
500
    /**
     * Can be called to draw multiple copies (e.g. thumbnails) of a window.
     * You can change window's opacity/brightness/etc here, but you can't
501
502
503
504
     *  do any transformations.
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
505
     */
Albert Astals Cid's avatar
Albert Astals Cid committed
506
    virtual void drawWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data);
507
508
509
510

    /**
     * Define new window quads so that they can be transformed by other effects.
     * It's up to the effect to keep track of them.
511
     */
512
513
    virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList);

514
    virtual void windowInputMouseEvent(QEvent* e);
515
516
    virtual void grabbedKeyboardEvent(QKeyEvent* e);

517
518
519
520
521
522
523
524
525
526
527
528
529
530
    /**
     * Overwrite this method to indicate whether your effect will be doing something in
     * the next frame to be rendered. If the method returns @c false the effect will be
     * excluded from the chained methods in the next rendered frame.
     *
     * This method is called always directly before the paint loop begins. So it is totally
     * fine to e.g. react on a window event, issue a repaint to trigger an animation and
     * change a flag to indicate that this method returns @c true.
     *
     * As the method is called each frame, you should not perform complex calculations.
     * Best use just a boolean flag.
     *
     * The default implementation of this method returns @c true.
     * @since 4.8
531
     */
532
533
    virtual bool isActive() const;

534
535
    /**
     * Reimplement this method to provide online debugging.
Yuri Chornoivan's avatar
Yuri Chornoivan committed
536
     * This could be as trivial as printing specific detail information about the effect state
537
538
539
540
541
542
543
     * but could also be used to move the effect in and out of a special debug modes, clear bogus
     * data, etc.
     * Notice that the functions is const by intent! Whenever you alter the state of the object
     * due to random user input, you should do so with greatest care, hence const_cast<> your
     * object - signalling "let me alone, i know what i'm doing"
     * @param parameter A freeform string user input for your effect to interpret.
     * @since 4.11
544
     */
545
546
    virtual QString debug(const QString &parameter) const;

547
548
549
550
551
552
553
554
555
556
557
    /**
     * Reimplement this method to indicate where in the Effect chain the Effect should be placed.
     *
     * A low number indicates early chain position, thus before other Effects got called, a high
     * number indicates a late position. The returned number should be in the interval [0, 100].
     * The default value is 0.
     *
     * In KWin4 this information was provided in the Effect's desktop file as property
     * X-KDE-Ordering. In the case of Scripted Effects this property is still used.
     *
     * @since 5.0
558
     */
559
560
    virtual int requestedEffectChainPosition() const;

561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

    /**
     * A touch point was pressed.
     *
     * If the effect wants to exclusively use the touch event it should return @c true.
     * If @c false is returned the touch event is passed to further effects.
     *
     * In general an Effect should only return @c true if it is the exclusive effect getting
     * input events. E.g. has grabbed mouse events.
     *
     * Default implementation returns @c false.
     *
     * @param id The unique id of the touch point
     * @param pos The position of the touch point in global coordinates
     * @param time Timestamp
     *
     * @see touchMotion
     * @see touchUp
     * @since 5.8
580
     */
581
    virtual bool touchDown(qint32 id, const QPointF &pos, quint32 time);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
    /**
     * A touch point moved.
     *
     * If the effect wants to exclusively use the touch event it should return @c true.
     * If @c false is returned the touch event is passed to further effects.
     *
     * In general an Effect should only return @c true if it is the exclusive effect getting
     * input events. E.g. has grabbed mouse events.
     *
     * Default implementation returns @c false.
     *
     * @param id The unique id of the touch point
     * @param pos The position of the touch point in global coordinates
     * @param time Timestamp
     *
     * @see touchDown
     * @see touchUp
     * @since 5.8
600
     */
601
    virtual bool touchMotion(qint32 id, const QPointF &pos, quint32 time);
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
    /**
     * A touch point was released.
     *
     * If the effect wants to exclusively use the touch event it should return @c true.
     * If @c false is returned the touch event is passed to further effects.
     *
     * In general an Effect should only return @c true if it is the exclusive effect getting
     * input events. E.g. has grabbed mouse events.
     *
     * Default implementation returns @c false.
     *
     * @param id The unique id of the touch point
     * @param time Timestamp
     *
     * @see touchDown
     * @see touchMotion
     * @since 5.8
619
     */
620
    virtual bool touchUp(qint32 id, quint32 time);
621

622
623
624
625
626
627
628
629
630
631
    static QPoint cursorPos();

    /**
     * Read animation time from the configuration and possibly adjust using animationTimeFactor().
     * The configuration value in the effect should also have special value 'default' (set using
     * QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted
     * using the global animation speed, otherwise the exact time configured is returned.
     * @param cfg configuration group to read value from
     * @param key configuration key to read value from
     * @param defaultTime default animation time in milliseconds
632
     */
633
634
635
636
637
    // return type is intentionally double so that one can divide using it without losing data
    static double animationTime(const KConfigGroup& cfg, const QString& key, int defaultTime);
    /**
     * @overload Use this variant if the animation time is hardcoded and not configurable
     * in the effect itself.
638
     */
639
    static double animationTime(int defaultTime);
640
641
642
    /**
     * @overload Use this variant if animation time is provided through a KConfigXT generated class
     * having a property called "duration".
643
     */
644
645
    template <typename T>
    int animationTime(int defaultDuration);
646
647
648
649
    /**
     * Linearly interpolates between @p x and @p y.
     *
     * Returns @p x when @p a = 0; returns @p y when @p a = 1.
650
     */
651
652
653
654
655
    static double interpolate(double x, double y, double a) {
        return x * (1 - a) + y * a;
    }
    /** Helper to set WindowPaintData and QRegion to necessary transformations so that
     * a following drawWindow() would put the window at the requested geometry (useful for thumbnails)
656
     */
657
658
    static void setPositionTransformations(WindowPaintData& data, QRect& region, EffectWindow* w,
                                           const QRect& r, Qt::AspectRatioMode aspect);
659
660
661

public Q_SLOTS:
    virtual bool borderActivated(ElectricBorder border);
662
663
664
665

protected:
    xcb_connection_t *xcbConnection() const;
    xcb_window_t x11RootWindow() const;
666
667
668
669
670

    /**
     * An implementing class can call this with it's kconfig compiled singleton class.
     * This method will perform the instance on the class.
     * @since 5.9
671
     */
672
673
    template <typename T>
    void initConfig();
674
};
675
676
677


/**
678
 * Prefer the KWIN_EFFECT_FACTORY macros.
679
 */
680
681
682
683
class KWINEFFECTS_EXPORT EffectPluginFactory : public KPluginFactory
{
    Q_OBJECT
public:
684
    EffectPluginFactory();
685
    ~EffectPluginFactory() override;
686
687
688
689
690
691
692
693
    /**
     * Returns whether the Effect is supported.
     *
     * An Effect can implement this method to determine at runtime whether the Effect is supported.
     *
     * If the current compositing backend is not supported it should return @c false.
     *
     * This method is optional, by default @c true is returned.
694
     */
695
696
697
698
699
700
701
702
703
704
705
706
707
    virtual bool isSupported() const;
    /**
     * Returns whether the Effect should get enabled by default.
     *
     * This function provides a way for an effect to override the default at runtime,
     * e.g. based on the capabilities of the hardware.
     *
     * This method is optional; the effect doesn't have to provide it.
     *
     * Note that this function is only called if the supported() function returns true,
     * and if X-KDE-PluginInfo-EnabledByDefault is set to true in the .desktop file.
     *
     * This method is optional, by default @c true is returned.
708
     */
709
710
711
    virtual bool enabledByDefault() const;
    /**
     * This method returns the created Effect.
712
     */
713
714
    virtual KWin::Effect *createEffect() const = 0;
};
715
716

/**
717
 * Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.
718
 *
719
720
721
 * If the Effect to be created does not need the isSupported or enabledByDefault methods prefer
 * the simplified KWIN_EFFECT_FACTORY, KWIN_EFFECT_FACTORY_SUPPORTED or KWIN_EFFECT_FACTORY_ENABLED
 * macros which create an EffectPluginFactory with a useable default value.
722
 *
723
724
725
726
 * The macro also adds a useable K_EXPORT_PLUGIN_VERSION to the definition. KWin will not load
 * any Effect with a non-matching plugin version. This API is not providing binary compatibility
 * and thus the effect plugin must be compiled against the same kwineffects library version as
 * KWin.
727
 *
728
729
730
731
732
 * @param factoryName The name to be used for the EffectPluginFactory
 * @param className The class name of the Effect sub class which is to be created by the factory
 * @param jsonFile Name of the json file to be compiled into the plugin as metadata
 * @param supported Source code to go into the isSupported() method, must return a boolean
 * @param enabled Source code to go into the enabledByDefault() method, must return a boolean
733
 */
734
735
736
737
738
739
740
#define KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, supported, enabled ) \
    class factoryName : public KWin::EffectPluginFactory \
    { \
        Q_OBJECT \
        Q_PLUGIN_METADATA(IID KPluginFactory_iid FILE jsonFile) \
        Q_INTERFACES(KPluginFactory) \
    public: \
741
        explicit factoryName() {} \
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
        ~factoryName() {} \
        bool isSupported() const override { \
            supported \
        } \
        bool enabledByDefault() const override { \
            enabled \
        } \
        KWin::Effect *createEffect() const override { \
            return new className(); \
        } \
    }; \
    K_EXPORT_PLUGIN_VERSION(quint32(KWIN_EFFECT_API_VERSION))

#define KWIN_EFFECT_FACTORY_ENABLED( factoryName, className, jsonFile, enabled ) \
    KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, return true;, enabled )

Nicolas Fella's avatar
Nicolas Fella committed
758
#define KWIN_EFFECT_FACTORY_SUPPORTED( factoryName, className, jsonFile, supported ) \
759
760
    KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, supported, return true; )

Nicolas Fella's avatar
Nicolas Fella committed
761
#define KWIN_EFFECT_FACTORY( factoryName, className, jsonFile ) \
762
763
    KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, return true;, return true; )

764

765

Rivo Laks's avatar
Rivo Laks committed
766
767
768
769
770
771
772
773
774
/**
 * @short Manager class that handles all the effects.
 *
 * This class creates Effect objects and calls it's appropriate methods.
 *
 * Effect objects can call methods of this class to interact with the
 *  workspace, e.g. to activate or move a specific window, change current
 *  desktop or create a special input window to receive mouse and keyboard
 *  events.
775
 */
776
class KWINEFFECTS_EXPORT EffectsHandler : public QObject
777
{
778
    Q_OBJECT
779
    Q_PROPERTY(int currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
780
    Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
781
782
783
784
785
786
787
788
    Q_PROPERTY(KWin::EffectWindow *activeWindow READ activeWindow WRITE activateWindow NOTIFY windowActivated)
    Q_PROPERTY(QSize desktopGridSize READ desktopGridSize)
    Q_PROPERTY(int desktopGridWidth READ desktopGridWidth)
    Q_PROPERTY(int desktopGridHeight READ desktopGridHeight)
    Q_PROPERTY(int workspaceWidth READ workspaceWidth)
    Q_PROPERTY(int workspaceHeight READ workspaceHeight)
    /**
     * The number of desktops currently used. Minimum number of desktops is 1, maximum 20.
789
     */
790
791
792
    Q_PROPERTY(int desktops READ numberOfDesktops WRITE setNumberOfDesktops NOTIFY numberDesktopsChanged)
    Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
    Q_PROPERTY(int activeScreen READ activeScreen)
793
    Q_PROPERTY(int numScreens READ numScreens NOTIFY numberScreensChanged)
794
795
796
797
798
799
    /**
     * Factor by which animation speed in the effect should be modified (multiplied).
     * If configurable in the effect itself, the option should have also 'default'
     * animation speed. The actual value should be determined using animationTime().
     * Note: The factor can be also 0, so make sure your code can cope with 0ms time
     * if used manually.
800
     */
801
    Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
802
    Q_PROPERTY(QList< KWin::EffectWindow* > stackingOrder READ stackingOrder)
803
804
    /**
     * Whether window decorations use the alpha channel.
805
     */
806
807
808
    Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
    /**
     * Whether the window decorations support blurring behind the decoration.
809
     */
810
811
812
    Q_PROPERTY(bool decorationSupportsBlurBehind READ decorationSupportsBlurBehind)
    Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
    Q_PROPERTY(QPoint cursorPos READ cursorPos)
813
814
    Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
    Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
815
    Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
816
817
818
819
820
821
822

    /**
     * The status of the session i.e if the user is logging out
     * @since 5.18
     */
    Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)

823
    friend class Effect;
824
public:
825
    explicit EffectsHandler(CompositingType type);
826
    ~EffectsHandler() override;
827
828
    // for use by effects
    virtual void prePaintScreen(ScreenPrePaintData& data, int time) = 0;
Albert Astals Cid's avatar
Albert Astals Cid committed
829
    virtual void paintScreen(int mask, const QRegion &region, ScreenPaintData& data) = 0;
830
831
    virtual void postPaintScreen() = 0;
    virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) = 0;
Albert Astals Cid's avatar
Albert Astals Cid committed
832
    virtual void paintWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data) = 0;
833
    virtual void postPaintWindow(EffectWindow* w) = 0;
Albert Astals Cid's avatar
Albert Astals Cid committed
834
835
    virtual void paintEffectFrame(EffectFrame* frame, const QRegion &region, double opacity, double frameOpacity) = 0;
    virtual void drawWindow(EffectWindow* w, int mask, const QRegion &region, WindowPaintData& data) = 0;
836
    virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList) = 0;
837
    virtual QVariant kwinOption(KWinOption kwopt) = 0;
838
839
840
841
    /**
     * Sets the cursor while the mouse is intercepted.
     * @see startMouseInterception
     * @since 4.11
842
     */
843
    virtual void defineCursor(Qt::CursorShape shape) = 0;
844
845
846
    virtual QPoint cursorPos() const = 0;
    virtual bool grabKeyboard(Effect* effect) = 0;
    virtual void ungrabKeyboard() = 0;
847
848
849
850
851
    /**
     * Ensures that all mouse events are sent to the @p effect.
     * No window will get the mouse events. Only fullscreen effects providing a custom user interface should
     * be using this method. The input events are delivered to Effect::windowInputMouseEvent.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
852
     * @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
853
854
     * all other windows, but no grab is performed.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
855
     * @param effect The effect
856
857
858
859
     * @param shape Sets the cursor to be used while the mouse is intercepted
     * @see stopMouseInterception
     * @see Effect::windowInputMouseEvent
     * @since 4.11
860
     */
861
862
863
864
865
    virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape) = 0;
    /**
     * Releases the hold mouse interception for @p effect
     * @see startMouseInterception
     * @since 4.11
866
     */
867
    virtual void stopMouseInterception(Effect *effect) = 0;
868

869
870
871
872
873
    /**
     * @brief Registers a global shortcut with the provided @p action.
     *
     * @param shortcut The global shortcut which should trigger the action
     * @param action The action which gets triggered when the shortcut matches
874
     */
875
    virtual void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) = 0;
876
877
878
879
880
881
    /**
     * @brief Registers a global pointer shortcut with the provided @p action.
     *
     * @param modifiers The keyboard modifiers which need to be holded
     * @param pointerButtons The pointer buttons which need to be pressed
     * @param action The action which gets triggered when the shortcut matches
882
     */
883
    virtual void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) = 0;
884
885
886
887
888
889
    /**
     * @brief Registers a global axis shortcut with the provided @p action.
     *
     * @param modifiers The keyboard modifiers which need to be holded
     * @param axis The direction in which the axis needs to be moved
     * @param action The action which gets triggered when the shortcut matches
890
     */
891
    virtual void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) = 0;
892

893
894
895
896
897
898
    /**
     * @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
     *
     * @param direction The direction for the swipe
     * @param action The action which gets triggered when the gesture triggers
     * @since 5.10
899
     */
900
901
    virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) = 0;

902
903
904
    /**
     * Retrieve the proxy class for an effect if it has one. Will return NULL if
     * the effect isn't loaded or doesn't have a proxy class.
905
     */
906
907
908
909
910
911
    virtual void* getProxy(QString name) = 0;

    // Mouse polling
    virtual void startMousePolling() = 0;
    virtual void stopMousePolling() = 0;

912
913
    virtual void reserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
    virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
914

915
916
917
918
    /**
     * Registers the given @p action for the given @p border to be activated through
     * a touch swipe gesture.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
919
     * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
920
921
922
     * signal gets invoked.
     *
     * To unregister the touch screen action either delete the @p action or
Yuri Chornoivan's avatar
Yuri Chornoivan committed
923
     * invoke unregisterTouchBorder.
924
925
926
     *
     * @see unregisterTouchBorder
     * @since 5.10
927
     */
928
929
930
931
932
933
    virtual void registerTouchBorder(ElectricBorder border, QAction *action) = 0;
    /**
     * Unregisters the given @p action for the given touch @p border.
     *
     * @see registerTouchBorder
     * @since 5.10
934
     */
935
936
    virtual void unregisterTouchBorder(ElectricBorder border, QAction *action) = 0;

937
    // functions that allow controlling windows/desktop
938
939
    virtual void activateWindow(KWin::EffectWindow* c) = 0;
    virtual KWin::EffectWindow* activeWindow() const = 0 ;
940
    Q_SCRIPTABLE virtual void moveWindow(KWin::EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) = 0;
941
942
943
944

    /**
     * Moves the window to the specific desktop
     * Setting desktop to NET::OnAllDesktops will set the window on all desktops
945
     */
946
    Q_SCRIPTABLE virtual void windowToDesktop(KWin::EffectWindow* w, int desktop) = 0;
947

948
    /**
949
950
951
952
953
     * Moves a window to the given desktops
     * On X11, the window will end up on the last window in the list
     * Setting this to an empty list will set the window on all desktops
     *
     * @arg desktopIds a list of desktops the window should be placed on. NET::OnAllDesktops is not a valid desktop X11Id
954
     */
955
956
    Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow* w, const QVector<uint> &desktopIds) = 0;

957
    Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, int screen) = 0;
958
959
    virtual void setShowingDesktop(bool showing) = 0;

960
961
962
    // Activities
    /**
     * @returns The ID of the current activity.
963
     */
964
    virtual QString currentActivity() const = 0;
965
966
967
    // Desktops
    /**
     * @returns The ID of the current desktop.
968
     */
969
970
971
    virtual int currentDesktop() const = 0;
    /**
     * @returns Total number of desktops currently in existence.
972
     */
973
974
975
    virtual int numberOfDesktops() const = 0;
    /**
     * Set the current desktop to @a desktop.
976
     */
977
978
    virtual void setCurrentDesktop(int desktop) = 0;
    /**
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
979
     * Sets the total number of desktops to @a desktops.
980
     */
981
982
983
    virtual void setNumberOfDesktops(int desktops) = 0;
    /**
     * @returns The size of desktop layout in grid units.
984
     */
985
986
987
    virtual QSize desktopGridSize() const = 0;
    /**
     * @returns The width of desktop layout in grid units.
988
     */
989
990
991
    virtual int desktopGridWidth() const = 0;
    /**
     * @returns The height of desktop layout in grid units.
992
     */
993
994
995
    virtual int desktopGridHeight() const = 0;
    /**
     * @returns The width of desktop layout in pixels.
996
     */
997
998
999
    virtual int workspaceWidth() const = 0;
    /**
     * @returns The height of desktop layout in pixels.
1000
     */
1001
1002
1003
1004
    virtual int workspaceHeight() const = 0;
    /**
     * @returns The ID of the desktop at the point @a coords or 0 if no desktop exists at that
     * point. @a coords is to be in grid units.
1005
     */
1006
1007
1008
    virtual int desktopAtCoords(QPoint coords) const = 0;
    /**
     * @returns The coords of desktop @a id in grid units.
1009
     */
1010
1011
1012
    virtual QPoint desktopGridCoords(int id) const = 0;
    /**
     * @returns The coords of the top-left corner of desktop @a id in pixels.
1013
     */
1014
1015
1016
1017
    virtual QPoint desktopCoords(int id) const = 0;
    /**
     * @returns The ID of the desktop above desktop @a id. Wraps around to the bottom of
     * the layout if @a wrap is set. If @a id is not set use the current one.
1018
     */
1019
    Q_SCRIPTABLE virtual int desktopAbove(int desktop = 0, bool wrap = true) const = 0;
1020
1021
1022
    /**
     * @returns The ID of the desktop to the right of desktop @a id. Wraps around to the
     * left of the layout if @a wrap is set. If @a id is not set use the current one.
1023
     */
1024
    Q_SCRIPTABLE virtual int desktopToRight(int desktop = 0, bool wrap = true) const = 0;
1025
1026
1027
    /**
     * @returns The ID of the desktop below desktop @a id. Wraps around to the top of the
     * layout if @a wrap is set. If @a id is not set use the current one.
1028
     */
1029
    Q_SCRIPTABLE virtual int desktopBelow(int desktop = 0, bool wrap = true) const = 0;
1030
1031
1032
    /**
     * @returns The ID of the desktop to the left of desktop @a id. Wraps around to the
     * right of the layout if @a wrap is set. If @a id is not set use the current one.
1033
     */
1034
1035
    Q_SCRIPTABLE virtual int desktopToLeft(int desktop = 0, bool wrap = true) const = 0;
    Q_SCRIPTABLE virtual QString desktopName(int desktop) const = 0;
1036
1037
1038
1039
    virtual bool optionRollOverDesktops() const = 0;

    virtual int activeScreen() const = 0; // Xinerama
    virtual int numScreens() const = 0; // Xinerama
1040
    Q_SCRIPTABLE virtual int screenNumber(const QPoint& pos) const = 0;   // Xinerama
1041
1042
1043
    virtual QRect clientArea(clientAreaOption, int screen, int desktop) const = 0;
    virtual QRect clientArea(clientAreaOption, const EffectWindow* c) const = 0;
    virtual QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const = 0;
1044
1045
1046
1047
1048
1049
1050
1051

    /**
     * The bounding size of all screens combined. Overlapping areas
     * are not counted multiple times.
     *
     * @see virtualScreenGeometry()
     * @see virtualScreenSizeChanged()
     * @since 5.0
1052
     */
1053
1054
1055
1056
1057
1058
1059
1060
    virtual QSize virtualScreenSize() const = 0;
    /**
     * The bounding geometry of all outputs combined. Always starts at (0,0) and has
     * virtualScreenSize as it's size.
     *
     * @see virtualScreenSize()
     * @see virtualScreenGeometryChanged()
     * @since 5.0
1061
     */
1062
    virtual QRect virtualScreenGeometry() const = 0;
1063
1064
1065
1066
1067
1068
    /**
     * Factor by which animation speed in the effect should be modified (multiplied).
     * If configurable in the effect itself, the option should have also 'default'
     * animation speed. The actual value should be determined using animationTime().
     * Note: The factor can be also 0, so make sure your code can cope with 0ms time
     * if used manually.
1069
     */
1070
1071
1072
    virtual double animationTimeFactor() const = 0;
    virtual WindowQuadType newWindowQuadType() = 0;

1073
    Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(WId id) const = 0;
1074
    Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(KWaylandServer::SurfaceInterface *surf) const = 0;
1075
1076
1077
1078
1079
1080
1081
1082
    /**
     * Finds the EffectWindow for the internal window @p w.
     * If there is no such window @c null is returned.
     *
     * On Wayland this returns the internal window. On X11 it returns an Unamanged with the
     * window id matching that of the provided window @p w.
     *
     * @since 5.16
1083
     */
1084
    Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
1085
1086
1087
1088
1089
    /**
     * Finds the EffectWindow for the Toplevel with KWin internal @p id.
     * If there is no such window @c null is returned.
     *
     * @since 5.16
1090
     */
1091
    Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(const QUuid &id) const = 0;
1092
1093
    virtual EffectWindowList stackingOrder() const = 0;
    // window will be temporarily painted as if being at the top of the stack
1094
    Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0;
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

    virtual void setTabBoxWindow(EffectWindow*) = 0;
    virtual void setTabBoxDesktop(int) = 0;
    virtual EffectWindowList currentTabBoxWindowList() const = 0;
    virtual void refTabBox() = 0;
    virtual void unrefTabBox() = 0;
    virtual void closeTabBox() = 0;
    virtual QList< int > currentTabBoxDesktopList() const = 0;
    virtual int currentTabBoxDesktop() const = 0;
    virtual EffectWindow* currentTabBoxWindow() const = 0;

    virtual void setActiveFullScreenEffect(Effect* e) = 0;
    virtual Effect* activeFullScreenEffect() const = 0;

    /**
     * Schedules the entire workspace to be repainted next time.
     * If you call it during painting (including prepaint) then it does not
     *  affect the current painting.
1113
     */
1114
1115
1116
1117
    Q_SCRIPTABLE virtual void addRepaintFull() = 0;
    Q_SCRIPTABLE virtual void addRepaint(const QRect& r) = 0;
    Q_SCRIPTABLE virtual void addRepaint(const QRegion& r) = 0;
    Q_SCRIPTABLE virtual void addRepaint(int x, int y, int w, int h) = 0;
1118
1119

    CompositingType compositingType() const;
1120
1121
1122
1123
    /**
     * @brief Whether the Compositor is OpenGL based (either GL 1 or 2).
     *
     * @return bool @c true in case of OpenGL based Compositor, @c false otherwise
1124
     */
1125
    bool isOpenGLCompositing() const;
1126
    virtual unsigned long xrenderBufferPicture() = 0;
1127
1128
1129
1130
1131
1132
1133
    /**
     * @brief Provides access to the QPainter which is rendering to the back buffer.
     *
     * Only relevant for CompositingType QPainterCompositing. For all other compositing types
     * @c null is returned.
     *
     * @return QPainter* The Scene's QPainter or @c null.
1134
     */