kwineffects.h 135 KB
Newer Older
1
/********************************************************************
2 3 4 5
 KWin - the KDE window manager
 This file is part of the KDE project.

Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
6
Copyright (C) 2009 Lucas Murray <lmurray@undefinedfire.com>
Martin Flöser's avatar
Martin Flöser committed
7
Copyright (C) 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
8
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
9

10 11 12 13 14 15 16 17 18 19 20 21 22
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
23

24 25
#ifndef KWINEFFECTS_H
#define KWINEFFECTS_H
26

27
#include <kwinconfig.h>
28
#include <kwineffects_export.h>
29 30
#include <kwinglobals.h>

31
#include <QEasingCurve>
32
#include <QIcon>
33 34 35
#include <QPair>
#include <QSet>
#include <QRect>
36 37 38
#include <QRegion>
#include <QVector2D>
#include <QVector3D>
39

40
#include <QVector>
41
#include <QLoggingCategory>
42 43 44
#include <QList>
#include <QHash>
#include <QStack>
45
#include <QScopedPointer>
46

47
#include <KPluginFactory>
48
#include <KSharedConfig>
Bernhard Loos's avatar
Bernhard Loos committed
49

50
#include <assert.h>
51
#include <limits.h>
Thomas Lübking's avatar
Thomas Lübking committed
52
#include <netwm.h>
53

54 55
#include <functional>

56
class KConfigGroup;
Martin Flöser's avatar
Martin Flöser committed
57
class QFont;
58
class QGraphicsScale;
59
class QKeyEvent;
60
class QMatrix4x4;
61
class QAction;
62

63 64 65 66
/**
 * Logging category to be used inside the KWin effects.
 * Do not use in this library.
 **/
Allen Winter's avatar
Allen Winter committed
67
Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
68

69 70 71 72 73 74 75
namespace KWayland {
    namespace Server {
        class SurfaceInterface;
        class Display;
    }
}

76 77 78
namespace KWin
{

79
class PaintDataPrivate;
80
class WindowPaintDataPrivate;
81

82 83
class EffectWindow;
class EffectWindowGroup;
84
class EffectFrame;
85
class EffectFramePrivate;
86
class Effect;
87
class WindowQuad;
88
class GLShader;
89
class XRenderPicture;
90 91 92 93 94
class WindowQuadList;
class WindowPrePaintData;
class WindowPaintData;
class ScreenPrePaintData;
class ScreenPaintData;
95 96

typedef QPair< QString, Effect* > EffectPair;
97
typedef QList< KWin::EffectWindow* > EffectWindowList;
98 99


100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/** @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.
 *
117 118 119 120 121
 * @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.
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 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
 *
 * @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.
 *
 * @{
 **/

#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
191
#define KWIN_EFFECT_API_VERSION_MINOR 227
192
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
193
        KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
194

195
enum WindowQuadType {
196 197
    WindowQuadError, // for the stupid default ctor
    WindowQuadContents,
198
    WindowQuadDecoration,
199
    // Shadow Quad types
Fredrik Höglund's avatar
Fredrik Höglund committed
200
    WindowQuadShadow,             // OpenGL only. The other shadow types are only used by Xrender
201 202 203 204 205 206 207 208
    WindowQuadShadowTop,
    WindowQuadShadowTopRight,
    WindowQuadShadowRight,
    WindowQuadShadowBottomRight,
    WindowQuadShadowBottom,
    WindowQuadShadowBottomLeft,
    WindowQuadShadowLeft,
    WindowQuadShadowTopLeft,
209
    EFFECT_QUAD_TYPE_START = 100 ///< @internal
210
};
211

212 213 214 215
/**
 * EffectWindow::setData() and EffectWindow::data() global roles.
 * All values between 0 and 999 are reserved for global roles.
 */
216
enum DataRole {
217 218 219 220 221
    // 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,
222
    WindowUnminimizedGrabRole,
223
    WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
224
    WindowBlurBehindRole, ///< For single windows to blur behind
225 226
    WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
    WindowBackgroundContrastRole, ///< For single windows to enable Background contrast
227
    LanczosCacheRole
228
};
229

230 231 232 233
/**
 * Style types used by @ref EffectFrame.
 * @since 4.6
 */
234
enum EffectFrameStyle {
235 236 237
    EffectFrameNone, ///< Displays no frame around the contents.
    EffectFrameUnstyled, ///< Displays a basic box around the contents.
    EffectFrameStyled ///< Displays a Plasma-styled frame around the contents.
238
};
239

240 241 242
/**
 * Infinite region (i.e. a special region type saying that everything needs to be painted).
 */
243
KWINEFFECTS_EXPORT inline
244
QRect infiniteRegion()
245 246 247 248
{
    // 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);
}
249

Rivo Laks's avatar
Rivo Laks committed
250 251 252 253 254 255
/**
 * @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.
 *
256 257 258 259 260
 * 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
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 286 287 288 289 290 291 292 293 294 295 296 297 298
 *
 * @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.
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
 *
 * @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.
Rivo Laks's avatar
Rivo Laks committed
314
 **/
315
class KWINEFFECTS_EXPORT Effect : public QObject
316
{
317
    Q_OBJECT
318 319 320 321
public:
    /** Flags controlling how painting is done. */
    // TODO: is that ok here?
    enum {
Rivo Laks's avatar
Rivo Laks committed
322
        /**
323
         * Window (or at least part of it) will be painted opaque.
Rivo Laks's avatar
Rivo Laks committed
324
         **/
325
        PAINT_WINDOW_OPAQUE         = 1 << 0,
Rivo Laks's avatar
Rivo Laks committed
326
        /**
327
         * Window (or at least part of it) will be painted translucent.
Rivo Laks's avatar
Rivo Laks committed
328
         **/
329
        PAINT_WINDOW_TRANSLUCENT    = 1 << 1,
330
        /**
331
         * Window will be painted with transformed geometry.
Rivo Laks's avatar
Rivo Laks committed
332
         **/
333
        PAINT_WINDOW_TRANSFORMED    = 1 << 2,
Rivo Laks's avatar
Rivo Laks committed
334
        /**
335 336
         * Paint only a region of the screen (can be optimized, cannot
         * be used together with TRANSFORMED flags).
Rivo Laks's avatar
Rivo Laks committed
337
         **/
338
        PAINT_SCREEN_REGION         = 1 << 3,
Rivo Laks's avatar
Rivo Laks committed
339
        /**
340 341
         * The whole screen will be painted with transformed geometry.
         * Forces the entire screen to be painted.
Rivo Laks's avatar
Rivo Laks committed
342
         **/
343
        PAINT_SCREEN_TRANSFORMED    = 1 << 4,
Rivo Laks's avatar
Rivo Laks committed
344
        /**
345 346
         * At least one window will be painted with transformed geometry.
         * Forces the entire screen to be painted.
Rivo Laks's avatar
Rivo Laks committed
347
         **/
348
        PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
Rivo Laks's avatar
Rivo Laks committed
349
        /**
350
         * Clear whole background as the very first step, without optimizing it
Rivo Laks's avatar
Rivo Laks committed
351
         **/
352
        PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
353
        // PAINT_DECORATION_ONLY = 1 << 7 has been deprecated
354
        /**
355
         * Window will be painted with a lanczos filter.
356
         **/
Laurent Montel's avatar
Laurent Montel committed
357
        PAINT_WINDOW_LANCZOS = 1 << 8
358
        // PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS = 1 << 9 has been removed
359
    };
360

361
    enum Feature {
362 363 364 365 366 367 368 369
        Nothing = 0,
        Resize,
        GeometryTip,
        Outline, /**< @deprecated */
        ScreenInversion,
        Blur,
        Contrast,
        HighlightWindows
370
    };
371

372 373
    /**
     * Constructs new Effect object.
374 375 376
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when the Effect is constructed.
377 378 379 380
     **/
    Effect();
    /**
     * Destructs the Effect object.
381 382 383
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when the Effect is destroyed.
384 385 386 387 388 389 390 391
     **/
    virtual ~Effect();

    /**
     * Flags describing which parts of configuration have changed.
     */
    enum ReconfigureFlag {
        ReconfigureAll = 1 << 0 /// Everything needs to be reconfigured.
392
    };
393 394 395 396
    Q_DECLARE_FLAGS(ReconfigureFlags, ReconfigureFlag)

    /**
     * Called when configuration changes (either the effect's or KWin's global).
397 398 399 400
     *
     * 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.
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
     */
    virtual void reconfigure(ReconfigureFlags flags);

    /**
     * Called when another effect requests the proxy for this effect.
     */
    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
416 417 418
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
419 420 421 422 423 424 425 426
    **/
    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
427 428 429
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
430 431 432 433 434 435 436
     **/
    virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
    /**
     * 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.
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 448 449
     **/
    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
450 451 452
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
453 454 455 456 457 458 459 460
     **/
    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
461 462 463
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
464 465 466 467 468 469 470
     **/
    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.
471 472 473
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
474 475 476 477 478 479 480 481 482 483 484 485
     **/
    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
486 487 488
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
489 490 491 492 493
     **/
    virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity);

    /**
     * Called on Transparent resizes.
494
     * return true if your effect substitutes questioned feature
495 496 497
    */
    virtual bool provides(Feature);

498 499 500 501 502 503 504 505 506 507 508 509 510
    /**
     * 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
     **/
    virtual bool perform(Feature feature, const QVariantList &arguments);

511 512 513
    /**
     * 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
514 515 516 517
     *  do any transformations.
     *
     * In OpenGL based compositing, the frameworks ensures that the context is current
     * when this method is invoked.
518 519 520 521 522 523 524 525 526
     **/
    virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);

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

527
    virtual void windowInputMouseEvent(QEvent* e);
528 529
    virtual void grabbedKeyboardEvent(QKeyEvent* e);

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
    /**
     * 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
     **/
    virtual bool isActive() const;

547 548
    /**
     * Reimplement this method to provide online debugging.
Yuri Chornoivan's avatar
Yuri Chornoivan committed
549
     * This could be as trivial as printing specific detail information about the effect state
550 551 552 553 554 555 556 557 558 559
     * 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
     */
    virtual QString debug(const QString &parameter) const;

560 561 562 563 564 565 566 567 568 569 570 571 572 573
    /**
     * 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
     **/
    virtual int requestedEffectChainPosition() const;

574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634

    /**
     * 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
     **/
    virtual bool touchDown(quint32 id, const QPointF &pos, quint32 time);
    /**
     * 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
     **/
    virtual bool touchMotion(quint32 id, const QPointF &pos, quint32 time);
    /**
     * 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
     **/
    virtual bool touchUp(quint32 id, quint32 time);

635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
    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
     */
    // 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.
     */
    static double animationTime(int defaultTime);
653 654 655 656 657 658
    /**
     * @overload Use this variant if animation time is provided through a KConfigXT generated class
     * having a property called "duration".
     **/
    template <typename T>
    int animationTime(int defaultDuration);
659 660 661 662 663 664 665 666 667 668 669 670 671
    /**
     * Linearly interpolates between @p x and @p y.
     *
     * Returns @p x when @p a = 0; returns @p y when @p a = 1.
     **/
    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)
     **/
    static void setPositionTransformations(WindowPaintData& data, QRect& region, EffectWindow* w,
                                           const QRect& r, Qt::AspectRatioMode aspect);
672 673 674

public Q_SLOTS:
    virtual bool borderActivated(ElectricBorder border);
675 676 677 678

protected:
    xcb_connection_t *xcbConnection() const;
    xcb_window_t x11RootWindow() const;
679 680 681 682 683 684 685 686

    /**
     * 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
     **/
    template <typename T>
    void initConfig();
687
};
688 689 690


/**
691 692 693 694 695 696
 * Prefer the KWIN_EFFECT_FACTORY macros.
 */
class KWINEFFECTS_EXPORT EffectPluginFactory : public KPluginFactory
{
    Q_OBJECT
public:
697
    EffectPluginFactory();
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
    virtual ~EffectPluginFactory();
    /**
     * 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.
     */
    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.
     */
    virtual bool enabledByDefault() const;
    /**
     * This method returns the created Effect.
     */
    virtual KWin::Effect *createEffect() const = 0;
};
728 729

/**
730
 * Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.
731
 *
732 733 734
 * 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.
735
 *
736 737 738 739
 * 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.
740
 *
741 742 743 744 745
 * @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
746
 **/
747 748 749 750 751 752 753
#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: \
754
        explicit factoryName() {} \
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776
        ~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 )

#define KWIN_EFFECT_FACTORY_SUPPORTED( factoryName, classname, jsonFile, supported ) \
    KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, supported, return true; )

#define KWIN_EFFECT_FACTORY( factoryName, classname, jsonFile ) \
    KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, return true;, return true; )

777

778

Rivo Laks's avatar
Rivo Laks committed
779 780 781 782 783 784 785 786 787 788
/**
 * @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.
 **/
789
class KWINEFFECTS_EXPORT EffectsHandler : public QObject
790
{
791
    Q_OBJECT
792
    Q_PROPERTY(int currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
793
    Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
794 795 796 797 798 799 800 801 802 803 804 805
    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.
     **/
    Q_PROPERTY(int desktops READ numberOfDesktops WRITE setNumberOfDesktops NOTIFY numberDesktopsChanged)
    Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
    Q_PROPERTY(int activeScreen READ activeScreen)
806
    Q_PROPERTY(int numScreens READ numScreens NOTIFY numberScreensChanged)
807 808 809 810 811 812 813 814
    /**
     * 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.
     */
    Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
815
    Q_PROPERTY(QList< KWin::EffectWindow* > stackingOrder READ stackingOrder)
816 817 818 819 820 821 822 823 824 825
    /**
     * Whether window decorations use the alpha channel.
     **/
    Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
    /**
     * Whether the window decorations support blurring behind the decoration.
     **/
    Q_PROPERTY(bool decorationSupportsBlurBehind READ decorationSupportsBlurBehind)
    Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
    Q_PROPERTY(QPoint cursorPos READ cursorPos)
826 827
    Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
    Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
828
    Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
829
    friend class Effect;
830
public:
831
    explicit EffectsHandler(CompositingType type);
832 833 834 835 836 837 838 839 840 841 842
    virtual ~EffectsHandler();
    // for use by effects
    virtual void prePaintScreen(ScreenPrePaintData& data, int time) = 0;
    virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data) = 0;
    virtual void postPaintScreen() = 0;
    virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) = 0;
    virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) = 0;
    virtual void postPaintWindow(EffectWindow* w) = 0;
    virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity) = 0;
    virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) = 0;
    virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList) = 0;
843
    virtual QVariant kwinOption(KWinOption kwopt) = 0;
844 845 846 847 848 849
    /**
     * Sets the cursor while the mouse is intercepted.
     * @see startMouseInterception
     * @since 4.11
     **/
    virtual void defineCursor(Qt::CursorShape shape) = 0;
850 851 852
    virtual QPoint cursorPos() const = 0;
    virtual bool grabKeyboard(Effect* effect) = 0;
    virtual void ungrabKeyboard() = 0;
853 854 855 856 857
    /**
     * 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
858
     * @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
859 860
     * all other windows, but no grab is performed.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
861
     * @param effect The effect
862 863 864 865 866 867 868 869 870 871 872 873
     * @param shape Sets the cursor to be used while the mouse is intercepted
     * @see stopMouseInterception
     * @see Effect::windowInputMouseEvent
     * @since 4.11
     **/
    virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape) = 0;
    /**
     * Releases the hold mouse interception for @p effect
     * @see startMouseInterception
     * @since 4.11
     **/
    virtual void stopMouseInterception(Effect *effect) = 0;
874

875 876 877 878 879 880 881
    /**
     * @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
     */
    virtual void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) = 0;
882 883 884 885 886 887 888 889
    /**
     * @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
     **/
    virtual void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) = 0;
890 891 892 893 894 895 896 897
    /**
     * @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
     **/
    virtual void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) = 0;
898

899 900 901 902 903 904 905 906 907
    /**
     * @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
     **/
    virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) = 0;

908 909 910 911 912 913 914 915 916 917
    /**
     * 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.
     */
    virtual void* getProxy(QString name) = 0;

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

918 919
    virtual void reserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
    virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
920

921 922 923 924
    /**
     * 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
925
     * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
926 927 928
     * signal gets invoked.
     *
     * To unregister the touch screen action either delete the @p action or
Yuri Chornoivan's avatar
Yuri Chornoivan committed
929
     * invoke unregisterTouchBorder.
930 931 932 933 934 935 936 937 938 939 940 941 942
     *
     * @see unregisterTouchBorder
     * @since 5.10
     **/
    virtual void registerTouchBorder(ElectricBorder border, QAction *action) = 0;
    /**
     * Unregisters the given @p action for the given touch @p border.
     *
     * @see registerTouchBorder
     * @since 5.10
     **/
    virtual void unregisterTouchBorder(ElectricBorder border, QAction *action) = 0;

943
    // functions that allow controlling windows/desktop
944 945
    virtual void activateWindow(KWin::EffectWindow* c) = 0;
    virtual KWin::EffectWindow* activeWindow() const = 0 ;
946
    Q_SCRIPTABLE virtual void moveWindow(KWin::EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) = 0;
947 948 949 950 951

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

954
    /**
955 956 957 958 959
     * 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
960
     */
961 962
    Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow* w, const QVector<uint> &desktopIds) = 0;

963
    Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, int screen) = 0;
964 965
    virtual void setShowingDesktop(bool showing) = 0;

966 967 968 969 970
    // Activities
    /**
     * @returns The ID of the current activity.
     */
    virtual QString currentActivity() const = 0;
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
    // Desktops
    /**
     * @returns The ID of the current desktop.
     */
    virtual int currentDesktop() const = 0;
    /**
     * @returns Total number of desktops currently in existence.
     */
    virtual int numberOfDesktops() const = 0;
    /**
     * Set the current desktop to @a desktop.
     */
    virtual void setCurrentDesktop(int desktop) = 0;
    /**
    * Sets the total number of desktops to @a desktops.
    */
    virtual void setNumberOfDesktops(int desktops) = 0;
    /**
     * @returns The size of desktop layout in grid units.
     */
    virtual QSize desktopGridSize() const = 0;
    /**
     * @returns The width of desktop layout in grid units.
     */
    virtual int desktopGridWidth() const = 0;
    /**
     * @returns The height of desktop layout in grid units.
     */
    virtual int desktopGridHeight() const = 0;
    /**
     * @returns The width of desktop layout in pixels.
     */
    virtual int workspaceWidth() const = 0;
    /**
     * @returns The height of desktop layout in pixels.
     */
    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.
     */
    virtual int desktopAtCoords(QPoint coords) const = 0;
    /**
     * @returns The coords of desktop @a id in grid units.
     */
    virtual QPoint desktopGridCoords(int id) const = 0;
    /**
     * @returns The coords of the top-left corner of desktop @a id in pixels.
     */
    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.
     */
1025
    Q_SCRIPTABLE virtual int desktopAbove(int desktop = 0, bool wrap = true) const = 0;
1026 1027 1028 1029
    /**
     * @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.
     */
1030
    Q_SCRIPTABLE virtual int desktopToRight(int desktop = 0, bool wrap = true) const = 0;
1031 1032 1033 1034
    /**
     * @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.
     */
1035
    Q_SCRIPTABLE virtual int desktopBelow(int desktop = 0, bool wrap = true) const = 0;
1036 1037 1038 1039
    /**
     * @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.
     */
1040 1041
    Q_SCRIPTABLE virtual int desktopToLeft(int desktop = 0, bool wrap = true) const = 0;
    Q_SCRIPTABLE virtual QString desktopName(int desktop) const = 0;
1042 1043 1044 1045
    virtual bool optionRollOverDesktops() const = 0;

    virtual int activeScreen() const = 0; // Xinerama
    virtual int numScreens() const = 0; // Xinerama
1046
    Q_SCRIPTABLE virtual int screenNumber(const QPoint& pos) const = 0;   // Xinerama
1047 1048 1049
    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;
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

    /**
     * The bounding size of all screens combined. Overlapping areas
     * are not counted multiple times.
     *
     * @see virtualScreenGeometry()
     * @see virtualScreenSizeChanged()
     * @since 5.0
     **/
    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
     **/
    virtual QRect virtualScreenGeometry() const = 0;
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
    /**
     * 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.
     */
    virtual double animationTimeFactor() const = 0;
    virtual WindowQuadType newWindowQuadType() = 0;

1079
    Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(WId id) const = 0;
Marco Martin's avatar
Marco Martin committed
1080
    Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const = 0;
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
    /**
     * 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
     **/
    Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
1091 1092 1093 1094 1095 1096 1097
    /**
     * Finds the EffectWindow for the Toplevel with KWin internal @p id.
     * If there is no such window @c null is returned.
     *
     * @since 5.16
     **/
    Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(const QUuid &id) const = 0;
1098 1099
    virtual EffectWindowList stackingOrder() const = 0;
    // window will be temporarily painted as if being at the top of the stack
1100
    Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0;
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119

    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.
     **/
1120 1121 1122 1123
    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;
1124 1125

    CompositingType compositingType() const;
1126 1127 1128 1129 1130 1131
    /**
     * @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
     **/
    bool isOpenGLCompositing() const;
1132
    virtual unsigned long xrenderBufferPicture() = 0;
1133 1134 1135 1136 1137 1138 1139 1140 1141
    /**
     * @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.
     */
    virtual QPainter *scenePainter() = 0;
1142 1143 1144
    virtual void reconfigure() = 0;

    virtual QByteArray readRootProperty(long atom, long type, int format) const = 0;
1145 1146 1147 1148 1149 1150 1151
    /**
     * @brief Announces support for the feature with the given name. If no other Effect
     * has announced support for this feature yet, an X11 property will be installed on
     * the root window.
     *
     * The Effect will be notified for events through the signal propertyNotify().
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
1152
     * To remove the support again use removeSupportProperty. When an Effect is
1153
     * destroyed it is automatically taken care of removing the support. It is not
Yuri Chornoivan's avatar
Yuri Chornoivan committed
1154
     * required to call removeSupportProperty in the Effect's cleanup handling.
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
     *
     * @param propertyName The name of the property to announce support for
     * @param effect The effect which announces support
     * @return xcb_atom_t The created X11 atom
     * @see removeSupportProperty
     * @since 4.11
     **/
    virtual xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
    /**
     * @brief Removes support for the feature with the given name. If there is no other Effect left
     * which has announced support for the given property, the property will be removed from the
     * root window.
     *
     * In case the Effect had not registered support, calling this function does not change anything.
     *
     * @param propertyName The name of the property to remove support for
     * @param effect The effect which had registered the property.
     * @see announceSupportProperty
     * @since 4.11
     **/
    virtual void removeSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204

    /**
     * Returns @a true if the active window decoration has shadow API hooks.
     */
    virtual bool hasDecorationShadows() const = 0;

    /**
     * Returns @a true if the window decorations use the alpha channel, and @a false otherwise.
     * @since 4.5
     */
    virtual bool decorationsHaveAlpha() const = 0;

    /**
     * Returns @a true if the window decorations support blurring behind the decoration, and @a false otherwise
     * @since 4.6
     */
    virtual bool decorationSupportsBlurBehind() const = 0;

    /**
     * Creates a new frame object. If the frame does not have a static size
     * then it will be located at @a position with @a alignment. A
     * non-static frame will automatically adjust its size to fit the contents.
     * @returns A new @ref EffectFrame. It is the responsibility of the caller to delete the
     * EffectFrame.
     * @since 4.6
     */
    virtual EffectFrame* effectFrame(EffectFrameStyle style, bool staticSize = true,
                                     const QPoint& position = QPoint(-1, -1), Qt::Alignment alignment = Qt::AlignCenter) const = 0;

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
    /**
     * Allows an effect to trigger a reload of itself.
     * This can be used by an effect which needs to be reloaded when screen geometry changes.
     * It is possible that the effect cannot be loaded again as it's supported method does no longer
     * hold.
     * @param effect The effect to reload
     * @since 4.8
     **/
    virtual void reloadEffect(Effect *effect) = 0;

1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
    /**
     * Whether the screen is currently considered as locked.
     * Note for technical reasons this is not always possible to detect. The screen will only
     * be considered as locked if the screen locking process implements the
     * org.freedesktop.ScreenSaver interface.
     *
     * @returns @c true if the screen is currently locked, @c false otherwise
     * @see screenLockingChanged
     * @since 4.11
     **/
    virtual bool isScreenLocked() const = 0;

1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
    /**
     * @brief Makes the OpenGL compositing context current.
     *
     * If the compositing backend is not using OpenGL, this method returns @c false.
     *
     * @return bool @c true if the context became current, @c false otherwise.
     */
    virtual bool makeOpenGLContextCurrent() = 0;
    /**
     * @brief Makes a null OpenGL context current resulting in no context
     * being current.
     *
     * If the compositing backend is not OpenGL based, this method is a noop.
     *
     * There is normally no reason for an Effect to call this method.
     */
    virtual void doneOpenGLContextCurrent() = 0;

1245 1246 1247
    virtual xcb_connection_t *xcbConnection() const = 0;
    virtual xcb_window_t x11RootWindow() const = 0;

1248 1249 1250 1251 1252 1253 1254
    /**
     * Interface to the Wayland display: this is relevant only
     * on Wayland, on X11 it will be nullptr
     * @since 5.5
     */
    virtual KWayland::Server::Display *waylandDisplay() const = 0;

1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
    /**
     * Whether animations are supported by the Scene.
     * If this method returns @c false Effects are supposed to not
     * animate transitions.
     *
     * @returns Whether the Scene can drive animations
     * @since 5.8
     **/
    virtual bool animationsSupported() const = 0;

1265 1266 1267 1268 1269 1270 1271
    /**
     * The current cursor image of the Platform.
     * @see cursorPos
     * @since 5.9
     **/
    virtual PlatformCursorImage cursorImage() const = 0;

1272 1273 1274 1275 1276 1277 1278 1279
    /**
     * The cursor image should be hidden.
     * @see showCursor
     * @since 5.9
     **/
    virtual void hideCursor() = 0;

    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
1280
     * The cursor image should be shown again after having been hidden.
1281 1282 1283 1284 1285
     * @see hideCursor
     * @since 5.9
     **/
    virtual void showCursor() = 0;

1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
    /**
     * Starts an interactive window selection process.
     *
     * Once the user selected a window the @p callback is invoked with the selected EffectWindow as
     * argument. In case the user cancels the interactive window selection or selecting a window is currently
     * not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument.
     *
     * During the interactive window selection the cursor is turned into a crosshair cursor.
     *
     * @param callback The function to invoke once the interactive window selection ends
     * @since 5.9
     **/
    virtual void startInteractiveWindowSelection(std::function<void(KWin::EffectWindow*)> callback) = 0;

1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
    /**
     * Starts an interactive position selection process.
     *
     * Once the user selected a position on the screen the @p callback is invoked with
     * the selected point as argument. In case the user cancels the interactive position selection
     * or selecting a position is currently not possible (e.g. screen locked) the @p callback
     * is invoked with a point at @c -1 as x and y argument.
     *
     * During the interactive window selection the cursor is turned into a crosshair cursor.
     *
     * @param callback The function to invoke once the interactive position selection ends
     * @since 5.9
     **/
    virtual void startInteractivePositionSelection(std::function<void(const QPoint &)> callback) = 0;

1315
    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
1316
     * Shows an on-screen-message. To hide it again use hideOnScreenMessage.
1317 1318 1319 1320 1321 1322 1323 1324
     *
     * @param message The message to show
     * @param iconName The optional themed icon name
     * @see hideOnScreenMessage
     * @since 5.9
     **/
    virtual void showOnScreenMessage(const QString &message, const QString &iconName = QString()) = 0;

1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
    /**
     * Flags for how to hide a shown on-screen-message
     * @see hideOnScreenMessage
     * @since 5.9
     **/
    enum class OnScreenMessageHideFlag {
        /**
         * The on-screen-message should skip the close window animation.
         * @see EffectWindow::skipsCloseAnimation
         **/
        SkipsCloseAnimation = 1
    };
    Q_DECLARE_FLAGS(OnScreenMessageHideFlags, OnScreenMessageHideFlag)
1338 1339
    /**
     * Hides a previously shown on-screen-message again.
1340
     * @param flags The flags for how to hide the message
1341 1342 1343
     * @see showOnScreenMessage
     * @since 5.9
     **/