File indexing completed on 2024-05-19 16:34:32

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0006     SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
0007     SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
0008     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 
0013 #pragma once
0014 
0015 #include <kwinconfig.h>
0016 #include <kwineffects_export.h>
0017 #include <kwinglobals.h>
0018 
0019 #include <QEasingCurve>
0020 #include <QIcon>
0021 #include <QPair>
0022 #include <QRect>
0023 #include <QRegion>
0024 #include <QSet>
0025 #include <QVector2D>
0026 #include <QVector3D>
0027 
0028 #include <QHash>
0029 #include <QList>
0030 #include <QLoggingCategory>
0031 #include <QStack>
0032 #include <QVector>
0033 
0034 #include <KPluginFactory>
0035 #include <KSharedConfig>
0036 
0037 #include <netwm.h>
0038 
0039 #include <climits>
0040 #include <cmath>
0041 #include <functional>
0042 #include <optional>
0043 #include <span>
0044 
0045 class KConfigGroup;
0046 class QFont;
0047 class QKeyEvent;
0048 class QMatrix4x4;
0049 class QAction;
0050 class QTabletEvent;
0051 
0052 /**
0053  * Logging category to be used inside the KWin effects.
0054  * Do not use in this library.
0055  */
0056 Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
0057 
0058 namespace KDecoration2
0059 {
0060 class Decoration;
0061 }
0062 
0063 namespace KWaylandServer
0064 {
0065 class SurfaceInterface;
0066 class Display;
0067 }
0068 
0069 namespace KWin
0070 {
0071 
0072 class PaintDataPrivate;
0073 class WindowPaintDataPrivate;
0074 
0075 class EffectWindow;
0076 class EffectWindowGroup;
0077 class EffectFrame;
0078 class EffectFramePrivate;
0079 class OffscreenQuickView;
0080 class EffectScreen;
0081 class Effect;
0082 class WindowQuad;
0083 class WindowQuadList;
0084 class WindowPrePaintData;
0085 class WindowPaintData;
0086 class ScreenPrePaintData;
0087 class ScreenPaintData;
0088 
0089 typedef QPair<QString, Effect *> EffectPair;
0090 typedef QList<KWin::EffectWindow *> EffectWindowList;
0091 
0092 /** @defgroup kwineffects KWin effects library
0093  * KWin effects library contains necessary classes for creating new KWin
0094  * compositing effects.
0095  *
0096  * @section creating Creating new effects
0097  * This example will demonstrate the basics of creating an effect. We'll use
0098  *  CoolEffect as the class name, cooleffect as internal name and
0099  *  "Cool Effect" as user-visible name of the effect.
0100  *
0101  * This example doesn't demonstrate how to write the effect's code. For that,
0102  *  see the documentation of the Effect class.
0103  *
0104  * @subsection creating-class CoolEffect class
0105  * First you need to create CoolEffect class which has to be a subclass of
0106  *  @ref KWin::Effect. In that class you can reimplement various virtual
0107  *  methods to control how and where the windows are drawn.
0108  *
0109  * @subsection creating-macro KWIN_EFFECT_FACTORY macro
0110  * This library provides a specialized KPluginFactory subclass and macros to
0111  * create a sub class. This subclass of KPluginFactory has to be used, otherwise
0112  * KWin won't load the plugin. Use the @ref KWIN_EFFECT_FACTORY macro to create the
0113  * plugin factory. This macro will take the embedded json metadata filename as the second argument.
0114  *
0115  * @subsection creating-buildsystem Buildsystem
0116  * To build the effect, you can use the kcoreaddons_add_plugin cmake macro which
0117  *  takes care of creating the library and installing it.
0118  *  The first parameter is the name of the library, this is the same as the id of the plugin.
0119  *  If our effect's source is in cooleffect.cpp, we'd use following:
0120  * @code
0121  *     kcoreaddons_add_plugin(cooleffect SOURCES cooleffect.cpp INSTALL_NAMESPACE "kwin/effects/plugins")
0122  * @endcode
0123  *
0124  * @subsection creating-json-metadata Effect's .json file for embedded metadata
0125  * The format follows the one of the @see KPluginMetaData class.
0126  *
0127  * Example cooleffect.json file:
0128  * @code
0129 {
0130     "KPlugin": {
0131         "Authors": [
0132             {
0133                 "Email": "my@email.here",
0134                 "Name": "My Name"
0135             }
0136         ],
0137         "Category": "Misc",
0138         "Description": "The coolest effect you've ever seen",
0139         "Icon": "preferences-system-windows-effect-cooleffect",
0140         "Name": "Cool Effect"
0141     }
0142 }
0143  * @endcode
0144  *
0145  * @section accessing Accessing windows and workspace
0146  * Effects can gain access to the properties of windows and workspace via
0147  *  EffectWindow and EffectsHandler classes.
0148  *
0149  * There is one global EffectsHandler object which you can access using the
0150  *  @ref effects pointer.
0151  * For each window, there is an EffectWindow object which can be used to read
0152  *  window properties such as position and also to change them.
0153  *
0154  * For more information about this, see the documentation of the corresponding
0155  *  classes.
0156  *
0157  * @{
0158  */
0159 
0160 #define KWIN_EFFECT_API_MAKE_VERSION(major, minor) ((major) << 8 | (minor))
0161 #define KWIN_EFFECT_API_VERSION_MAJOR 0
0162 #define KWIN_EFFECT_API_VERSION_MINOR 236
0163 #define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
0164     KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR)
0165 
0166 /**
0167  * EffectWindow::setData() and EffectWindow::data() global roles.
0168  * All values between 0 and 999 are reserved for global roles.
0169  */
0170 enum DataRole {
0171     // Grab roles are used to force all other animations to ignore the window.
0172     // The value of the data is set to the Effect's `this` value.
0173     WindowAddedGrabRole = 1,
0174     WindowClosedGrabRole,
0175     WindowMinimizedGrabRole,
0176     WindowUnminimizedGrabRole,
0177     WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
0178     WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
0179 };
0180 
0181 /**
0182  * Style types used by @ref EffectFrame.
0183  * @since 4.6
0184  */
0185 enum EffectFrameStyle {
0186     EffectFrameNone, ///< Displays no frame around the contents.
0187     EffectFrameUnstyled, ///< Displays a basic box around the contents.
0188     EffectFrameStyled ///< Displays a Plasma-styled frame around the contents.
0189 };
0190 
0191 /**
0192  * Scale a rect by a scalar.
0193  */
0194 KWINEFFECTS_EXPORT inline QRectF scaledRect(const QRectF &rect, qreal scale)
0195 {
0196     return QRectF{rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale};
0197 }
0198 
0199 /**
0200  * Round a vector to nearest integer.
0201  */
0202 KWINEFFECTS_EXPORT inline QVector2D roundVector(const QVector2D &input)
0203 {
0204     return QVector2D(std::round(input.x()), std::round(input.y()));
0205 }
0206 
0207 /**
0208  * Convert a QPointF to a QPoint by flooring instead of rounding.
0209  *
0210  * By default, QPointF::toPoint() rounds which can cause problems in certain
0211  * cases.
0212  */
0213 KWINEFFECTS_EXPORT inline QPoint flooredPoint(const QPointF &point)
0214 {
0215     return QPoint(std::floor(point.x()), std::floor(point.y()));
0216 }
0217 
0218 /**
0219  * @short Base class for all KWin effects
0220  *
0221  * This is the base class for all effects. By reimplementing virtual methods
0222  *  of this class, you can customize how the windows are painted.
0223  *
0224  * The virtual methods are used for painting and need to be implemented for
0225  * custom painting.
0226  *
0227  * In order to react to state changes (e.g. a window gets closed) the effect
0228  * should provide slots for the signals emitted by the EffectsHandler.
0229  *
0230  * @section Chaining
0231  * Most methods of this class are called in chain style. This means that when
0232  *  effects A and B area active then first e.g. A::paintWindow() is called and
0233  *  then from within that method B::paintWindow() is called (although
0234  *  indirectly). To achieve this, you need to make sure to call corresponding
0235  *  method in EffectsHandler class from each such method (using @ref effects
0236  *  pointer):
0237  * @code
0238  *  void MyEffect::postPaintScreen()
0239  *  {
0240  *      // Do your own processing here
0241  *      ...
0242  *      // Call corresponding EffectsHandler method
0243  *      effects->postPaintScreen();
0244  *  }
0245  * @endcode
0246  *
0247  * @section Effectsptr Effects pointer
0248  * @ref effects pointer points to the global EffectsHandler object that you can
0249  *  use to interact with the windows.
0250  *
0251  * @section painting Painting stages
0252  * Painting of windows is done in three stages:
0253  * @li First, the prepaint pass.<br>
0254  *  Here you can specify how the windows will be painted, e.g. that they will
0255  *  be translucent and transformed.
0256  * @li Second, the paint pass.<br>
0257  *  Here the actual painting takes place. You can change attributes such as
0258  *  opacity of windows as well as apply transformations to them. You can also
0259  *  paint something onto the screen yourself.
0260  * @li Finally, the postpaint pass.<br>
0261  *  Here you can mark windows, part of windows or even the entire screen for
0262  *  repainting to create animations.
0263  *
0264  * For each stage there are *Screen() and *Window() methods. The window method
0265  *  is called for every window while the screen method is usually called just
0266  *  once.
0267  *
0268  * @section OpenGL
0269  * Effects can use OpenGL if EffectsHandler::isOpenGLCompositing() returns @c true.
0270  * The OpenGL context may not always be current when code inside the effect is
0271  * executed. The framework ensures that the OpenGL context is current when the Effect
0272  * gets created, destroyed or reconfigured and during the painting stages. All virtual
0273  * methods which have the OpenGL context current are documented.
0274  *
0275  * If OpenGL code is going to be executed outside the painting stages, e.g. in reaction
0276  * to a global shortcut, it is the task of the Effect to make the OpenGL context current:
0277  * @code
0278  * effects->makeOpenGLContextCurrent();
0279  * @endcode
0280  *
0281  * There is in general no need to call the matching doneCurrent method.
0282  */
0283 class KWINEFFECTS_EXPORT Effect : public QObject
0284 {
0285     Q_OBJECT
0286 public:
0287     /** Flags controlling how painting is done. */
0288     // TODO: is that ok here?
0289     enum {
0290         /**
0291          * Window (or at least part of it) will be painted opaque.
0292          */
0293         PAINT_WINDOW_OPAQUE = 1 << 0,
0294         /**
0295          * Window (or at least part of it) will be painted translucent.
0296          */
0297         PAINT_WINDOW_TRANSLUCENT = 1 << 1,
0298         /**
0299          * Window will be painted with transformed geometry.
0300          */
0301         PAINT_WINDOW_TRANSFORMED = 1 << 2,
0302         /**
0303          * Paint only a region of the screen (can be optimized, cannot
0304          * be used together with TRANSFORMED flags).
0305          */
0306         PAINT_SCREEN_REGION = 1 << 3,
0307         /**
0308          * The whole screen will be painted with transformed geometry.
0309          * Forces the entire screen to be painted.
0310          */
0311         PAINT_SCREEN_TRANSFORMED = 1 << 4,
0312         /**
0313          * At least one window will be painted with transformed geometry.
0314          * Forces the entire screen to be painted.
0315          */
0316         PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
0317         /**
0318          * Clear whole background as the very first step, without optimizing it
0319          */
0320         PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
0321     };
0322 
0323     enum Feature {
0324         Nothing = 0,
0325         Resize, /**< @deprecated */
0326         GeometryTip, /**< @deprecated */
0327         Outline, /**< @deprecated */
0328         ScreenInversion,
0329         Blur,
0330         Contrast,
0331         HighlightWindows
0332     };
0333 
0334     /**
0335      * Constructs new Effect object.
0336      *
0337      * In OpenGL based compositing, the frameworks ensures that the context is current
0338      * when the Effect is constructed.
0339      */
0340     Effect(QObject *parent = nullptr);
0341     /**
0342      * Destructs the Effect object.
0343      *
0344      * In OpenGL based compositing, the frameworks ensures that the context is current
0345      * when the Effect is destroyed.
0346      */
0347     ~Effect() override;
0348 
0349     /**
0350      * Flags describing which parts of configuration have changed.
0351      */
0352     enum ReconfigureFlag {
0353         ReconfigureAll = 1 << 0 /// Everything needs to be reconfigured.
0354     };
0355     Q_DECLARE_FLAGS(ReconfigureFlags, ReconfigureFlag)
0356 
0357     /**
0358      * Called when configuration changes (either the effect's or KWin's global).
0359      *
0360      * In OpenGL based compositing, the frameworks ensures that the context is current
0361      * when the Effect is reconfigured. If this method is called from within the Effect it is
0362      * required to ensure that the context is current if the implementation does OpenGL calls.
0363      */
0364     virtual void reconfigure(ReconfigureFlags flags);
0365 
0366     /**
0367      * Called when another effect requests the proxy for this effect.
0368      */
0369     virtual void *proxy();
0370 
0371     /**
0372      * Called before starting to paint the screen.
0373      * In this method you can:
0374      * @li set whether the windows or the entire screen will be transformed
0375      * @li change the region of the screen that will be painted
0376      * @li do various housekeeping tasks such as initing your effect's variables
0377             for the upcoming paint pass or updating animation's progress
0378      *
0379      * @a presentTime specifies the expected monotonic time when the rendered frame
0380      * will be displayed on the screen.
0381     */
0382     virtual void prePaintScreen(ScreenPrePaintData &data,
0383                                 std::chrono::milliseconds presentTime);
0384     /**
0385      * In this method you can:
0386      * @li paint something on top of the windows (by painting after calling
0387      *      effects->paintScreen())
0388      * @li paint multiple desktops and/or multiple copies of the same desktop
0389      *      by calling effects->paintScreen() multiple times
0390      *
0391      * In OpenGL based compositing, the frameworks ensures that the context is current
0392      * when this method is invoked.
0393      */
0394     virtual void paintScreen(int mask, const QRegion &region, ScreenPaintData &data);
0395     /**
0396      * Called after all the painting has been finished.
0397      * In this method you can:
0398      * @li schedule next repaint in case of animations
0399      * You shouldn't paint anything here.
0400      *
0401      * In OpenGL based compositing, the frameworks ensures that the context is current
0402      * when this method is invoked.
0403      */
0404     virtual void postPaintScreen();
0405 
0406     /**
0407      * Called for every window before the actual paint pass
0408      * In this method you can:
0409      * @li enable or disable painting of the window (e.g. enable paiting of minimized window)
0410      * @li set window to be painted with translucency
0411      * @li set window to be transformed
0412      * @li request the window to be divided into multiple parts
0413      *
0414      * In OpenGL based compositing, the frameworks ensures that the context is current
0415      * when this method is invoked.
0416      *
0417      * @a presentTime specifies the expected monotonic time when the rendered frame
0418      * will be displayed on the screen.
0419      */
0420     virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
0421                                 std::chrono::milliseconds presentTime);
0422     /**
0423      * This is the main method for painting windows.
0424      * In this method you can:
0425      * @li do various transformations
0426      * @li change opacity of the window
0427      * @li change brightness and/or saturation, if it's supported
0428      *
0429      * In OpenGL based compositing, the frameworks ensures that the context is current
0430      * when this method is invoked.
0431      */
0432     virtual void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data);
0433     /**
0434      * Called for every window after all painting has been finished.
0435      * In this method you can:
0436      * @li schedule next repaint for individual window(s) in case of animations
0437      * You shouldn't paint anything here.
0438      *
0439      * In OpenGL based compositing, the frameworks ensures that the context is current
0440      * when this method is invoked.
0441      */
0442     virtual void postPaintWindow(EffectWindow *w);
0443 
0444     /**
0445      * Called on Transparent resizes.
0446      * return true if your effect substitutes questioned feature
0447      */
0448     virtual bool provides(Feature);
0449 
0450     /**
0451      * Performs the @p feature with the @p arguments.
0452      *
0453      * This allows to have specific protocols between KWin core and an Effect.
0454      *
0455      * The method is supposed to return @c true if it performed the features,
0456      * @c false otherwise.
0457      *
0458      * The default implementation returns @c false.
0459      * @since 5.8
0460      */
0461     virtual bool perform(Feature feature, const QVariantList &arguments);
0462 
0463     /**
0464      * Can be called to draw multiple copies (e.g. thumbnails) of a window.
0465      * You can change window's opacity/brightness/etc here, but you can't
0466      *  do any transformations.
0467      *
0468      * In OpenGL based compositing, the frameworks ensures that the context is current
0469      * when this method is invoked.
0470      */
0471     virtual void drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
0472 
0473     virtual void windowInputMouseEvent(QEvent *e);
0474     virtual void grabbedKeyboardEvent(QKeyEvent *e);
0475 
0476     /**
0477      * Overwrite this method to indicate whether your effect will be doing something in
0478      * the next frame to be rendered. If the method returns @c false the effect will be
0479      * excluded from the chained methods in the next rendered frame.
0480      *
0481      * This method is called always directly before the paint loop begins. So it is totally
0482      * fine to e.g. react on a window event, issue a repaint to trigger an animation and
0483      * change a flag to indicate that this method returns @c true.
0484      *
0485      * As the method is called each frame, you should not perform complex calculations.
0486      * Best use just a boolean flag.
0487      *
0488      * The default implementation of this method returns @c true.
0489      * @since 4.8
0490      */
0491     virtual bool isActive() const;
0492 
0493     /**
0494      * Reimplement this method to provide online debugging.
0495      * This could be as trivial as printing specific detail information about the effect state
0496      * but could also be used to move the effect in and out of a special debug modes, clear bogus
0497      * data, etc.
0498      * Notice that the functions is const by intent! Whenever you alter the state of the object
0499      * due to random user input, you should do so with greatest care, hence const_cast<> your
0500      * object - signalling "let me alone, i know what i'm doing"
0501      * @param parameter A freeform string user input for your effect to interpret.
0502      * @since 4.11
0503      */
0504     virtual QString debug(const QString &parameter) const;
0505 
0506     /**
0507      * Reimplement this method to indicate where in the Effect chain the Effect should be placed.
0508      *
0509      * A low number indicates early chain position, thus before other Effects got called, a high
0510      * number indicates a late position. The returned number should be in the interval [0, 100].
0511      * The default value is 0.
0512      *
0513      * In KWin4 this information was provided in the Effect's desktop file as property
0514      * X-KDE-Ordering. In the case of Scripted Effects this property is still used.
0515      *
0516      * @since 5.0
0517      */
0518     virtual int requestedEffectChainPosition() const;
0519 
0520     /**
0521      * A touch point was pressed.
0522      *
0523      * If the effect wants to exclusively use the touch event it should return @c true.
0524      * If @c false is returned the touch event is passed to further effects.
0525      *
0526      * In general an Effect should only return @c true if it is the exclusive effect getting
0527      * input events. E.g. has grabbed mouse events.
0528      *
0529      * Default implementation returns @c false.
0530      *
0531      * @param id The unique id of the touch point
0532      * @param pos The position of the touch point in global coordinates
0533      * @param time Timestamp
0534      *
0535      * @see touchMotion
0536      * @see touchUp
0537      * @since 5.8
0538      */
0539     virtual bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0540     /**
0541      * A touch point moved.
0542      *
0543      * If the effect wants to exclusively use the touch event it should return @c true.
0544      * If @c false is returned the touch event is passed to further effects.
0545      *
0546      * In general an Effect should only return @c true if it is the exclusive effect getting
0547      * input events. E.g. has grabbed mouse events.
0548      *
0549      * Default implementation returns @c false.
0550      *
0551      * @param id The unique id of the touch point
0552      * @param pos The position of the touch point in global coordinates
0553      * @param time Timestamp
0554      *
0555      * @see touchDown
0556      * @see touchUp
0557      * @since 5.8
0558      */
0559     virtual bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0560     /**
0561      * A touch point was released.
0562      *
0563      * If the effect wants to exclusively use the touch event it should return @c true.
0564      * If @c false is returned the touch event is passed to further effects.
0565      *
0566      * In general an Effect should only return @c true if it is the exclusive effect getting
0567      * input events. E.g. has grabbed mouse events.
0568      *
0569      * Default implementation returns @c false.
0570      *
0571      * @param id The unique id of the touch point
0572      * @param time Timestamp
0573      *
0574      * @see touchDown
0575      * @see touchMotion
0576      * @since 5.8
0577      */
0578     virtual bool touchUp(qint32 id, std::chrono::microseconds time);
0579 
0580     /**
0581      * There has been an event from a drawing tablet tool
0582      *
0583      * i.e. a pen and the likes.
0584      *
0585      * @param event the event information
0586      * @see QTabletEvent
0587      *
0588      * @since 5.25
0589      */
0590     virtual bool tabletToolEvent(QTabletEvent *event);
0591 
0592     /**
0593      * There has been an event from a button on a drawing tablet tool
0594      *
0595      * @param button which button
0596      * @param pressed true if pressed, false when released
0597      * @param tabletToolId the identifier of the tool id
0598      *
0599      * @since 5.25
0600      */
0601     virtual bool tabletToolButtonEvent(uint button, bool pressed, quint64 tabletToolId);
0602 
0603     /**
0604      * There has been an event from a button on a drawing tablet pad
0605      *
0606      * @param button which button
0607      * @param pressed true if pressed, false when released
0608      * @param tabletPadId the identifier of the tool id
0609      *
0610      * @since 5.25
0611      */
0612     virtual bool tabletPadButtonEvent(uint button, bool pressed, void *tabletPadId);
0613 
0614     /**
0615      * There has been an event from a input strip on a drawing tablet pad
0616      *
0617      * @param number which strip
0618      * @param position the value within the strip that was selected
0619      * @param isFinger if it was activated with a finger
0620      * @param tabletPadId the identifier of the tool id
0621      *
0622      * @since 5.25
0623      */
0624     virtual bool tabletPadStripEvent(int number, int position, bool isFinger, void *tabletPadId);
0625 
0626     /**
0627      * There has been an event from a input ring on a drawing tablet pad
0628      *
0629      * @param number which ring
0630      * @param position the value within the ring that was selected
0631      * @param isFinger if it was activated with a finger
0632      * @param tabletPadId the identifier of the tool id
0633      *
0634      * @since 5.25
0635      */
0636     virtual bool tabletPadRingEvent(int number, int position, bool isFinger, void *tabletPadId);
0637 
0638     static QPoint cursorPos();
0639 
0640     /**
0641      * Read animation time from the configuration and possibly adjust using animationTimeFactor().
0642      * The configuration value in the effect should also have special value 'default' (set using
0643      * QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted
0644      * using the global animation speed, otherwise the exact time configured is returned.
0645      * @param cfg configuration group to read value from
0646      * @param key configuration key to read value from
0647      * @param defaultTime default animation time in milliseconds
0648      */
0649     // return type is intentionally double so that one can divide using it without losing data
0650     static double animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime);
0651     /**
0652      * @overload Use this variant if the animation time is hardcoded and not configurable
0653      * in the effect itself.
0654      */
0655     static double animationTime(int defaultTime);
0656     /**
0657      * @overload Use this variant if animation time is provided through a KConfigXT generated class
0658      * having a property called "duration".
0659      */
0660     template<typename T>
0661     int animationTime(int defaultDuration);
0662     /**
0663      * Linearly interpolates between @p x and @p y.
0664      *
0665      * Returns @p x when @p a = 0; returns @p y when @p a = 1.
0666      */
0667     static double interpolate(double x, double y, double a)
0668     {
0669         return x * (1 - a) + y * a;
0670     }
0671     /** Helper to set WindowPaintData and QRegion to necessary transformations so that
0672      * a following drawWindow() would put the window at the requested geometry (useful for thumbnails)
0673      */
0674     static void setPositionTransformations(WindowPaintData &data, QRect &region, EffectWindow *w,
0675                                            const QRect &r, Qt::AspectRatioMode aspect);
0676 
0677     /**
0678      * overwrite this method to return false if your effect does not need to be drawn over opaque fullscreen windows
0679      */
0680     virtual bool blocksDirectScanout() const;
0681 
0682 public Q_SLOTS:
0683     virtual bool borderActivated(ElectricBorder border);
0684 
0685 protected:
0686     xcb_connection_t *xcbConnection() const;
0687     xcb_window_t x11RootWindow() const;
0688 
0689     /**
0690      * An implementing class can call this with it's kconfig compiled singleton class.
0691      * This method will perform the instance on the class.
0692      * @since 5.9
0693      */
0694     template<typename T>
0695     void initConfig();
0696 };
0697 
0698 /**
0699  * Prefer the KWIN_EFFECT_FACTORY macros.
0700  */
0701 class KWINEFFECTS_EXPORT EffectPluginFactory : public KPluginFactory
0702 {
0703     Q_OBJECT
0704 public:
0705     EffectPluginFactory();
0706     ~EffectPluginFactory() override;
0707     /**
0708      * Returns whether the Effect is supported.
0709      *
0710      * An Effect can implement this method to determine at runtime whether the Effect is supported.
0711      *
0712      * If the current compositing backend is not supported it should return @c false.
0713      *
0714      * This method is optional, by default @c true is returned.
0715      */
0716     virtual bool isSupported() const;
0717     /**
0718      * Returns whether the Effect should get enabled by default.
0719      *
0720      * This function provides a way for an effect to override the default at runtime,
0721      * e.g. based on the capabilities of the hardware.
0722      *
0723      * This method is optional; the effect doesn't have to provide it.
0724      *
0725      * Note that this function is only called if the supported() function returns true,
0726      * and if X-KDE-PluginInfo-EnabledByDefault is set to true in the .desktop file.
0727      *
0728      * This method is optional, by default @c true is returned.
0729      */
0730     virtual bool enabledByDefault() const;
0731     /**
0732      * This method returns the created Effect.
0733      */
0734     virtual KWin::Effect *createEffect() const = 0;
0735 };
0736 
0737 #define EffectPluginFactory_iid "org.kde.kwin.EffectPluginFactory" KWIN_PLUGIN_VERSION_STRING
0738 #define KWIN_PLUGIN_FACTORY_NAME KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME
0739 
0740 /**
0741  * Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.
0742  *
0743  * If the Effect to be created does not need the isSupported or enabledByDefault methods prefer
0744  * the simplified KWIN_EFFECT_FACTORY, KWIN_EFFECT_FACTORY_SUPPORTED or KWIN_EFFECT_FACTORY_ENABLED
0745  * macros which create an EffectPluginFactory with a useable default value.
0746  *
0747  * This API is not providing binary compatibility and thus the effect plugin must be compiled against
0748  * the same kwineffects library version as KWin.
0749  *
0750  * @param factoryName The name to be used for the EffectPluginFactory
0751  * @param className The class name of the Effect sub class which is to be created by the factory
0752  * @param jsonFile Name of the json file to be compiled into the plugin as metadata
0753  * @param supported Source code to go into the isSupported() method, must return a boolean
0754  * @param enabled Source code to go into the enabledByDefault() method, must return a boolean
0755  */
0756 #define KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, supported, enabled) \
0757     class KWIN_PLUGIN_FACTORY_NAME : public KWin::EffectPluginFactory                  \
0758     {                                                                                  \
0759         Q_OBJECT                                                                       \
0760         Q_PLUGIN_METADATA(IID EffectPluginFactory_iid FILE jsonFile)                   \
0761         Q_INTERFACES(KPluginFactory)                                                   \
0762     public:                                                                            \
0763         explicit KWIN_PLUGIN_FACTORY_NAME()                                            \
0764         {                                                                              \
0765         }                                                                              \
0766         ~KWIN_PLUGIN_FACTORY_NAME()                                                    \
0767         {                                                                              \
0768         }                                                                              \
0769         bool isSupported() const override                                              \
0770         {                                                                              \
0771             supported                                                                  \
0772         }                                                                              \
0773         bool enabledByDefault() const override{                                        \
0774             enabled} KWin::Effect *createEffect() const override                       \
0775         {                                                                              \
0776             return new className();                                                    \
0777         }                                                                              \
0778     };
0779 
0780 #define KWIN_EFFECT_FACTORY_ENABLED(className, jsonFile, enabled) \
0781     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, return true;, enabled)
0782 
0783 #define KWIN_EFFECT_FACTORY_SUPPORTED(className, jsonFile, supported) \
0784     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, supported, return true;)
0785 
0786 #define KWIN_EFFECT_FACTORY(className, jsonFile) \
0787     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, return true;, return true;)
0788 
0789 /**
0790  * @short Manager class that handles all the effects.
0791  *
0792  * This class creates Effect objects and calls it's appropriate methods.
0793  *
0794  * Effect objects can call methods of this class to interact with the
0795  *  workspace, e.g. to activate or move a specific window, change current
0796  *  desktop or create a special input window to receive mouse and keyboard
0797  *  events.
0798  */
0799 class KWINEFFECTS_EXPORT EffectsHandler : public QObject
0800 {
0801     Q_OBJECT
0802     Q_PROPERTY(int currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
0803     Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
0804     Q_PROPERTY(KWin::EffectWindow *activeWindow READ activeWindow WRITE activateWindow NOTIFY windowActivated)
0805     Q_PROPERTY(QSize desktopGridSize READ desktopGridSize NOTIFY desktopGridSizeChanged)
0806     Q_PROPERTY(int desktopGridWidth READ desktopGridWidth NOTIFY desktopGridWidthChanged)
0807     Q_PROPERTY(int desktopGridHeight READ desktopGridHeight NOTIFY desktopGridHeightChanged)
0808     Q_PROPERTY(int workspaceWidth READ workspaceWidth)
0809     Q_PROPERTY(int workspaceHeight READ workspaceHeight)
0810     /**
0811      * The number of desktops currently used. Minimum number of desktops is 1, maximum 20.
0812      */
0813     Q_PROPERTY(int desktops READ numberOfDesktops WRITE setNumberOfDesktops NOTIFY numberDesktopsChanged)
0814     Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
0815     Q_PROPERTY(KWin::EffectScreen *activeScreen READ activeScreen)
0816     /**
0817      * Factor by which animation speed in the effect should be modified (multiplied).
0818      * If configurable in the effect itself, the option should have also 'default'
0819      * animation speed. The actual value should be determined using animationTime().
0820      * Note: The factor can be also 0, so make sure your code can cope with 0ms time
0821      * if used manually.
0822      */
0823     Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
0824     Q_PROPERTY(KWin::EffectWindowList stackingOrder READ stackingOrder)
0825     /**
0826      * Whether window decorations use the alpha channel.
0827      */
0828     Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
0829     Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
0830     Q_PROPERTY(QPoint cursorPos READ cursorPos)
0831     Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
0832     Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
0833     Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
0834 
0835     /**
0836      * The status of the session i.e if the user is logging out
0837      * @since 5.18
0838      */
0839     Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
0840 
0841     Q_PROPERTY(KWin::EffectWindow *inputPanel READ inputPanel NOTIFY inputPanelChanged)
0842 
0843     friend class Effect;
0844 
0845 public:
0846     using TouchBorderCallback = std::function<void(ElectricBorder border, const QPointF &, EffectScreen *screen)>;
0847 
0848     explicit EffectsHandler(CompositingType type);
0849     ~EffectsHandler() override;
0850     // for use by effects
0851     virtual void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) = 0;
0852     virtual void paintScreen(int mask, const QRegion &region, ScreenPaintData &data) = 0;
0853     virtual void postPaintScreen() = 0;
0854     virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) = 0;
0855     virtual void paintWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) = 0;
0856     virtual void postPaintWindow(EffectWindow *w) = 0;
0857     virtual void drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) = 0;
0858     virtual void renderWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) = 0;
0859     virtual QVariant kwinOption(KWinOption kwopt) = 0;
0860     /**
0861      * Sets the cursor while the mouse is intercepted.
0862      * @see startMouseInterception
0863      * @since 4.11
0864      */
0865     virtual void defineCursor(Qt::CursorShape shape) = 0;
0866     virtual QPoint cursorPos() const = 0;
0867     virtual bool grabKeyboard(Effect *effect) = 0;
0868     virtual void ungrabKeyboard() = 0;
0869     /**
0870      * Ensures that all mouse events are sent to the @p effect.
0871      * No window will get the mouse events. Only fullscreen effects providing a custom user interface should
0872      * be using this method. The input events are delivered to Effect::windowInputMouseEvent.
0873      *
0874      * @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
0875      * all other windows, but no grab is performed.
0876      *
0877      * @param effect The effect
0878      * @param shape Sets the cursor to be used while the mouse is intercepted
0879      * @see stopMouseInterception
0880      * @see Effect::windowInputMouseEvent
0881      * @since 4.11
0882      */
0883     virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape) = 0;
0884     /**
0885      * Releases the hold mouse interception for @p effect
0886      * @see startMouseInterception
0887      * @since 4.11
0888      */
0889     virtual void stopMouseInterception(Effect *effect) = 0;
0890 
0891     /**
0892      * @brief Registers a global pointer shortcut with the provided @p action.
0893      *
0894      * @param modifiers The keyboard modifiers which need to be holded
0895      * @param pointerButtons The pointer buttons which need to be pressed
0896      * @param action The action which gets triggered when the shortcut matches
0897      */
0898     virtual void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) = 0;
0899     /**
0900      * @brief Registers a global axis shortcut with the provided @p action.
0901      *
0902      * @param modifiers The keyboard modifiers which need to be holded
0903      * @param axis The direction in which the axis needs to be moved
0904      * @param action The action which gets triggered when the shortcut matches
0905      */
0906     virtual void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) = 0;
0907 
0908     /**
0909      * @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
0910      *
0911      * @param direction The direction for the swipe
0912      * @param action The action which gets triggered when the gesture triggers
0913      * @since 5.10
0914      */
0915     virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) = 0;
0916 
0917     virtual void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) = 0;
0918 
0919     virtual void registerRealtimeTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) = 0;
0920 
0921     virtual void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action) = 0;
0922 
0923     /**
0924      * @brief Registers a global touchscreen swipe gesture shortcut with the provided @p action.
0925      *
0926      * @param direction The direction for the swipe
0927      * @param action The action which gets triggered when the gesture triggers
0928      * @since 5.25
0929      */
0930     virtual void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback) = 0;
0931 
0932     /**
0933      * Retrieve the proxy class for an effect if it has one. Will return NULL if
0934      * the effect isn't loaded or doesn't have a proxy class.
0935      */
0936     virtual void *getProxy(QString name) = 0;
0937 
0938     // Mouse polling
0939     virtual void startMousePolling() = 0;
0940     virtual void stopMousePolling() = 0;
0941 
0942     virtual void reserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
0943     virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
0944 
0945     /**
0946      * Registers the given @p action for the given @p border to be activated through
0947      * a touch swipe gesture.
0948      *
0949      * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
0950      * signal gets invoked.
0951      *
0952      * To unregister the touch screen action either delete the @p action or
0953      * invoke unregisterTouchBorder.
0954      *
0955      * @see unregisterTouchBorder
0956      * @since 5.10
0957      */
0958     virtual void registerTouchBorder(ElectricBorder border, QAction *action) = 0;
0959 
0960     /**
0961      * Registers the given @p action for the given @p border to be activated through
0962      * a touch swipe gesture.
0963      *
0964      * If the @p border gets triggered through a touch swipe gesture the QAction::triggered
0965      * signal gets invoked.
0966      *
0967      * progressCallback will be dinamically called each time the touch position is updated
0968      * to show the effect "partially" activated
0969      *
0970      * To unregister the touch screen action either delete the @p action or
0971      * invoke unregisterTouchBorder.
0972      *
0973      * @see unregisterTouchBorder
0974      * @since 5.25
0975      */
0976     virtual void registerRealtimeTouchBorder(ElectricBorder border, QAction *action, TouchBorderCallback progressCallback) = 0;
0977 
0978     /**
0979      * Unregisters the given @p action for the given touch @p border.
0980      *
0981      * @see registerTouchBorder
0982      * @since 5.10
0983      */
0984     virtual void unregisterTouchBorder(ElectricBorder border, QAction *action) = 0;
0985 
0986     // functions that allow controlling windows/desktop
0987     virtual void activateWindow(KWin::EffectWindow *c) = 0;
0988     virtual KWin::EffectWindow *activeWindow() const = 0;
0989     Q_SCRIPTABLE virtual void moveWindow(KWin::EffectWindow *w, const QPoint &pos, bool snap = false, double snapAdjust = 1.0) = 0;
0990 
0991     /**
0992      * Moves the window to the specific desktop
0993      * Setting desktop to NET::OnAllDesktops will set the window on all desktops
0994      */
0995     Q_SCRIPTABLE virtual void windowToDesktop(KWin::EffectWindow *w, int desktop) = 0;
0996 
0997     /**
0998      * Moves a window to the given desktops
0999      * On X11, the window will end up on the last window in the list
1000      * Setting this to an empty list will set the window on all desktops
1001      *
1002      * @arg desktopIds a list of desktops the window should be placed on. NET::OnAllDesktops is not a valid desktop X11Id
1003      */
1004     Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow *w, const QVector<uint> &desktopIds) = 0;
1005 
1006     Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow *w, EffectScreen *screen) = 0;
1007     virtual void setShowingDesktop(bool showing) = 0;
1008 
1009     // Activities
1010     /**
1011      * @returns The ID of the current activity.
1012      */
1013     virtual QString currentActivity() const = 0;
1014     // Desktops
1015     /**
1016      * @returns The ID of the current desktop.
1017      */
1018     virtual int currentDesktop() const = 0;
1019     /**
1020      * @returns Total number of desktops currently in existence.
1021      */
1022     virtual int numberOfDesktops() const = 0;
1023     /**
1024      * Set the current desktop to @a desktop.
1025      */
1026     virtual void setCurrentDesktop(int desktop) = 0;
1027     /**
1028      * Sets the total number of desktops to @a desktops.
1029      */
1030     virtual void setNumberOfDesktops(int desktops) = 0;
1031     /**
1032      * @returns The size of desktop layout in grid units.
1033      */
1034     virtual QSize desktopGridSize() const = 0;
1035     /**
1036      * @returns The width of desktop layout in grid units.
1037      */
1038     virtual int desktopGridWidth() const = 0;
1039     /**
1040      * @returns The height of desktop layout in grid units.
1041      */
1042     virtual int desktopGridHeight() const = 0;
1043     /**
1044      * @returns The width of desktop layout in pixels.
1045      */
1046     virtual int workspaceWidth() const = 0;
1047     /**
1048      * @returns The height of desktop layout in pixels.
1049      */
1050     virtual int workspaceHeight() const = 0;
1051     /**
1052      * @returns The ID of the desktop at the point @a coords or 0 if no desktop exists at that
1053      * point. @a coords is to be in grid units.
1054      */
1055     virtual int desktopAtCoords(QPoint coords) const = 0;
1056     /**
1057      * @returns The coords of desktop @a id in grid units.
1058      */
1059     virtual QPoint desktopGridCoords(int id) const = 0;
1060     /**
1061      * @returns The coords of the top-left corner of desktop @a id in pixels.
1062      */
1063     virtual QPoint desktopCoords(int id) const = 0;
1064     /**
1065      * @returns The ID of the desktop above desktop @a id. Wraps around to the bottom of
1066      * the layout if @a wrap is set. If @a id is not set use the current one.
1067      */
1068     Q_SCRIPTABLE virtual int desktopAbove(int desktop = 0, bool wrap = true) const = 0;
1069     /**
1070      * @returns The ID of the desktop to the right of desktop @a id. Wraps around to the
1071      * left of the layout if @a wrap is set. If @a id is not set use the current one.
1072      */
1073     Q_SCRIPTABLE virtual int desktopToRight(int desktop = 0, bool wrap = true) const = 0;
1074     /**
1075      * @returns The ID of the desktop below desktop @a id. Wraps around to the top of the
1076      * layout if @a wrap is set. If @a id is not set use the current one.
1077      */
1078     Q_SCRIPTABLE virtual int desktopBelow(int desktop = 0, bool wrap = true) const = 0;
1079     /**
1080      * @returns The ID of the desktop to the left of desktop @a id. Wraps around to the
1081      * right of the layout if @a wrap is set. If @a id is not set use the current one.
1082      */
1083     Q_SCRIPTABLE virtual int desktopToLeft(int desktop = 0, bool wrap = true) const = 0;
1084     Q_SCRIPTABLE virtual QString desktopName(int desktop) const = 0;
1085     virtual bool optionRollOverDesktops() const = 0;
1086 
1087     virtual EffectScreen *activeScreen() const = 0; // Xinerama
1088     virtual QRectF clientArea(clientAreaOption, const EffectScreen *screen, int desktop) const = 0;
1089     virtual QRectF clientArea(clientAreaOption, const EffectWindow *c) const = 0;
1090     virtual QRectF clientArea(clientAreaOption, const QPoint &p, int desktop) const = 0;
1091 
1092     /**
1093      * The bounding size of all screens combined. Overlapping areas
1094      * are not counted multiple times.
1095      *
1096      * @see virtualScreenGeometry()
1097      * @see virtualScreenSizeChanged()
1098      * @since 5.0
1099      */
1100     virtual QSize virtualScreenSize() const = 0;
1101     /**
1102      * The bounding geometry of all outputs combined. Always starts at (0,0) and has
1103      * virtualScreenSize as it's size.
1104      *
1105      * @see virtualScreenSize()
1106      * @see virtualScreenGeometryChanged()
1107      * @since 5.0
1108      */
1109     virtual QRect virtualScreenGeometry() const = 0;
1110     /**
1111      * Factor by which animation speed in the effect should be modified (multiplied).
1112      * If configurable in the effect itself, the option should have also 'default'
1113      * animation speed. The actual value should be determined using animationTime().
1114      * Note: The factor can be also 0, so make sure your code can cope with 0ms time
1115      * if used manually.
1116      */
1117     virtual double animationTimeFactor() const = 0;
1118 
1119     Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(WId id) const = 0;
1120     Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(KWaylandServer::SurfaceInterface *surf) const = 0;
1121     /**
1122      * Finds the EffectWindow for the internal window @p w.
1123      * If there is no such window @c null is returned.
1124      *
1125      * On Wayland this returns the internal window. On X11 it returns an Unamanged with the
1126      * window id matching that of the provided window @p w.
1127      *
1128      * @since 5.16
1129      */
1130     Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
1131     /**
1132      * Finds the EffectWindow for the Window with KWin internal @p id.
1133      * If there is no such window @c null is returned.
1134      *
1135      * @since 5.16
1136      */
1137     Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(const QUuid &id) const = 0;
1138     virtual EffectWindowList stackingOrder() const = 0;
1139     // window will be temporarily painted as if being at the top of the stack
1140     Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow *w, bool set) = 0;
1141 
1142     virtual void setTabBoxWindow(EffectWindow *) = 0;
1143     virtual void setTabBoxDesktop(int) = 0;
1144     virtual EffectWindowList currentTabBoxWindowList() const = 0;
1145     virtual void refTabBox() = 0;
1146     virtual void unrefTabBox() = 0;
1147     virtual void closeTabBox() = 0;
1148     virtual QList<int> currentTabBoxDesktopList() const = 0;
1149     virtual int currentTabBoxDesktop() const = 0;
1150     virtual EffectWindow *currentTabBoxWindow() const = 0;
1151 
1152     virtual void setActiveFullScreenEffect(Effect *e) = 0;
1153     virtual Effect *activeFullScreenEffect() const = 0;
1154 
1155     /**
1156      * Schedules the entire workspace to be repainted next time.
1157      * If you call it during painting (including prepaint) then it does not
1158      *  affect the current painting.
1159      */
1160     Q_SCRIPTABLE virtual void addRepaintFull() = 0;
1161     Q_SCRIPTABLE virtual void addRepaint(const QRectF &r) = 0;
1162     Q_SCRIPTABLE virtual void addRepaint(const QRect &r) = 0;
1163     Q_SCRIPTABLE virtual void addRepaint(const QRegion &r) = 0;
1164     Q_SCRIPTABLE virtual void addRepaint(int x, int y, int w, int h) = 0;
1165 
1166     CompositingType compositingType() const;
1167     /**
1168      * @brief Whether the Compositor is OpenGL based (either GL 1 or 2).
1169      *
1170      * @return bool @c true in case of OpenGL based Compositor, @c false otherwise
1171      */
1172     bool isOpenGLCompositing() const;
1173     /**
1174      * @brief Provides access to the QPainter which is rendering to the back buffer.
1175      *
1176      * Only relevant for CompositingType QPainterCompositing. For all other compositing types
1177      * @c null is returned.
1178      *
1179      * @return QPainter* The Scene's QPainter or @c null.
1180      */
1181     virtual QPainter *scenePainter() = 0;
1182     virtual void reconfigure() = 0;
1183 
1184     virtual QByteArray readRootProperty(long atom, long type, int format) const = 0;
1185     /**
1186      * @brief Announces support for the feature with the given name. If no other Effect
1187      * has announced support for this feature yet, an X11 property will be installed on
1188      * the root window.
1189      *
1190      * The Effect will be notified for events through the signal propertyNotify().
1191      *
1192      * To remove the support again use removeSupportProperty. When an Effect is
1193      * destroyed it is automatically taken care of removing the support. It is not
1194      * required to call removeSupportProperty in the Effect's cleanup handling.
1195      *
1196      * @param propertyName The name of the property to announce support for
1197      * @param effect The effect which announces support
1198      * @return xcb_atom_t The created X11 atom
1199      * @see removeSupportProperty
1200      * @since 4.11
1201      */
1202     virtual xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
1203     /**
1204      * @brief Removes support for the feature with the given name. If there is no other Effect left
1205      * which has announced support for the given property, the property will be removed from the
1206      * root window.
1207      *
1208      * In case the Effect had not registered support, calling this function does not change anything.
1209      *
1210      * @param propertyName The name of the property to remove support for
1211      * @param effect The effect which had registered the property.
1212      * @see announceSupportProperty
1213      * @since 4.11
1214      */
1215     virtual void removeSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
1216 
1217     /**
1218      * Returns @a true if the active window decoration has shadow API hooks.
1219      */
1220     virtual bool hasDecorationShadows() const = 0;
1221 
1222     /**
1223      * Returns @a true if the window decorations use the alpha channel, and @a false otherwise.
1224      * @since 4.5
1225      */
1226     virtual bool decorationsHaveAlpha() const = 0;
1227 
1228     /**
1229      * Creates a new frame object. If the frame does not have a static size
1230      * then it will be located at @a position with @a alignment. A
1231      * non-static frame will automatically adjust its size to fit the contents.
1232      * @returns A new @ref EffectFrame. It is the responsibility of the caller to delete the
1233      * EffectFrame.
1234      * @since 4.6
1235      */
1236     virtual std::unique_ptr<EffectFrame> effectFrame(EffectFrameStyle style, bool staticSize = true,
1237                                                      const QPoint &position = QPoint(-1, -1),
1238                                                      Qt::Alignment alignment = Qt::AlignCenter) const = 0;
1239 
1240     /**
1241      * Allows an effect to trigger a reload of itself.
1242      * This can be used by an effect which needs to be reloaded when screen geometry changes.
1243      * It is possible that the effect cannot be loaded again as it's supported method does no longer
1244      * hold.
1245      * @param effect The effect to reload
1246      * @since 4.8
1247      */
1248     virtual void reloadEffect(Effect *effect) = 0;
1249 
1250     /**
1251      * Whether the screen is currently considered as locked.
1252      * Note for technical reasons this is not always possible to detect. The screen will only
1253      * be considered as locked if the screen locking process implements the
1254      * org.freedesktop.ScreenSaver interface.
1255      *
1256      * @returns @c true if the screen is currently locked, @c false otherwise
1257      * @see screenLockingChanged
1258      * @since 4.11
1259      */
1260     virtual bool isScreenLocked() const = 0;
1261 
1262     /**
1263      * @brief Makes the OpenGL compositing context current.
1264      *
1265      * If the compositing backend is not using OpenGL, this method returns @c false.
1266      *
1267      * @return bool @c true if the context became current, @c false otherwise.
1268      */
1269     virtual bool makeOpenGLContextCurrent() = 0;
1270     /**
1271      * @brief Makes a null OpenGL context current resulting in no context
1272      * being current.
1273      *
1274      * If the compositing backend is not OpenGL based, this method is a noop.
1275      *
1276      * There is normally no reason for an Effect to call this method.
1277      */
1278     virtual void doneOpenGLContextCurrent() = 0;
1279 
1280     virtual xcb_connection_t *xcbConnection() const = 0;
1281     virtual xcb_window_t x11RootWindow() const = 0;
1282 
1283     /**
1284      * Interface to the Wayland display: this is relevant only
1285      * on Wayland, on X11 it will be nullptr
1286      * @since 5.5
1287      */
1288     virtual KWaylandServer::Display *waylandDisplay() const = 0;
1289 
1290     /**
1291      * Whether animations are supported by the Scene.
1292      * If this method returns @c false Effects are supposed to not
1293      * animate transitions.
1294      *
1295      * @returns Whether the Scene can drive animations
1296      * @since 5.8
1297      */
1298     virtual bool animationsSupported() const = 0;
1299 
1300     /**
1301      * The current cursor image of the Platform.
1302      * @see cursorPos
1303      * @since 5.9
1304      */
1305     virtual PlatformCursorImage cursorImage() const = 0;
1306 
1307     /**
1308      * The cursor image should be hidden.
1309      * @see showCursor
1310      * @since 5.9
1311      */
1312     virtual void hideCursor() = 0;
1313 
1314     /**
1315      * The cursor image should be shown again after having been hidden.
1316      * @see hideCursor
1317      * @since 5.9
1318      */
1319     virtual void showCursor() = 0;
1320 
1321     /**
1322      * @returns Whether or not the cursor is currently hidden
1323      */
1324     virtual bool isCursorHidden() const = 0;
1325 
1326     /**
1327      * Starts an interactive window selection process.
1328      *
1329      * Once the user selected a window the @p callback is invoked with the selected EffectWindow as
1330      * argument. In case the user cancels the interactive window selection or selecting a window is currently
1331      * not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument.
1332      *
1333      * During the interactive window selection the cursor is turned into a crosshair cursor.
1334      *
1335      * @param callback The function to invoke once the interactive window selection ends
1336      * @since 5.9
1337      */
1338     virtual void startInteractiveWindowSelection(std::function<void(KWin::EffectWindow *)> callback) = 0;
1339 
1340     /**
1341      * Starts an interactive position selection process.
1342      *
1343      * Once the user selected a position on the screen the @p callback is invoked with
1344      * the selected point as argument. In case the user cancels the interactive position selection
1345      * or selecting a position is currently not possible (e.g. screen locked) the @p callback
1346      * is invoked with a point at @c -1 as x and y argument.
1347      *
1348      * During the interactive window selection the cursor is turned into a crosshair cursor.
1349      *
1350      * @param callback The function to invoke once the interactive position selection ends
1351      * @since 5.9
1352      */
1353     virtual void startInteractivePositionSelection(std::function<void(const QPoint &)> callback) = 0;
1354 
1355     /**
1356      * Shows an on-screen-message. To hide it again use hideOnScreenMessage.
1357      *
1358      * @param message The message to show
1359      * @param iconName The optional themed icon name
1360      * @see hideOnScreenMessage
1361      * @since 5.9
1362      */
1363     virtual void showOnScreenMessage(const QString &message, const QString &iconName = QString()) = 0;
1364 
1365     /**
1366      * Flags for how to hide a shown on-screen-message
1367      * @see hideOnScreenMessage
1368      * @since 5.9
1369      */
1370     enum class OnScreenMessageHideFlag {
1371         /**
1372          * The on-screen-message should skip the close window animation.
1373          * @see EffectWindow::skipsCloseAnimation
1374          */
1375         SkipsCloseAnimation = 1
1376     };
1377     Q_DECLARE_FLAGS(OnScreenMessageHideFlags, OnScreenMessageHideFlag)
1378     /**
1379      * Hides a previously shown on-screen-message again.
1380      * @param flags The flags for how to hide the message
1381      * @see showOnScreenMessage
1382      * @since 5.9
1383      */
1384     virtual void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags()) = 0;
1385 
1386     /*
1387      * @returns The configuration used by the EffectsHandler.
1388      * @since 5.10
1389      */
1390     virtual KSharedConfigPtr config() const = 0;
1391 
1392     /**
1393      * @returns The global input configuration (kcminputrc)
1394      * @since 5.10
1395      */
1396     virtual KSharedConfigPtr inputConfig() const = 0;
1397 
1398     /**
1399      * Returns if activeFullScreenEffect is set
1400      */
1401     virtual bool hasActiveFullScreenEffect() const = 0;
1402 
1403     /**
1404      * Render the supplied OffscreenQuickView onto the scene
1405      * It can be called at any point during the scene rendering
1406      * @since 5.18
1407      */
1408     virtual void renderOffscreenQuickView(OffscreenQuickView *effectQuickView) const = 0;
1409 
1410     /**
1411      * The status of the session i.e if the user is logging out
1412      * @since 5.18
1413      */
1414     virtual SessionState sessionState() const = 0;
1415 
1416     /**
1417      * Returns the list of all the screens connected to the system.
1418      */
1419     virtual QList<EffectScreen *> screens() const = 0;
1420     virtual EffectScreen *screenAt(const QPoint &point) const = 0;
1421     virtual EffectScreen *findScreen(const QString &name) const = 0;
1422     virtual EffectScreen *findScreen(int screenId) const = 0;
1423 
1424     /**
1425      * Renders @p screen in the current render target
1426      */
1427     virtual void renderScreen(EffectScreen *screen) = 0;
1428 
1429     /**
1430      * Returns the rect that's currently being repainted, in the logical pixels.
1431      */
1432     virtual QRect renderTargetRect() const = 0;
1433     /**
1434      * Returns the device pixel ratio of the current render target.
1435      */
1436     virtual qreal renderTargetScale() const = 0;
1437 
1438     /**
1439      * Maps the given @a rect from the global screen cordinates to the render
1440      * target local coordinate system.
1441      */
1442     QRectF mapToRenderTarget(const QRectF &rect) const;
1443     /**
1444      * Maps the given @a region from the global screen coordinates to the render
1445      * target local coordinate system.
1446      */
1447     QRegion mapToRenderTarget(const QRegion &region) const;
1448 
1449     virtual KWin::EffectWindow *inputPanel() const = 0;
1450     virtual bool isInputPanelOverlay() const = 0;
1451 
1452 Q_SIGNALS:
1453     /**
1454      * This signal is emitted whenever a new @a screen is added to the system.
1455      */
1456     void screenAdded(KWin::EffectScreen *screen);
1457     /**
1458      * This signal is emitted whenever a @a screen is removed from the system.
1459      */
1460     void screenRemoved(KWin::EffectScreen *screen);
1461     /**
1462      * Signal emitted when the current desktop changed.
1463      * @param oldDesktop The previously current desktop
1464      * @param newDesktop The new current desktop
1465      * @param with The window which is taken over to the new desktop, can be NULL
1466      * @since 4.9
1467      */
1468     void desktopChanged(int oldDesktop, int newDesktop, KWin::EffectWindow *with);
1469 
1470     /**
1471      * Signal emmitted while desktop is changing for animation.
1472      * @param currentDesktop The current desktop untiotherwise.
1473      * @param offset The current desktop offset.
1474      * offset.x() = .6 means 60% of the way to the desktop to the right.
1475      * Positive Values means Up and Right.
1476      */
1477     void desktopChanging(uint currentDesktop, QPointF offset, KWin::EffectWindow *with);
1478     void desktopChangingCancelled();
1479 
1480     /**
1481      * @since 4.7
1482      * @deprecated
1483      */
1484     void KWIN_DEPRECATED desktopChanged(int oldDesktop, int newDesktop);
1485     /**
1486      * @internal
1487      */
1488     void desktopChangedLegacy(int oldDesktop, int newDesktop);
1489     /**
1490      * Signal emitted when a window moved to another desktop
1491      * NOTICE that this does NOT imply that the desktop has changed
1492      * The @param window which is moved to the new desktop
1493      * @param oldDesktop The previous desktop of the window
1494      * @param newDesktop The new desktop of the window
1495      * @since 4.11.4
1496      */
1497     void desktopPresenceChanged(KWin::EffectWindow *window, int oldDesktop, int newDesktop);
1498     /**
1499      * Emitted when the virtual desktop grid layout changes
1500      * @param size new size
1501      * @since 5.25
1502      */
1503     void desktopGridSizeChanged(const QSize &size);
1504     /**
1505      * Emitted when the virtual desktop grid layout changes
1506      * @param width new width
1507      * @since 5.25
1508      */
1509     void desktopGridWidthChanged(int width);
1510     /**
1511      * Emitted when the virtual desktop grid layout changes
1512      * @param height new height
1513      * @since 5.25
1514      */
1515     void desktopGridHeightChanged(int height);
1516     /**
1517      * Signal emitted when the number of currently existing desktops is changed.
1518      * @param old The previous number of desktops in used.
1519      * @see EffectsHandler::numberOfDesktops.
1520      * @since 4.7
1521      */
1522     void numberDesktopsChanged(uint old);
1523     /**
1524      * Signal emitted when the desktop showing ("dashboard") state changed
1525      * The desktop is risen to the keepAbove layer, you may want to elevate
1526      * windows or such.
1527      * @since 5.3
1528      */
1529     void showingDesktopChanged(bool);
1530     /**
1531      * Signal emitted when a new window has been added to the Workspace.
1532      * @param w The added window
1533      * @since 4.7
1534      */
1535     void windowAdded(KWin::EffectWindow *w);
1536     /**
1537      * Signal emitted when a window is being removed from the Workspace.
1538      * An effect which wants to animate the window closing should connect
1539      * to this signal and reference the window by using
1540      * refWindow
1541      * @param w The window which is being closed
1542      * @since 4.7
1543      */
1544     void windowClosed(KWin::EffectWindow *w);
1545     /**
1546      * Signal emitted when a window get's activated.
1547      * @param w The new active window, or @c NULL if there is no active window.
1548      * @since 4.7
1549      */
1550     void windowActivated(KWin::EffectWindow *w);
1551     /**
1552      * Signal emitted when a window is deleted.
1553      * This means that a closed window is not referenced any more.
1554      * An effect bookkeeping the closed windows should connect to this
1555      * signal to clean up the internal references.
1556      * @param w The window which is going to be deleted.
1557      * @see EffectWindow::refWindow
1558      * @see EffectWindow::unrefWindow
1559      * @see windowClosed
1560      * @since 4.7
1561      */
1562     void windowDeleted(KWin::EffectWindow *w);
1563     /**
1564      * Signal emitted when a user begins a window move or resize operation.
1565      * To figure out whether the user resizes or moves the window use
1566      * isUserMove or isUserResize.
1567      * Whenever the geometry is updated the signal @ref windowStepUserMovedResized
1568      * is emitted with the current geometry.
1569      * The move/resize operation ends with the signal @ref windowFinishUserMovedResized.
1570      * Only one window can be moved/resized by the user at the same time!
1571      * @param w The window which is being moved/resized
1572      * @see windowStepUserMovedResized
1573      * @see windowFinishUserMovedResized
1574      * @see EffectWindow::isUserMove
1575      * @see EffectWindow::isUserResize
1576      * @since 4.7
1577      */
1578     void windowStartUserMovedResized(KWin::EffectWindow *w);
1579     /**
1580      * Signal emitted during a move/resize operation when the user changed the geometry.
1581      * Please note: KWin supports two operation modes. In one mode all changes are applied
1582      * instantly. This means the window's geometry matches the passed in @p geometry. In the
1583      * other mode the geometry is changed after the user ended the move/resize mode.
1584      * The @p geometry differs from the window's geometry. Also the window's pixmap still has
1585      * the same size as before. Depending what the effect wants to do it would be recommended
1586      * to scale/translate the window.
1587      * @param w The window which is being moved/resized
1588      * @param geometry The geometry of the window in the current move/resize step.
1589      * @see windowStartUserMovedResized
1590      * @see windowFinishUserMovedResized
1591      * @see EffectWindow::isUserMove
1592      * @see EffectWindow::isUserResize
1593      * @since 4.7
1594      */
1595     void windowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry);
1596     /**
1597      * Signal emitted when the user finishes move/resize of window @p w.
1598      * @param w The window which has been moved/resized
1599      * @see windowStartUserMovedResized
1600      * @see windowFinishUserMovedResized
1601      * @since 4.7
1602      */
1603     void windowFinishUserMovedResized(KWin::EffectWindow *w);
1604     /**
1605      * Signal emitted when the maximized state of the window @p w changed.
1606      * A window can be in one of four states:
1607      * @li restored: both @p horizontal and @p vertical are @c false
1608      * @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
1609      * @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
1610      * @li completely maximized: both @p horizontal and @p vertical are @c true
1611      * @param w The window whose maximized state changed
1612      * @param horizontal If @c true maximized horizontally
1613      * @param vertical If @c true maximized vertically
1614      * @since 4.7
1615      */
1616     void windowMaximizedStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical);
1617 
1618     /**
1619      * Signal emitted when the maximized state of the window @p w is about to change,
1620      * but before windowMaximizedStateChanged is emitted or any geometry change.
1621      * Useful for OffscreenEffect to grab a window image before any actual change happens
1622      *
1623      * A window can be in one of four states:
1624      * @li restored: both @p horizontal and @p vertical are @c false
1625      * @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
1626      * @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
1627      * @li completely maximized: both @p horizontal and @p vertical are @c true
1628      * @param w The window whose maximized state changed
1629      * @param horizontal If @c true maximized horizontally
1630      * @param vertical If @c true maximized vertically
1631      * @since 5.26
1632      */
1633     void windowMaximizedStateAboutToChange(KWin::EffectWindow *w, bool horizontal, bool vertical);
1634 
1635     /**
1636      * Signal emitted when the geometry or shape of a window changed.
1637      * This is caused if the window changes geometry without user interaction.
1638      * E.g. the decoration is changed. This is in opposite to windowUserMovedResized
1639      * which is caused by direct user interaction.
1640      * @param w The window whose geometry changed
1641      * @param old The previous geometry
1642      * @see windowUserMovedResized
1643      * @since 4.7
1644      */
1645     void windowGeometryShapeChanged(KWin::EffectWindow *w, const QRectF &old);
1646     /**
1647      * This signal is emitted when the frame geometry of a window changed.
1648      * @param window The window whose geometry changed
1649      * @param oldGeometry The previous geometry
1650      * @since 5.19
1651      */
1652     void windowFrameGeometryChanged(KWin::EffectWindow *window, const QRectF &oldGeometry);
1653 
1654     /**
1655      * This signal is emitted when the frame geometry is about to change, the new one is not known yet.
1656      * Useful for OffscreenEffect to grab a window image before any actual change happens.
1657      *
1658      * @param window The window whose geometry is about to change
1659      * @since 5.26
1660      */
1661     void windowFrameGeometryAboutToChange(KWin::EffectWindow *window);
1662 
1663     /**
1664      * Signal emitted when the windows opacity is changed.
1665      * @param w The window whose opacity level is changed.
1666      * @param oldOpacity The previous opacity level
1667      * @param newOpacity The new opacity level
1668      * @since 4.7
1669      */
1670     void windowOpacityChanged(KWin::EffectWindow *w, qreal oldOpacity, qreal newOpacity);
1671     /**
1672      * Signal emitted when a window got minimized.
1673      * @param w The window which was minimized
1674      * @since 4.7
1675      */
1676     void windowMinimized(KWin::EffectWindow *w);
1677     /**
1678      * Signal emitted when a window got unminimized.
1679      * @param w The window which was unminimized
1680      * @since 4.7
1681      */
1682     void windowUnminimized(KWin::EffectWindow *w);
1683     /**
1684      * Signal emitted when a window either becomes modal (ie. blocking for its main client) or looses that state.
1685      * @param w The window which was unminimized
1686      * @since 4.11
1687      */
1688     void windowModalityChanged(KWin::EffectWindow *w);
1689     /**
1690      * Signal emitted when a window either became unresponsive (eg. app froze or crashed)
1691      * or respoonsive
1692      * @param w The window that became (un)responsive
1693      * @param unresponsive Whether the window is responsive or unresponsive
1694      * @since 5.10
1695      */
1696     void windowUnresponsiveChanged(KWin::EffectWindow *w, bool unresponsive);
1697     /**
1698      * Signal emitted when an area of a window is scheduled for repainting.
1699      * Use this signal in an effect if another area needs to be synced as well.
1700      * @param w The window which is scheduled for repainting
1701      * @param r Always empty.
1702      * @since 4.7
1703      */
1704     void windowDamaged(KWin::EffectWindow *w);
1705     /**
1706      * Signal emitted when a tabbox is added.
1707      * An effect who wants to replace the tabbox with itself should use refTabBox.
1708      * @param mode The TabBoxMode.
1709      * @see refTabBox
1710      * @see tabBoxClosed
1711      * @see tabBoxUpdated
1712      * @see tabBoxKeyEvent
1713      * @since 4.7
1714      */
1715     void tabBoxAdded(int mode);
1716     /**
1717      * Signal emitted when the TabBox was closed by KWin core.
1718      * An effect which referenced the TabBox should use unrefTabBox to unref again.
1719      * @see unrefTabBox
1720      * @see tabBoxAdded
1721      * @since 4.7
1722      */
1723     void tabBoxClosed();
1724     /**
1725      * Signal emitted when the selected TabBox window changed or the TabBox List changed.
1726      * An effect should only response to this signal if it referenced the TabBox with refTabBox.
1727      * @see refTabBox
1728      * @see currentTabBoxWindowList
1729      * @see currentTabBoxDesktopList
1730      * @see currentTabBoxWindow
1731      * @see currentTabBoxDesktop
1732      * @since 4.7
1733      */
1734     void tabBoxUpdated();
1735     /**
1736      * Signal emitted when a key event, which is not handled by TabBox directly is, happens while
1737      * TabBox is active. An effect might use the key event to e.g. change the selected window.
1738      * An effect should only response to this signal if it referenced the TabBox with refTabBox.
1739      * @param event The key event not handled by TabBox directly
1740      * @see refTabBox
1741      * @since 4.7
1742      */
1743     void tabBoxKeyEvent(QKeyEvent *event);
1744     void currentTabAboutToChange(KWin::EffectWindow *from, KWin::EffectWindow *to);
1745     void tabAdded(KWin::EffectWindow *from, KWin::EffectWindow *to); // from merged with to
1746     void tabRemoved(KWin::EffectWindow *c, KWin::EffectWindow *group); // c removed from group
1747     /**
1748      * Signal emitted when mouse changed.
1749      * If an effect needs to get updated mouse positions, it needs to first call startMousePolling.
1750      * For a fullscreen effect it is better to use an input window and react on windowInputMouseEvent.
1751      * @param pos The new mouse position
1752      * @param oldpos The previously mouse position
1753      * @param buttons The pressed mouse buttons
1754      * @param oldbuttons The previously pressed mouse buttons
1755      * @param modifiers Pressed keyboard modifiers
1756      * @param oldmodifiers Previously pressed keyboard modifiers.
1757      * @see startMousePolling
1758      * @since 4.7
1759      */
1760     void mouseChanged(const QPoint &pos, const QPoint &oldpos,
1761                       Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
1762                       Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
1763     /**
1764      * Signal emitted when the cursor shape changed.
1765      * You'll likely want to query the current cursor as reaction: xcb_xfixes_get_cursor_image_unchecked
1766      * Connection to this signal is tracked, so if you don't need it anymore, disconnect from it to stop cursor event filtering
1767      */
1768     void cursorShapeChanged();
1769     /**
1770      * Receives events registered for using registerPropertyType.
1771      * Use readProperty() to get the property data.
1772      * Note that the property may be already set on the window, so doing the same
1773      * processing from windowAdded() (e.g. simply calling propertyNotify() from it)
1774      * is usually needed.
1775      * @param w The window whose property changed, is @c null if it is a root window property
1776      * @param atom The property
1777      * @since 4.7
1778      */
1779     void propertyNotify(KWin::EffectWindow *w, long atom);
1780 
1781     /**
1782      * This signal is emitted when the global
1783      * activity is changed
1784      * @param id id of the new current activity
1785      * @since 4.9
1786      */
1787     void currentActivityChanged(const QString &id);
1788     /**
1789      * This signal is emitted when a new activity is added
1790      * @param id id of the new activity
1791      * @since 4.9
1792      */
1793     void activityAdded(const QString &id);
1794     /**
1795      * This signal is emitted when the activity
1796      * is removed
1797      * @param id id of the removed activity
1798      * @since 4.9
1799      */
1800     void activityRemoved(const QString &id);
1801     /**
1802      * This signal is emitted when the screen got locked or unlocked.
1803      * @param locked @c true if the screen is now locked, @c false if it is now unlocked
1804      * @since 4.11
1805      */
1806     void screenLockingChanged(bool locked);
1807 
1808     /**
1809      * This signal is emitted just before the screen locker tries to grab keys and lock the screen
1810      * Effects should release any grabs immediately
1811      * @since 5.17
1812      */
1813     void screenAboutToLock();
1814 
1815     /**
1816      * This signels is emitted when ever the stacking order is change, ie. a window is risen
1817      * or lowered
1818      * @since 4.10
1819      */
1820     void stackingOrderChanged();
1821     /**
1822      * This signal is emitted when the user starts to approach the @p border with the mouse.
1823      * The @p factor describes how far away the mouse is in a relative mean. The values are in
1824      * [0.0, 1.0] with 0.0 being emitted when first entered and on leaving. The value 1.0 means that
1825      * the @p border is reached with the mouse. So the values are well suited for animations.
1826      * The signal is always emitted when the mouse cursor position changes.
1827      * @param border The screen edge which is being approached
1828      * @param factor Value in range [0.0,1.0] to describe how close the mouse is to the border
1829      * @param geometry The geometry of the edge which is being approached
1830      * @since 4.11
1831      */
1832     void screenEdgeApproaching(ElectricBorder border, qreal factor, const QRect &geometry);
1833     /**
1834      * Emitted whenever the virtualScreenSize changes.
1835      * @see virtualScreenSize()
1836      * @since 5.0
1837      */
1838     void virtualScreenSizeChanged();
1839     /**
1840      * Emitted whenever the virtualScreenGeometry changes.
1841      * @see virtualScreenGeometry()
1842      * @since 5.0
1843      */
1844     void virtualScreenGeometryChanged();
1845 
1846     /**
1847      * The window @p w gets shown again. The window was previously
1848      * initially shown with windowAdded and hidden with windowHidden.
1849      *
1850      * @see windowHidden
1851      * @see windowAdded
1852      * @since 5.8
1853      */
1854     void windowShown(KWin::EffectWindow *w);
1855 
1856     /**
1857      * The window @p w got hidden but not yet closed.
1858      * This can happen when a window is still being used and is supposed to be shown again
1859      * with windowShown. On X11 an example is autohiding panels. On Wayland every
1860      * window first goes through the window hidden state and might get shown again, or might
1861      * get closed the normal way.
1862      *
1863      * @see windowShown
1864      * @see windowClosed
1865      * @since 5.8
1866      */
1867     void windowHidden(KWin::EffectWindow *w);
1868 
1869     /**
1870      * This signal gets emitted when the data on EffectWindow @p w for @p role changed.
1871      *
1872      * An Effect can connect to this signal to read the new value and react on it.
1873      * E.g. an Effect which does not operate on windows grabbed by another Effect wants
1874      * to cancel the already scheduled animation if another Effect adds a grab.
1875      *
1876      * @param w The EffectWindow for which the data changed
1877      * @param role The data role which changed
1878      * @see EffectWindow::setData
1879      * @see EffectWindow::data
1880      * @since 5.8.4
1881      */
1882     void windowDataChanged(KWin::EffectWindow *w, int role);
1883 
1884     /**
1885      * The xcb connection changed, either a new xcbConnection got created or the existing one
1886      * got destroyed.
1887      * Effects can use this to refetch the properties they want to set.
1888      *
1889      * When the xcbConnection changes also the x11RootWindow becomes invalid.
1890      * @see xcbConnection
1891      * @see x11RootWindow
1892      * @since 5.11
1893      */
1894     void xcbConnectionChanged();
1895 
1896     /**
1897      * This signal is emitted when active fullscreen effect changed.
1898      *
1899      * @see activeFullScreenEffect
1900      * @see setActiveFullScreenEffect
1901      * @since 5.14
1902      */
1903     void activeFullScreenEffectChanged();
1904 
1905     /**
1906      * This signal is emitted when active fullscreen effect changed to being
1907      * set or unset
1908      *
1909      * @see activeFullScreenEffect
1910      * @see setActiveFullScreenEffect
1911      * @since 5.15
1912      */
1913     void hasActiveFullScreenEffectChanged();
1914 
1915     /**
1916      * This signal is emitted when the keep above state of @p w was changed.
1917      *
1918      * @param w The window whose the keep above state was changed.
1919      * @since 5.15
1920      */
1921     void windowKeepAboveChanged(KWin::EffectWindow *w);
1922 
1923     /**
1924      * This signal is emitted when the keep below state of @p was changed.
1925      *
1926      * @param w The window whose the keep below state was changed.
1927      * @since 5.15
1928      */
1929     void windowKeepBelowChanged(KWin::EffectWindow *w);
1930 
1931     /**
1932      * This signal is emitted when the full screen state of @p w was changed.
1933      *
1934      * @param w The window whose the full screen state was changed.
1935      * @since 5.15
1936      */
1937     void windowFullScreenChanged(KWin::EffectWindow *w);
1938 
1939     /**
1940      * This signal is emitted when the session state was changed
1941      * @since 5.18
1942      */
1943     void sessionStateChanged();
1944 
1945     /**
1946      * This signal is emitted when decoration of @p was changed.
1947      *
1948      * @param w The window for which decoration changed
1949      * @since 5.25
1950      */
1951     void windowDecorationChanged(KWin::EffectWindow *window);
1952 
1953     /**
1954      * This signal is emitted when the visible geometry of a window changed.
1955      */
1956     void windowExpandedGeometryChanged(KWin::EffectWindow *window);
1957 
1958     void startupAdded(const QString &id, const QIcon &icon);
1959     void startupChanged(const QString &id, const QIcon &icon);
1960     void startupRemoved(const QString &id);
1961 
1962     void inputPanelChanged();
1963 
1964 protected:
1965     QVector<EffectPair> loaded_effects;
1966     // QHash< QString, EffectFactory* > effect_factories;
1967     CompositingType compositing_type;
1968 };
1969 
1970 /**
1971  * The EffectScreen class represents a screen used by/for Effect classes.
1972  */
1973 class KWINEFFECTS_EXPORT EffectScreen : public QObject
1974 {
1975     Q_OBJECT
1976     Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
1977     Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
1978     Q_PROPERTY(QString name READ name CONSTANT)
1979     Q_PROPERTY(QString manufacturer READ manufacturer CONSTANT)
1980     Q_PROPERTY(QString model READ model CONSTANT)
1981     Q_PROPERTY(QString serialNumber READ serialNumber CONSTANT)
1982     Q_PROPERTY(qreal refreshRate READ refreshRate CONSTANT)
1983 
1984 public:
1985     explicit EffectScreen(QObject *parent = nullptr);
1986 
1987     /**
1988      * Returns the name of the screen, e.g. "DP-1".
1989      */
1990     virtual QString name() const = 0;
1991 
1992     /**
1993      * Returns the screen's ratio between physical pixels and device-independent pixels.
1994      */
1995     virtual qreal devicePixelRatio() const = 0;
1996 
1997     /**
1998      * Returns the screen's geometry in the device-independent pixels.
1999      */
2000     virtual QRect geometry() const = 0;
2001 
2002     Q_INVOKABLE QPointF mapToGlobal(const QPointF &pos) const;
2003     Q_INVOKABLE QPointF mapFromGlobal(const QPointF &pos) const;
2004 
2005     /**
2006      * Returns the screen's refresh rate in milli-hertz.
2007      */
2008     virtual int refreshRate() const = 0;
2009 
2010     enum class Transform {
2011         Normal,
2012         Rotated90,
2013         Rotated180,
2014         Rotated270,
2015         Flipped,
2016         Flipped90,
2017         Flipped180,
2018         Flipped270
2019     };
2020     Q_ENUM(Transform)
2021     virtual Transform transform() const = 0;
2022 
2023     virtual QString manufacturer() const = 0;
2024     virtual QString model() const = 0;
2025     virtual QString serialNumber() const = 0;
2026 
2027 Q_SIGNALS:
2028     /**
2029      * Notifies that the display will be dimmed in @p time ms.
2030      */
2031     void aboutToTurnOff(std::chrono::milliseconds time);
2032 
2033     /**
2034      * Notifies that the output has been turned on and the wake can be decorated.
2035      */
2036     void wakeUp();
2037 
2038     /**
2039      * This signal is emitted when the geometry of this screen changes.
2040      */
2041     void geometryChanged();
2042 
2043     /**
2044      * This signal is emitted when the device pixel ratio of this screen changes.
2045      */
2046     void devicePixelRatioChanged();
2047 
2048     /**
2049      * Notifies that the output is about to change configuration based on a
2050      * user interaction.
2051      *
2052      * Be it because it gets a transformation or moved around.
2053      */
2054     void aboutToChange();
2055 
2056     /**
2057      * Notifies that the output changed based on a user interaction.
2058      *
2059      * Be it because it gets a transformation or moved around.
2060      */
2061     void changed();
2062 };
2063 
2064 class EffectWindowVisibleRef;
2065 /**
2066  * @short Representation of a window used by/for Effect classes.
2067  *
2068  * The purpose is to hide internal data and also to serve as a single
2069  *  representation for the case when Client/Unmanaged becomes Deleted.
2070  */
2071 class KWINEFFECTS_EXPORT EffectWindow : public QObject
2072 {
2073     Q_OBJECT
2074     Q_PROPERTY(QRectF geometry READ geometry)
2075     Q_PROPERTY(QRectF expandedGeometry READ expandedGeometry)
2076     Q_PROPERTY(qreal height READ height)
2077     Q_PROPERTY(qreal opacity READ opacity)
2078     Q_PROPERTY(QPointF pos READ pos)
2079     Q_PROPERTY(KWin::EffectScreen *screen READ screen)
2080     Q_PROPERTY(QSizeF size READ size)
2081     Q_PROPERTY(qreal width READ width)
2082     Q_PROPERTY(qreal x READ x)
2083     Q_PROPERTY(qreal y READ y)
2084     Q_PROPERTY(int desktop READ desktop)
2085     Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops)
2086     Q_PROPERTY(bool onCurrentDesktop READ isOnCurrentDesktop)
2087     Q_PROPERTY(QRectF rect READ rect)
2088     Q_PROPERTY(QString windowClass READ windowClass)
2089     Q_PROPERTY(QString windowRole READ windowRole)
2090     /**
2091      * Returns whether the window is a desktop background window (the one with wallpaper).
2092      * See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2093      */
2094     Q_PROPERTY(bool desktopWindow READ isDesktop)
2095     /**
2096      * Returns whether the window is a dock (i.e. a panel).
2097      * See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2098      */
2099     Q_PROPERTY(bool dock READ isDock)
2100     /**
2101      * Returns whether the window is a standalone (detached) toolbar window.
2102      * See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2103      */
2104     Q_PROPERTY(bool toolbar READ isToolbar)
2105     /**
2106      * Returns whether the window is a torn-off menu.
2107      * See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2108      */
2109     Q_PROPERTY(bool menu READ isMenu)
2110     /**
2111      * Returns whether the window is a "normal" window, i.e. an application or any other window
2112      * for which none of the specialized window types fit.
2113      * See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2114      */
2115     Q_PROPERTY(bool normalWindow READ isNormalWindow)
2116     /**
2117      * Returns whether the window is a dialog window.
2118      * See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2119      */
2120     Q_PROPERTY(bool dialog READ isDialog)
2121     /**
2122      * Returns whether the window is a splashscreen. Note that many (especially older) applications
2123      * do not support marking their splash windows with this type.
2124      * See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2125      */
2126     Q_PROPERTY(bool splash READ isSplash)
2127     /**
2128      * Returns whether the window is a utility window, such as a tool window.
2129      * See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2130      */
2131     Q_PROPERTY(bool utility READ isUtility)
2132     /**
2133      * Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
2134      * from the applications menubar).
2135      * See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2136      */
2137     Q_PROPERTY(bool dropdownMenu READ isDropdownMenu)
2138     /**
2139      * Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
2140      * See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2141      */
2142     Q_PROPERTY(bool popupMenu READ isPopupMenu)
2143     /**
2144      * Returns whether the window is a tooltip.
2145      * See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2146      */
2147     Q_PROPERTY(bool tooltip READ isTooltip)
2148     /**
2149      * Returns whether the window is a window with a notification.
2150      * See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2151      */
2152     Q_PROPERTY(bool notification READ isNotification)
2153     /**
2154      * Returns whether the window is a window with a critical notification.
2155      * using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
2156      */
2157     Q_PROPERTY(bool criticalNotification READ isCriticalNotification)
2158     /**
2159      * Returns whether the window is an on screen display window
2160      * using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY
2161      */
2162     Q_PROPERTY(bool onScreenDisplay READ isOnScreenDisplay)
2163     /**
2164      * Returns whether the window is a combobox popup.
2165      * See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2166      */
2167     Q_PROPERTY(bool comboBox READ isComboBox)
2168     /**
2169      * Returns whether the window is a Drag&Drop icon.
2170      * See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2171      */
2172     Q_PROPERTY(bool dndIcon READ isDNDIcon)
2173     /**
2174      * Returns the NETWM window type
2175      * See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2176      */
2177     Q_PROPERTY(int windowType READ windowType)
2178     /**
2179      * Whether this EffectWindow is managed by KWin (it has control over its placement and other
2180      * aspects, as opposed to override-redirect windows that are entirely handled by the application).
2181      */
2182     Q_PROPERTY(bool managed READ isManaged)
2183     /**
2184      * Whether this EffectWindow represents an already deleted window and only kept for the compositor for animations.
2185      */
2186     Q_PROPERTY(bool deleted READ isDeleted)
2187     /**
2188      * The Caption of the window. Read from WM_NAME property together with a suffix for hostname and shortcut.
2189      */
2190     Q_PROPERTY(QString caption READ caption)
2191     /**
2192      * Whether the window is set to be kept above other windows.
2193      */
2194     Q_PROPERTY(bool keepAbove READ keepAbove)
2195     /**
2196      * Whether the window is set to be kept below other windows.
2197      */
2198     Q_PROPERTY(bool keepBelow READ keepBelow)
2199     /**
2200      * Whether the window is minimized.
2201      */
2202     Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized)
2203     /**
2204      * Whether the window represents a modal window.
2205      */
2206     Q_PROPERTY(bool modal READ isModal)
2207     /**
2208      * Whether the window is moveable. Even if it is not moveable, it might be possible to move
2209      * it to another screen.
2210      * @see moveableAcrossScreens
2211      */
2212     Q_PROPERTY(bool moveable READ isMovable)
2213     /**
2214      * Whether the window can be moved to another screen.
2215      * @see moveable
2216      */
2217     Q_PROPERTY(bool moveableAcrossScreens READ isMovableAcrossScreens)
2218     /**
2219      * By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
2220      * MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
2221      */
2222     Q_PROPERTY(QSizeF basicUnit READ basicUnit)
2223     /**
2224      * Whether the window is currently being moved by the user.
2225      */
2226     Q_PROPERTY(bool move READ isUserMove)
2227     /**
2228      * Whether the window is currently being resized by the user.
2229      */
2230     Q_PROPERTY(bool resize READ isUserResize)
2231     /**
2232      * The optional geometry representing the minimized Client in e.g a taskbar.
2233      * See _NET_WM_ICON_GEOMETRY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2234      */
2235     Q_PROPERTY(QRectF iconGeometry READ iconGeometry)
2236     /**
2237      * Returns whether the window is any of special windows types (desktop, dock, splash, ...),
2238      * i.e. window types that usually don't have a window frame and the user does not use window
2239      * management (moving, raising,...) on them.
2240      */
2241     Q_PROPERTY(bool specialWindow READ isSpecialWindow)
2242     Q_PROPERTY(QIcon icon READ icon)
2243     /**
2244      * Whether the window should be excluded from window switching effects.
2245      */
2246     Q_PROPERTY(bool skipSwitcher READ isSkipSwitcher)
2247     /**
2248      * Geometry of the actual window contents inside the whole (including decorations) window.
2249      */
2250     Q_PROPERTY(QRectF contentsRect READ contentsRect)
2251     /**
2252      * Geometry of the transparent rect in the decoration.
2253      * May be different from contentsRect if the decoration is extended into the client area.
2254      */
2255     Q_PROPERTY(QRectF decorationInnerRect READ decorationInnerRect)
2256     Q_PROPERTY(bool hasDecoration READ hasDecoration)
2257     Q_PROPERTY(QStringList activities READ activities)
2258     Q_PROPERTY(bool onCurrentActivity READ isOnCurrentActivity)
2259     Q_PROPERTY(bool onAllActivities READ isOnAllActivities)
2260     /**
2261      * Whether the decoration currently uses an alpha channel.
2262      * @since 4.10
2263      */
2264     Q_PROPERTY(bool decorationHasAlpha READ decorationHasAlpha)
2265     /**
2266      * Whether the window is currently visible to the user, that is:
2267      * <ul>
2268      * <li>Not minimized</li>
2269      * <li>On current desktop</li>
2270      * <li>On current activity</li>
2271      * </ul>
2272      * @since 4.11
2273      */
2274     Q_PROPERTY(bool visible READ isVisible)
2275     /**
2276      * Whether the window does not want to be animated on window close.
2277      * In case this property is @c true it is not useful to start an animation on window close.
2278      * The window will not be visible, but the animation hooks are executed.
2279      * @since 5.0
2280      */
2281     Q_PROPERTY(bool skipsCloseAnimation READ skipsCloseAnimation)
2282 
2283     /**
2284      * Whether the window is fullscreen.
2285      * @since 5.6
2286      */
2287     Q_PROPERTY(bool fullScreen READ isFullScreen)
2288 
2289     /**
2290      * Whether this client is unresponsive.
2291      *
2292      * When an application failed to react on a ping request in time, it is
2293      * considered unresponsive. This usually indicates that the application froze or crashed.
2294      *
2295      * @since 5.10
2296      */
2297     Q_PROPERTY(bool unresponsive READ isUnresponsive)
2298 
2299     /**
2300      * Whether this is a Wayland client.
2301      * @since 5.15
2302      */
2303     Q_PROPERTY(bool waylandClient READ isWaylandClient CONSTANT)
2304 
2305     /**
2306      * Whether this is an X11 client.
2307      * @since 5.15
2308      */
2309     Q_PROPERTY(bool x11Client READ isX11Client CONSTANT)
2310 
2311     /**
2312      * Whether the window is a popup.
2313      *
2314      * A popup is a window that can be used to implement tooltips, combo box popups,
2315      * popup menus and other similar user interface concepts.
2316      *
2317      * @since 5.15
2318      */
2319     Q_PROPERTY(bool popupWindow READ isPopupWindow CONSTANT)
2320 
2321     /**
2322      * KWin internal window. Specific to Wayland platform.
2323      *
2324      * If the EffectWindow does not reference an internal window, this property is @c null.
2325      * @since 5.16
2326      */
2327     Q_PROPERTY(QWindow *internalWindow READ internalWindow CONSTANT)
2328 
2329     /**
2330      * Whether this EffectWindow represents the outline.
2331      *
2332      * When compositing is turned on, the outline is an actual window.
2333      *
2334      * @since 5.16
2335      */
2336     Q_PROPERTY(bool outline READ isOutline CONSTANT)
2337 
2338     /**
2339      * The PID of the application this window belongs to.
2340      *
2341      * @since 5.18
2342      */
2343     Q_PROPERTY(pid_t pid READ pid CONSTANT)
2344 
2345     /**
2346      * Whether this EffectWindow represents the screenlocker greeter.
2347      *
2348      * @since 5.22
2349      */
2350     Q_PROPERTY(bool lockScreen READ isLockScreen CONSTANT)
2351 
2352 public:
2353     /**  Flags explaining why painting should be disabled  */
2354     enum {
2355         /**  Window will not be painted  */
2356         PAINT_DISABLED = 1 << 0,
2357         /**  Window will not be painted because it is deleted  */
2358         PAINT_DISABLED_BY_DELETE = 1 << 1,
2359         /**  Window will not be painted because of which desktop it's on  */
2360         PAINT_DISABLED_BY_DESKTOP = 1 << 2,
2361         /**  Window will not be painted because it is minimized  */
2362         PAINT_DISABLED_BY_MINIMIZE = 1 << 3,
2363         /**  Deprecated, tab groups have been removed: Window will not be painted because it is not the active window in a client group */
2364         PAINT_DISABLED_BY_TAB_GROUP = 1 << 4,
2365         /**  Window will not be painted because it's not on the current activity  */
2366         PAINT_DISABLED_BY_ACTIVITY = 1 << 5
2367     };
2368 
2369     explicit EffectWindow();
2370     ~EffectWindow() override;
2371 
2372     Q_SCRIPTABLE virtual void addRepaint(const QRect &r) = 0;
2373     Q_SCRIPTABLE void addRepaint(int x, int y, int w, int h);
2374     Q_SCRIPTABLE virtual void addRepaintFull() = 0;
2375     Q_SCRIPTABLE virtual void addLayerRepaint(const QRect &r) = 0;
2376     Q_SCRIPTABLE void addLayerRepaint(int x, int y, int w, int h);
2377 
2378     virtual void refWindow() = 0;
2379     virtual void unrefWindow() = 0;
2380 
2381     virtual bool isDeleted() const = 0;
2382 
2383     virtual bool isMinimized() const = 0;
2384     virtual double opacity() const = 0;
2385 
2386     bool isOnCurrentActivity() const;
2387     Q_SCRIPTABLE bool isOnActivity(const QString &id) const;
2388     bool isOnAllActivities() const;
2389     virtual QStringList activities() const = 0;
2390 
2391     Q_SCRIPTABLE bool isOnDesktop(int d) const;
2392     bool isOnCurrentDesktop() const;
2393     bool isOnAllDesktops() const;
2394     /**
2395      * The desktop this window is in. This makes sense only on X11
2396      * where desktops are mutually exclusive, on Wayland it's the last
2397      * desktop the window has been added to.
2398      * use desktops() instead.
2399      * @see desktops()
2400      * @deprecated
2401      */
2402 #ifndef KWIN_NO_DEPRECATED
2403     virtual int KWIN_DEPRECATED desktop() const = 0; // prefer isOnXXX()
2404 #endif
2405     /**
2406      * All the desktops by number that the window is in. On X11 this list will always have
2407      * a length of 1, on Wayland can be any subset.
2408      * If the list is empty it means the window is on all desktops
2409      */
2410     virtual QVector<uint> desktops() const = 0;
2411 
2412     virtual qreal x() const = 0;
2413     virtual qreal y() const = 0;
2414     virtual qreal width() const = 0;
2415     virtual qreal height() const = 0;
2416     /**
2417      * By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
2418      * MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
2419      */
2420     virtual QSizeF basicUnit() const = 0;
2421     /**
2422      * @deprecated Use frameGeometry() instead.
2423      */
2424     virtual QRectF KWIN_DEPRECATED geometry() const = 0;
2425     /**
2426      * Returns the geometry of the window excluding server-side and client-side
2427      * drop-shadows.
2428      *
2429      * @since 5.18
2430      */
2431     virtual QRectF frameGeometry() const = 0;
2432     /**
2433      * Returns the geometry of the pixmap or buffer attached to this window.
2434      *
2435      * For X11 clients, this method returns server-side geometry of the Window.
2436      *
2437      * For Wayland clients, this method returns rectangle that the main surface
2438      * occupies on the screen, in global screen coordinates.
2439      *
2440      * @since 5.18
2441      */
2442     virtual QRectF bufferGeometry() const = 0;
2443     virtual QRectF clientGeometry() const = 0;
2444     /**
2445      * Geometry of the window including decoration and potentially shadows.
2446      * May be different from geometry() if the window has a shadow.
2447      * @since 4.9
2448      */
2449     virtual QRectF expandedGeometry() const = 0;
2450     virtual EffectScreen *screen() const = 0;
2451     virtual QPointF pos() const = 0;
2452     virtual QSizeF size() const = 0;
2453     virtual QRectF rect() const = 0;
2454     virtual bool isMovable() const = 0;
2455     virtual bool isMovableAcrossScreens() const = 0;
2456     virtual bool isUserMove() const = 0;
2457     virtual bool isUserResize() const = 0;
2458     virtual QRectF iconGeometry() const = 0;
2459 
2460     /**
2461      * Geometry of the actual window contents inside the whole (including decorations) window.
2462      */
2463     virtual QRectF contentsRect() const = 0;
2464     /**
2465      * Geometry of the transparent rect in the decoration.
2466      * May be different from contentsRect() if the decoration is extended into the client area.
2467      * @since 4.5
2468      */
2469     virtual QRectF decorationInnerRect() const = 0;
2470     bool hasDecoration() const;
2471     virtual bool decorationHasAlpha() const = 0;
2472     /**
2473      * Returns the decoration
2474      * @since 5.25
2475      */
2476     virtual KDecoration2::Decoration *decoration() const = 0;
2477     virtual QByteArray readProperty(long atom, long type, int format) const = 0;
2478     virtual void deleteProperty(long atom) const = 0;
2479 
2480     virtual QString caption() const = 0;
2481     virtual QIcon icon() const = 0;
2482     virtual QString windowClass() const = 0;
2483     virtual QString windowRole() const = 0;
2484     virtual const EffectWindowGroup *group() const = 0;
2485 
2486     /**
2487      * Returns whether the window is a desktop background window (the one with wallpaper).
2488      * See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2489      */
2490     virtual bool isDesktop() const = 0;
2491     /**
2492      * Returns whether the window is a dock (i.e. a panel).
2493      * See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2494      */
2495     virtual bool isDock() const = 0;
2496     /**
2497      * Returns whether the window is a standalone (detached) toolbar window.
2498      * See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2499      */
2500     virtual bool isToolbar() const = 0;
2501     /**
2502      * Returns whether the window is a torn-off menu.
2503      * See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2504      */
2505     virtual bool isMenu() const = 0;
2506     /**
2507      * Returns whether the window is a "normal" window, i.e. an application or any other window
2508      * for which none of the specialized window types fit.
2509      * See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2510      */
2511     virtual bool isNormalWindow() const = 0; // normal as in 'NET::Normal or NET::Unknown non-transient'
2512     /**
2513      * Returns whether the window is any of special windows types (desktop, dock, splash, ...),
2514      * i.e. window types that usually don't have a window frame and the user does not use window
2515      * management (moving, raising,...) on them.
2516      */
2517     virtual bool isSpecialWindow() const = 0;
2518     /**
2519      * Returns whether the window is a dialog window.
2520      * See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2521      */
2522     virtual bool isDialog() const = 0;
2523     /**
2524      * Returns whether the window is a splashscreen. Note that many (especially older) applications
2525      * do not support marking their splash windows with this type.
2526      * See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2527      */
2528     virtual bool isSplash() const = 0;
2529     /**
2530      * Returns whether the window is a utility window, such as a tool window.
2531      * See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2532      */
2533     virtual bool isUtility() const = 0;
2534     /**
2535      * Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
2536      * from the applications menubar).
2537      * See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2538      */
2539     virtual bool isDropdownMenu() const = 0;
2540     /**
2541      * Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
2542      * See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2543      */
2544     virtual bool isPopupMenu() const = 0; // a context popup, not dropdown, not torn-off
2545     /**
2546      * Returns whether the window is a tooltip.
2547      * See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2548      */
2549     virtual bool isTooltip() const = 0;
2550     /**
2551      * Returns whether the window is a window with a notification.
2552      * See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2553      */
2554     virtual bool isNotification() const = 0;
2555     /**
2556      * Returns whether the window is a window with a critical notification.
2557      * using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
2558      */
2559     virtual bool isCriticalNotification() const = 0;
2560     /**
2561      * Returns whether the window is a window used for applet popups.
2562      */
2563     virtual bool isAppletPopup() const = 0;
2564     /**
2565      * Returns whether the window is an on screen display window
2566      * using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY
2567      */
2568     virtual bool isOnScreenDisplay() const = 0;
2569     /**
2570      * Returns whether the window is a combobox popup.
2571      * See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2572      */
2573     virtual bool isComboBox() const = 0;
2574     /**
2575      * Returns whether the window is a Drag&Drop icon.
2576      * See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2577      */
2578     virtual bool isDNDIcon() const = 0;
2579     /**
2580      * Returns the NETWM window type
2581      * See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
2582      */
2583     virtual NET::WindowType windowType() const = 0;
2584     /**
2585      * Returns whether the window is managed by KWin (it has control over its placement and other
2586      * aspects, as opposed to override-redirect windows that are entirely handled by the application).
2587      */
2588     virtual bool isManaged() const = 0; // whether it's managed or override-redirect
2589     /**
2590      * Returns whether or not the window can accept keyboard focus.
2591      */
2592     virtual bool acceptsFocus() const = 0;
2593     /**
2594      * Returns whether or not the window is kept above all other windows.
2595      */
2596     virtual bool keepAbove() const = 0;
2597     /**
2598      * Returns whether the window is kept below all other windows.
2599      */
2600     virtual bool keepBelow() const = 0;
2601 
2602     virtual bool isModal() const = 0;
2603     Q_SCRIPTABLE virtual KWin::EffectWindow *findModal() = 0;
2604     Q_SCRIPTABLE virtual KWin::EffectWindow *transientFor() = 0;
2605     Q_SCRIPTABLE virtual KWin::EffectWindowList mainWindows() const = 0;
2606 
2607     /**
2608      * Returns whether the window should be excluded from window switching effects.
2609      * @since 4.5
2610      */
2611     virtual bool isSkipSwitcher() const = 0;
2612 
2613     void setMinimized(bool minimize);
2614     virtual void minimize() = 0;
2615     virtual void unminimize() = 0;
2616     Q_SCRIPTABLE virtual void closeWindow() = 0;
2617 
2618     /// deprecated
2619     virtual bool isCurrentTab() const = 0;
2620 
2621     /**
2622      * @since 4.11
2623      */
2624     bool isVisible() const;
2625 
2626     /**
2627      * @since 5.0
2628      */
2629     virtual bool skipsCloseAnimation() const = 0;
2630 
2631     /**
2632      * @since 5.5
2633      */
2634     virtual KWaylandServer::SurfaceInterface *surface() const = 0;
2635 
2636     /**
2637      * @since 5.6
2638      */
2639     virtual bool isFullScreen() const = 0;
2640 
2641     /**
2642      * @since 5.10
2643      */
2644     virtual bool isUnresponsive() const = 0;
2645 
2646     /**
2647      * @since 5.15
2648      */
2649     virtual bool isWaylandClient() const = 0;
2650 
2651     /**
2652      * @since 5.15
2653      */
2654     virtual bool isX11Client() const = 0;
2655 
2656     /**
2657      * @since 5.15
2658      */
2659     virtual bool isPopupWindow() const = 0;
2660 
2661     /**
2662      * @since 5.16
2663      */
2664     virtual QWindow *internalWindow() const = 0;
2665 
2666     /**
2667      * @since 5.16
2668      */
2669     virtual bool isOutline() const = 0;
2670 
2671     /**
2672      * @since 5.22
2673      */
2674     virtual bool isLockScreen() const = 0;
2675 
2676     /**
2677      * @since 5.18
2678      */
2679     virtual pid_t pid() const = 0;
2680 
2681     /**
2682      * @since 5.21
2683      */
2684     virtual qlonglong windowId() const = 0;
2685     /**
2686      * Returns the internal id of the window that uniquely identifies it. The main difference
2687      * between internalId() and windowId() is that the latter one works as expected only on X11,
2688      * while the former is unique regardless of the window system.
2689      *
2690      * Note that the internaId() has special meaning only to kwin.
2691      * @since 5.24
2692      */
2693     virtual QUuid internalId() const = 0;
2694 
2695     /**
2696      * Can be used to by effects to store arbitrary data in the EffectWindow.
2697      *
2698      * Invoking this method will emit the signal EffectsHandler::windowDataChanged.
2699      * @see EffectsHandler::windowDataChanged
2700      */
2701     Q_SCRIPTABLE virtual void setData(int role, const QVariant &data) = 0;
2702     Q_SCRIPTABLE virtual QVariant data(int role) const = 0;
2703 
2704     /**
2705      * @brief References the previous window pixmap to prevent discarding.
2706      *
2707      * This method allows to reference the previous window pixmap in case that a window changed
2708      * its size, which requires a new window pixmap. By referencing the previous (and then outdated)
2709      * window pixmap an effect can for example cross fade the current window pixmap with the previous
2710      * one. This allows for smoother transitions for window geometry changes.
2711      *
2712      * If an effect calls this method on a window it also needs to call unreferencePreviousWindowPixmap
2713      * once it does no longer need the previous window pixmap.
2714      *
2715      * Note: the window pixmap is not kept forever even when referenced. If the geometry changes again, so that
2716      * a new window pixmap is created, the previous window pixmap will be exchanged with the current one. This
2717      * means it's still possible to have rendering glitches. An effect is supposed to track for itself the changes
2718      * to the window's geometry and decide how the transition should continue in such a situation.
2719      *
2720      * @see unreferencePreviousWindowPixmap
2721      * @since 4.11
2722      */
2723     virtual void referencePreviousWindowPixmap() = 0;
2724     /**
2725      * @brief Unreferences the previous window pixmap. Only relevant after referencePreviousWindowPixmap had
2726      * been called.
2727      *
2728      * @see referencePreviousWindowPixmap
2729      * @since 4.11
2730      */
2731     virtual void unreferencePreviousWindowPixmap() = 0;
2732 
2733     virtual bool isHidden() const = 0;
2734 
2735 protected:
2736     friend EffectWindowVisibleRef;
2737     virtual void refVisible(const EffectWindowVisibleRef *holder) = 0;
2738     virtual void unrefVisible(const EffectWindowVisibleRef *holder) = 0;
2739 
2740 private:
2741     class Private;
2742     std::unique_ptr<Private> d;
2743 };
2744 
2745 /**
2746  * The EffectWindowDeletedRef provides a convenient way to prevent deleting a closed
2747  * window until an effect has finished animating it.
2748  */
2749 class KWINEFFECTS_EXPORT EffectWindowDeletedRef
2750 {
2751 public:
2752     EffectWindowDeletedRef()
2753         : m_window(nullptr)
2754     {
2755     }
2756 
2757     explicit EffectWindowDeletedRef(EffectWindow *window)
2758         : m_window(window)
2759     {
2760         m_window->refWindow();
2761     }
2762 
2763     EffectWindowDeletedRef(const EffectWindowDeletedRef &other)
2764         : m_window(other.m_window)
2765     {
2766         if (m_window) {
2767             m_window->refWindow();
2768         }
2769     }
2770 
2771     ~EffectWindowDeletedRef()
2772     {
2773         if (m_window) {
2774             m_window->unrefWindow();
2775         }
2776     }
2777 
2778     EffectWindowDeletedRef &operator=(const EffectWindowDeletedRef &other)
2779     {
2780         if (other.m_window) {
2781             other.m_window->refWindow();
2782         }
2783         if (m_window) {
2784             m_window->unrefWindow();
2785         }
2786         m_window = other.m_window;
2787         return *this;
2788     }
2789 
2790     bool isNull() const
2791     {
2792         return m_window == nullptr;
2793     }
2794 
2795 private:
2796     EffectWindow *m_window;
2797 };
2798 
2799 /**
2800  * The EffectWindowVisibleRef provides a convenient way to force the visible status of a
2801  * window until an effect is finished animating it.
2802  */
2803 class KWINEFFECTS_EXPORT EffectWindowVisibleRef
2804 {
2805 public:
2806     EffectWindowVisibleRef()
2807         : m_window(nullptr)
2808         , m_reason(0)
2809     {
2810     }
2811 
2812     explicit EffectWindowVisibleRef(EffectWindow *window, int reason)
2813         : m_window(window)
2814         , m_reason(reason)
2815     {
2816         m_window->refVisible(this);
2817     }
2818 
2819     EffectWindowVisibleRef(const EffectWindowVisibleRef &other)
2820         : m_window(other.m_window)
2821         , m_reason(other.m_reason)
2822     {
2823         if (m_window) {
2824             m_window->refVisible(this);
2825         }
2826     }
2827 
2828     ~EffectWindowVisibleRef()
2829     {
2830         if (m_window) {
2831             m_window->unrefVisible(this);
2832         }
2833     }
2834 
2835     int reason() const
2836     {
2837         return m_reason;
2838     }
2839 
2840     EffectWindowVisibleRef &operator=(const EffectWindowVisibleRef &other)
2841     {
2842         if (other.m_window) {
2843             other.m_window->refVisible(&other);
2844         }
2845         if (m_window) {
2846             m_window->unrefVisible(this);
2847         }
2848         m_window = other.m_window;
2849         m_reason = other.m_reason;
2850         return *this;
2851     }
2852 
2853     bool isNull() const
2854     {
2855         return m_window == nullptr;
2856     }
2857 
2858 private:
2859     EffectWindow *m_window;
2860     int m_reason;
2861 };
2862 
2863 class KWINEFFECTS_EXPORT EffectWindowGroup
2864 {
2865 public:
2866     virtual ~EffectWindowGroup();
2867     virtual EffectWindowList members() const = 0;
2868 };
2869 
2870 struct GLVertex2D
2871 {
2872     QVector2D position;
2873     QVector2D texcoord;
2874 };
2875 
2876 struct GLVertex3D
2877 {
2878     QVector3D position;
2879     QVector2D texcoord;
2880 };
2881 
2882 /**
2883  * @short Vertex class
2884  *
2885  * A vertex is one position in a window. WindowQuad consists of four WindowVertex objects
2886  * and represents one part of a window.
2887  */
2888 class KWINEFFECTS_EXPORT WindowVertex
2889 {
2890 public:
2891     WindowVertex();
2892     WindowVertex(const QPointF &position, const QPointF &textureCoordinate);
2893     WindowVertex(double x, double y, double tx, double ty);
2894 
2895     double x() const
2896     {
2897         return px;
2898     }
2899     double y() const
2900     {
2901         return py;
2902     }
2903     double u() const
2904     {
2905         return tx;
2906     }
2907     double v() const
2908     {
2909         return ty;
2910     }
2911     void move(double x, double y);
2912     void setX(double x);
2913     void setY(double y);
2914 
2915 private:
2916     friend class WindowQuad;
2917     friend class WindowQuadList;
2918     double px, py; // position
2919     double tx, ty; // texture coords
2920 };
2921 
2922 /**
2923  * @short Class representing one area of a window.
2924  *
2925  * WindowQuads consists of four WindowVertex objects and represents one part of a window.
2926  */
2927 // NOTE: This class expects the (original) vertices to be in the clockwise order starting from topleft.
2928 class KWINEFFECTS_EXPORT WindowQuad
2929 {
2930 public:
2931     WindowQuad();
2932     WindowQuad makeSubQuad(double x1, double y1, double x2, double y2) const;
2933     WindowVertex &operator[](int index);
2934     const WindowVertex &operator[](int index) const;
2935     double left() const;
2936     double right() const;
2937     double top() const;
2938     double bottom() const;
2939     QRectF bounds() const;
2940 
2941 private:
2942     friend class WindowQuadList;
2943     WindowVertex verts[4];
2944 };
2945 
2946 class KWINEFFECTS_EXPORT WindowQuadList
2947     : public QVector<WindowQuad>
2948 {
2949 public:
2950     WindowQuadList splitAtX(double x) const;
2951     WindowQuadList splitAtY(double y) const;
2952     WindowQuadList makeGrid(int maxquadsize) const;
2953     WindowQuadList makeRegularGrid(int xSubdivisions, int ySubdivisions) const;
2954 };
2955 
2956 /**
2957  * A helper class for render geometry in device coordinates.
2958  *
2959  * This mostly represents a vector of vertices, with some convenience methods
2960  * for easily converting from WindowQuad and related classes to lists of
2961  * GLVertex2D. This class assumes rendering happens as unindexed triangles.
2962  */
2963 class KWINEFFECTS_EXPORT RenderGeometry : public QVector<GLVertex2D>
2964 {
2965 public:
2966     /**
2967      * In what way should vertices snap to integer device coordinates?
2968      *
2969      * Vertices are converted to device coordinates before being sent to the
2970      * rendering system. Depending on scaling factors, this may lead to device
2971      * coordinates with fractional parts. For some cases, this may not be ideal
2972      * as fractional coordinates need to be interpolated and can lead to
2973      * "blurry" rendering. To avoid that, we can snap the vertices to integer
2974      * device coordinates when they are added.
2975      */
2976     enum class VertexSnappingMode {
2977         None, //< No rounding, device coordinates containing fractional parts
2978               //  are passed directly to the rendering system.
2979         Round, //< Perform a simple rounding, device coordinates will not have
2980                //  any fractional parts.
2981     };
2982 
2983     /**
2984      * The vertex snapping mode to use for this geometry.
2985      *
2986      * By default, this is VertexSnappingMode::Round.
2987      */
2988     inline VertexSnappingMode vertexSnappingMode() const
2989     {
2990         return m_vertexSnappingMode;
2991     }
2992     /**
2993      * Set the vertex snapping mode to use for this geometry.
2994      *
2995      * Note that this doesn't change vertices retroactively, so you should set
2996      * this before adding any vertices, or clear and rebuild the geometry after
2997      * setting it.
2998      *
2999      * @param mode The new rounding mode.
3000      */
3001     void setVertexSnappingMode(VertexSnappingMode mode)
3002     {
3003         m_vertexSnappingMode = mode;
3004     }
3005     /**
3006      * Copy geometry data into another buffer.
3007      *
3008      * This is primarily intended for copying into a vertex buffer for rendering.
3009      *
3010      * @param destination The destination buffer. This needs to be at least large
3011      *                    enough to contain all elements.
3012      */
3013     void copy(std::span<GLVertex2D> destination);
3014     /**
3015      * Append a WindowVertex as a geometry vertex.
3016      *
3017      * WindowVertex is assumed to be in logical coordinates. It will be converted
3018      * to device coordinates using the specified device scale and then rounded
3019      * so it fits correctly on the device pixel grid.
3020      *
3021      * @param windowVertex The WindowVertex instance to append.
3022      * @param deviceScale The scaling factor to use to go from logical to device
3023      *                    coordinates.
3024      */
3025     void appendWindowVertex(const WindowVertex &windowVertex, qreal deviceScale);
3026     /**
3027      * Append a WindowQuad as two triangles.
3028      *
3029      * This will append the corners of the specified WindowQuad in the right
3030      * order so they make two triangles that can be rendered by OpenGL. The
3031      * corners are converted to device coordinates and rounded, just like
3032      * `appendWindowVertex()` does.
3033      *
3034      * @param quad The WindowQuad instance to append.
3035      * @param deviceScale The scaling factor to use to go from logical to device
3036      *                    coordinates.
3037      */
3038     void appendWindowQuad(const WindowQuad &quad, qreal deviceScale);
3039     /**
3040      * Append a sub-quad of a WindowQuad as two triangles.
3041      *
3042      * This will append the sub-quad specified by `intersection` as two
3043      * triangles. The quad is expected to be in logical coordinates, while the
3044      * intersection is expected to be in device coordinates. The texture
3045      * coordinates of the resulting vertices are based upon those of the quad,
3046      * using bilinear interpolation for interpolating how much of the original
3047      * texture coordinates to use.
3048      *
3049      * @param quad The WindowQuad instance to use a sub-quad of.
3050      * @param subquad The sub-quad to append.
3051      * @param deviceScale The scaling factor used to convert from logical to
3052      *                    device coordinates.
3053      */
3054     void appendSubQuad(const WindowQuad &quad, const QRectF &subquad, qreal deviceScale);
3055     /**
3056      * Modify this geometry's texture coordinates based on a matrix.
3057      *
3058      * This is primarily intended to convert from non-normalised to normalised
3059      * texture coordinates.
3060      *
3061      * @param textureMatrix The texture matrix to use for modifying the
3062      *                      texture coordinates. Note that only the 2D scale and
3063      *                      translation are used.
3064      */
3065     void postProcessTextureCoordinates(const QMatrix4x4 &textureMatrix);
3066 
3067 private:
3068     VertexSnappingMode m_vertexSnappingMode = VertexSnappingMode::Round;
3069 };
3070 
3071 class KWINEFFECTS_EXPORT WindowPrePaintData
3072 {
3073 public:
3074     int mask;
3075     /**
3076      * Region that will be painted, in screen coordinates.
3077      */
3078     QRegion paint;
3079     /**
3080      * Region indicating the opaque content. It can be used to avoid painting
3081      * windows occluded by the opaque region.
3082      */
3083     QRegion opaque;
3084     /**
3085      * Simple helper that sets data to say the window will be painted as non-opaque.
3086      * Takes also care of changing the regions.
3087      */
3088     void setTranslucent();
3089     /**
3090      * Helper to mark that this window will be transformed
3091      */
3092     void setTransformed();
3093 };
3094 
3095 class KWINEFFECTS_EXPORT PaintData
3096 {
3097 public:
3098     virtual ~PaintData();
3099     /**
3100      * @returns scale factor in X direction.
3101      * @since 4.10
3102      */
3103     qreal xScale() const;
3104     /**
3105      * @returns scale factor in Y direction.
3106      * @since 4.10
3107      */
3108     qreal yScale() const;
3109     /**
3110      * @returns scale factor in Z direction.
3111      * @since 4.10
3112      */
3113     qreal zScale() const;
3114     /**
3115      * Sets the scale factor in X direction to @p scale
3116      * @param scale The scale factor in X direction
3117      * @since 4.10
3118      */
3119     void setXScale(qreal scale);
3120     /**
3121      * Sets the scale factor in Y direction to @p scale
3122      * @param scale The scale factor in Y direction
3123      * @since 4.10
3124      */
3125     void setYScale(qreal scale);
3126     /**
3127      * Sets the scale factor in Z direction to @p scale
3128      * @param scale The scale factor in Z direction
3129      * @since 4.10
3130      */
3131     void setZScale(qreal scale);
3132     /**
3133      * Sets the scale factor in X and Y direction.
3134      * @param scale The scale factor for X and Y direction
3135      * @since 4.10
3136      */
3137     void setScale(const QVector2D &scale);
3138     /**
3139      * Sets the scale factor in X, Y and Z direction
3140      * @param scale The scale factor for X, Y and Z direction
3141      * @since 4.10
3142      */
3143     void setScale(const QVector3D &scale);
3144     const QVector3D &scale() const;
3145     const QVector3D &translation() const;
3146     /**
3147      * @returns the translation in X direction.
3148      * @since 4.10
3149      */
3150     qreal xTranslation() const;
3151     /**
3152      * @returns the translation in Y direction.
3153      * @since 4.10
3154      */
3155     qreal yTranslation() const;
3156     /**
3157      * @returns the translation in Z direction.
3158      * @since 4.10
3159      */
3160     qreal zTranslation() const;
3161     /**
3162      * Sets the translation in X direction to @p translate.
3163      * @since 4.10
3164      */
3165     void setXTranslation(qreal translate);
3166     /**
3167      * Sets the translation in Y direction to @p translate.
3168      * @since 4.10
3169      */
3170     void setYTranslation(qreal translate);
3171     /**
3172      * Sets the translation in Z direction to @p translate.
3173      * @since 4.10
3174      */
3175     void setZTranslation(qreal translate);
3176     /**
3177      * Performs a translation by adding the values component wise.
3178      * @param x Translation in X direction
3179      * @param y Translation in Y direction
3180      * @param z Translation in Z direction
3181      * @since 4.10
3182      */
3183     void translate(qreal x, qreal y = 0.0, qreal z = 0.0);
3184     /**
3185      * Performs a translation by adding the values component wise.
3186      * Overloaded method for convenience.
3187      * @param translate The translation
3188      * @since 4.10
3189      */
3190     void translate(const QVector3D &translate);
3191 
3192     /**
3193      * Sets the rotation angle.
3194      * @param angle The new rotation angle.
3195      * @since 4.10
3196      * @see rotationAngle()
3197      */
3198     void setRotationAngle(qreal angle);
3199     /**
3200      * Returns the rotation angle.
3201      * Initially 0.0.
3202      * @returns The current rotation angle.
3203      * @since 4.10
3204      * @see setRotationAngle
3205      */
3206     qreal rotationAngle() const;
3207     /**
3208      * Sets the rotation origin.
3209      * @param origin The new rotation origin.
3210      * @since 4.10
3211      * @see rotationOrigin()
3212      */
3213     void setRotationOrigin(const QVector3D &origin);
3214     /**
3215      * Returns the rotation origin. That is the point in space which is fixed during the rotation.
3216      * Initially this is 0/0/0.
3217      * @returns The rotation's origin
3218      * @since 4.10
3219      * @see setRotationOrigin()
3220      */
3221     QVector3D rotationOrigin() const;
3222     /**
3223      * Sets the rotation axis.
3224      * Set a component to 1.0 to rotate around this axis and to 0.0 to disable rotation around the
3225      * axis.
3226      * @param axis A vector holding information on which axis to rotate
3227      * @since 4.10
3228      * @see rotationAxis()
3229      */
3230     void setRotationAxis(const QVector3D &axis);
3231     /**
3232      * Sets the rotation axis.
3233      * Overloaded method for convenience.
3234      * @param axis The axis around which should be rotated.
3235      * @since 4.10
3236      * @see rotationAxis()
3237      */
3238     void setRotationAxis(Qt::Axis axis);
3239     /**
3240      * The current rotation axis.
3241      * By default the rotation is (0/0/1) which means a rotation around the z axis.
3242      * @returns The current rotation axis.
3243      * @since 4.10
3244      * @see setRotationAxis
3245      */
3246     QVector3D rotationAxis() const;
3247 
3248     /**
3249      * Returns the corresponding transform matrix.
3250      *
3251      * The transform matrix is converted to device coordinates using the
3252      * supplied deviceScale.
3253      */
3254     QMatrix4x4 toMatrix(qreal deviceScale) const;
3255 
3256 protected:
3257     PaintData();
3258     PaintData(const PaintData &other);
3259 
3260 private:
3261     const std::unique_ptr<PaintDataPrivate> d;
3262 };
3263 
3264 class KWINEFFECTS_EXPORT WindowPaintData : public PaintData
3265 {
3266 public:
3267     WindowPaintData();
3268     explicit WindowPaintData(const QMatrix4x4 &projectionMatrix);
3269     WindowPaintData(const WindowPaintData &other);
3270     ~WindowPaintData() override;
3271     /**
3272      * Scales the window by @p scale factor.
3273      * Multiplies all three components by the given factor.
3274      * @since 4.10
3275      */
3276     WindowPaintData &operator*=(qreal scale);
3277     /**
3278      * Scales the window by @p scale factor.
3279      * Performs a component wise multiplication on x and y components.
3280      * @since 4.10
3281      */
3282     WindowPaintData &operator*=(const QVector2D &scale);
3283     /**
3284      * Scales the window by @p scale factor.
3285      * Performs a component wise multiplication.
3286      * @since 4.10
3287      */
3288     WindowPaintData &operator*=(const QVector3D &scale);
3289     /**
3290      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
3291      * @since 4.10
3292      */
3293     WindowPaintData &operator+=(const QPointF &translation);
3294     /**
3295      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
3296      * Overloaded method for convenience.
3297      * @since 4.10
3298      */
3299     WindowPaintData &operator+=(const QPoint &translation);
3300     /**
3301      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
3302      * Overloaded method for convenience.
3303      * @since 4.10
3304      */
3305     WindowPaintData &operator+=(const QVector2D &translation);
3306     /**
3307      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
3308      * Overloaded method for convenience.
3309      * @since 4.10
3310      */
3311     WindowPaintData &operator+=(const QVector3D &translation);
3312     /**
3313      * Window opacity, in range 0 = transparent to 1 = fully opaque
3314      * @see setOpacity
3315      * @since 4.10
3316      */
3317     qreal opacity() const;
3318     /**
3319      * Sets the window opacity to the new @p opacity.
3320      * If you want to modify the existing opacity level consider using multiplyOpacity.
3321      * @param opacity The new opacity level
3322      * @since 4.10
3323      */
3324     void setOpacity(qreal opacity);
3325     /**
3326      * Multiplies the current opacity with the @p factor.
3327      * @param factor Factor with which the opacity should be multiplied
3328      * @return New opacity level
3329      * @since 4.10
3330      */
3331     qreal multiplyOpacity(qreal factor);
3332     /**
3333      * Saturation of the window, in range [0; 1]
3334      * 1 means that the window is unchanged, 0 means that it's completely
3335      *  unsaturated (greyscale). 0.5 would make the colors less intense,
3336      *  but not completely grey
3337      * Use EffectsHandler::saturationSupported() to find out whether saturation
3338      * is supported by the system, otherwise this value has no effect.
3339      * @return The current saturation
3340      * @see setSaturation()
3341      * @since 4.10
3342      */
3343     qreal saturation() const;
3344     /**
3345      * Sets the window saturation level to @p saturation.
3346      * If you want to modify the existing saturation level consider using multiplySaturation.
3347      * @param saturation The new saturation level
3348      * @since 4.10
3349      */
3350     void setSaturation(qreal saturation) const;
3351     /**
3352      * Multiplies the current saturation with @p factor.
3353      * @param factor with which the saturation should be multiplied
3354      * @return New saturation level
3355      * @since 4.10
3356      */
3357     qreal multiplySaturation(qreal factor);
3358     /**
3359      * Brightness of the window, in range [0; 1]
3360      * 1 means that the window is unchanged, 0 means that it's completely
3361      * black. 0.5 would make it 50% darker than usual
3362      */
3363     qreal brightness() const;
3364     /**
3365      * Sets the window brightness level to @p brightness.
3366      * If you want to modify the existing brightness level consider using multiplyBrightness.
3367      * @param brightness The new brightness level
3368      */
3369     void setBrightness(qreal brightness);
3370     /**
3371      * Multiplies the current brightness level with @p factor.
3372      * @param factor with which the brightness should be multiplied.
3373      * @return New brightness level
3374      * @since 4.10
3375      */
3376     qreal multiplyBrightness(qreal factor);
3377     /**
3378      * The screen number for which the painting should be done.
3379      * This affects color correction (different screens may need different
3380      * color correction lookup tables because they have different ICC profiles).
3381      * @return screen for which painting should be done
3382      */
3383     int screen() const;
3384     /**
3385      * @param screen New screen number
3386      * A value less than 0 will indicate that a default profile should be done.
3387      */
3388     void setScreen(int screen) const;
3389     /**
3390      * @brief Sets the cross fading @p factor to fade over with previously sized window.
3391      * If @c 1.0 only the current window is used, if @c 0.0 only the previous window is used.
3392      *
3393      * By default only the current window is used. This factor can only make any visual difference
3394      * if the previous window get referenced.
3395      *
3396      * @param factor The cross fade factor between @c 0.0 (previous window) and @c 1.0 (current window)
3397      * @see crossFadeProgress
3398      */
3399     void setCrossFadeProgress(qreal factor);
3400     /**
3401      * @see setCrossFadeProgress
3402      */
3403     qreal crossFadeProgress() const;
3404 
3405     /**
3406      * Sets the projection matrix that will be used when painting the window.
3407      *
3408      * The default projection matrix can be overridden by setting this matrix
3409      * to a non-identity matrix.
3410      */
3411     void setProjectionMatrix(const QMatrix4x4 &matrix);
3412 
3413     /**
3414      * Returns the current projection matrix.
3415      *
3416      * The default value for this matrix is the identity matrix.
3417      */
3418     QMatrix4x4 projectionMatrix() const;
3419 
3420     /**
3421      * Returns a reference to the projection matrix.
3422      */
3423     QMatrix4x4 &rprojectionMatrix();
3424 
3425     /**
3426      * An override for the scale the window should be rendered at.
3427      *
3428      * When set, this value will be used instead of the window's output scale
3429      * when rendering.
3430      */
3431     std::optional<qreal> renderTargetScale() const;
3432     void setRenderTargetScale(qreal scale);
3433 
3434 private:
3435     const std::unique_ptr<WindowPaintDataPrivate> d;
3436 };
3437 
3438 class KWINEFFECTS_EXPORT ScreenPaintData
3439 {
3440 public:
3441     ScreenPaintData();
3442     ScreenPaintData(const QMatrix4x4 &projectionMatrix, EffectScreen *screen = nullptr);
3443     ScreenPaintData(const ScreenPaintData &other);
3444     ~ScreenPaintData();
3445 
3446     ScreenPaintData &operator=(const ScreenPaintData &rhs);
3447 
3448     /**
3449      * The projection matrix used by the scene for the current rendering pass.
3450      * On non-OpenGL compositors it's set to Identity matrix.
3451      * @since 5.6
3452      */
3453     QMatrix4x4 projectionMatrix() const;
3454 
3455     /**
3456      * Returns the currently rendered screen. It's always the primary screen on X11.
3457      */
3458     EffectScreen *screen() const;
3459 
3460 private:
3461     class Private;
3462     std::unique_ptr<Private> d;
3463 };
3464 
3465 class KWINEFFECTS_EXPORT ScreenPrePaintData
3466 {
3467 public:
3468     int mask;
3469     QRegion paint;
3470     EffectScreen *screen = nullptr;
3471 };
3472 
3473 /**
3474  * @internal
3475  */
3476 template<typename T>
3477 class KWINEFFECTS_EXPORT Motion
3478 {
3479 public:
3480     /**
3481      * Creates a new motion object. "Strength" is the amount of
3482      * acceleration that is applied to the object when the target
3483      * changes and "smoothness" relates to how fast the object
3484      * can change its direction and speed.
3485      */
3486     explicit Motion(T initial, double strength, double smoothness);
3487     /**
3488      * Creates an exact copy of another motion object, including
3489      * position, target and velocity.
3490      */
3491     Motion(const Motion<T> &other);
3492     ~Motion();
3493 
3494     inline T value() const
3495     {
3496         return m_value;
3497     }
3498     inline void setValue(const T value)
3499     {
3500         m_value = value;
3501     }
3502     inline T target() const
3503     {
3504         return m_target;
3505     }
3506     inline void setTarget(const T target)
3507     {
3508         m_start = m_value;
3509         m_target = target;
3510     }
3511     inline T velocity() const
3512     {
3513         return m_velocity;
3514     }
3515     inline void setVelocity(const T velocity)
3516     {
3517         m_velocity = velocity;
3518     }
3519 
3520     inline double strength() const
3521     {
3522         return m_strength;
3523     }
3524     inline void setStrength(const double strength)
3525     {
3526         m_strength = strength;
3527     }
3528     inline double smoothness() const
3529     {
3530         return m_smoothness;
3531     }
3532     inline void setSmoothness(const double smoothness)
3533     {
3534         m_smoothness = smoothness;
3535     }
3536     inline T startValue()
3537     {
3538         return m_start;
3539     }
3540 
3541     /**
3542      * The distance between the current position and the target.
3543      */
3544     inline T distance() const
3545     {
3546         return m_target - m_value;
3547     }
3548 
3549     /**
3550      * Calculates the new position if not at the target. Called
3551      * once per frame only.
3552      */
3553     void calculate(const int msec);
3554     /**
3555      * Place the object on top of the target immediately,
3556      * bypassing all movement calculation.
3557      */
3558     void finish();
3559 
3560 private:
3561     T m_value;
3562     T m_start;
3563     T m_target;
3564     T m_velocity;
3565     double m_strength;
3566     double m_smoothness;
3567 };
3568 
3569 /**
3570  * @short A single 1D motion dynamics object.
3571  *
3572  * This class represents a single object that can be moved around a
3573  * 1D space. Although it can be used directly by itself it is
3574  * recommended to use a motion manager instead.
3575  */
3576 class KWINEFFECTS_EXPORT Motion1D : public Motion<double>
3577 {
3578 public:
3579     explicit Motion1D(double initial = 0.0, double strength = 0.08, double smoothness = 4.0);
3580     Motion1D(const Motion1D &other);
3581     ~Motion1D();
3582 };
3583 
3584 /**
3585  * @short A single 2D motion dynamics object.
3586  *
3587  * This class represents a single object that can be moved around a
3588  * 2D space. Although it can be used directly by itself it is
3589  * recommended to use a motion manager instead.
3590  */
3591 class KWINEFFECTS_EXPORT Motion2D : public Motion<QPointF>
3592 {
3593 public:
3594     explicit Motion2D(QPointF initial = QPointF(), double strength = 0.08, double smoothness = 4.0);
3595     Motion2D(const Motion2D &other);
3596     ~Motion2D();
3597 };
3598 
3599 /**
3600  * @short Helper class for motion dynamics in KWin effects.
3601  *
3602  * This motion manager class is intended to help KWin effect authors
3603  * move windows across the screen smoothly and naturally. Once
3604  * windows are registered by the manager the effect can issue move
3605  * commands with the moveWindow() methods. The position of any
3606  * managed window can be determined in realtime by the
3607  * transformedGeometry() method. As the manager knows if any windows
3608  * are moving at any given time it can also be used as a notifier as
3609  * to see whether the effect is active or not.
3610  */
3611 class KWINEFFECTS_EXPORT WindowMotionManager
3612 {
3613 public:
3614     /**
3615      * Creates a new window manager object.
3616      */
3617     explicit WindowMotionManager(bool useGlobalAnimationModifier = true);
3618     ~WindowMotionManager();
3619 
3620     /**
3621      * Register a window for managing.
3622      */
3623     void manage(EffectWindow *w);
3624     /**
3625      * Register a list of windows for managing.
3626      */
3627     inline void manage(const EffectWindowList &list)
3628     {
3629         for (int i = 0; i < list.size(); i++) {
3630             manage(list.at(i));
3631         }
3632     }
3633     /**
3634      * Deregister a window. All transformations applied to the
3635      * window will be permanently removed and cannot be recovered.
3636      */
3637     void unmanage(EffectWindow *w);
3638     /**
3639      * Deregister all windows, returning the manager to its
3640      * originally initiated state.
3641      */
3642     void unmanageAll();
3643     /**
3644      * Determine the new positions for windows that have not
3645      * reached their target. Called once per frame, usually in
3646      * prePaintScreen(). Remember to set the
3647      * Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS flag.
3648      */
3649     void calculate(int time);
3650     /**
3651      * Modify a registered window's paint data to make it appear
3652      * at its real location on the screen. Usually called in
3653      * paintWindow(). Remember to flag the window as having been
3654      * transformed in prePaintWindow() by calling
3655      * WindowPrePaintData::setTransformed()
3656      */
3657     void apply(EffectWindow *w, WindowPaintData &data);
3658     /**
3659      * Set all motion targets and values back to where the
3660      * windows were before transformations. The same as
3661      * unmanaging then remanaging all windows.
3662      */
3663     void reset();
3664     /**
3665      * Resets the motion target and current value of a single
3666      * window.
3667      */
3668     void reset(EffectWindow *w);
3669 
3670     /**
3671      * Ask the manager to move the window to the target position
3672      * with the specified scale. If `yScale` is not provided or
3673      * set to 0.0, `scale` will be used as the scale in the
3674      * vertical direction as well as in the horizontal direction.
3675      */
3676     void moveWindow(EffectWindow *w, QPoint target, double scale = 1.0, double yScale = 0.0);
3677     /**
3678      * This is an overloaded method, provided for convenience.
3679      *
3680      * Ask the manager to move the window to the target rectangle.
3681      * Automatically determines scale.
3682      */
3683     inline void moveWindow(EffectWindow *w, QRect target)
3684     {
3685         // TODO: Scale might be slightly different in the comparison due to rounding
3686         moveWindow(w, target.topLeft(),
3687                    target.width() / double(w->width()), target.height() / double(w->height()));
3688     }
3689 
3690     /**
3691      * Retrieve the current tranformed geometry of a registered
3692      * window.
3693      */
3694     QRectF transformedGeometry(EffectWindow *w) const;
3695     /**
3696      * Sets the current transformed geometry of a registered window to the given geometry.
3697      * @see transformedGeometry
3698      * @since 4.5
3699      */
3700     void setTransformedGeometry(EffectWindow *w, const QRectF &geometry);
3701     /**
3702      * Retrieve the current target geometry of a registered
3703      * window.
3704      */
3705     QRectF targetGeometry(EffectWindow *w) const;
3706     /**
3707      * Return the window that has its transformed geometry under
3708      * the specified point. It is recommended to use the stacking
3709      * order as it's what the user sees, but it is slightly
3710      * slower to process.
3711      */
3712     EffectWindow *windowAtPoint(QPoint point, bool useStackingOrder = true) const;
3713 
3714     /**
3715      * Return a list of all currently registered windows.
3716      */
3717     inline EffectWindowList managedWindows() const
3718     {
3719         return m_managedWindows.keys();
3720     }
3721     /**
3722      * Returns whether or not a specified window is being managed
3723      * by this manager object.
3724      */
3725     inline bool isManaging(EffectWindow *w) const
3726     {
3727         return m_managedWindows.contains(w);
3728     }
3729     /**
3730      * Returns whether or not this manager object is actually
3731      * managing any windows or not.
3732      */
3733     inline bool managingWindows() const
3734     {
3735         return !m_managedWindows.empty();
3736     }
3737     /**
3738      * Returns whether all windows have reached their targets yet
3739      * or not. Can be used to see if an effect should be
3740      * processed and displayed or not.
3741      */
3742     inline bool areWindowsMoving() const
3743     {
3744         return !m_movingWindowsSet.isEmpty();
3745     }
3746     /**
3747      * Returns whether a window has reached its targets yet
3748      * or not.
3749      */
3750     inline bool isWindowMoving(EffectWindow *w) const
3751     {
3752         return m_movingWindowsSet.contains(w);
3753     }
3754 
3755 private:
3756     bool m_useGlobalAnimationModifier;
3757     struct WindowMotion
3758     {
3759         // TODO: Rotation, etc?
3760         Motion2D translation; // Absolute position
3761         Motion2D scale; // xScale and yScale
3762     };
3763     QHash<EffectWindow *, WindowMotion> m_managedWindows;
3764     QSet<EffectWindow *> m_movingWindowsSet;
3765 };
3766 
3767 /**
3768  * @short Helper class for displaying text and icons in frames.
3769  *
3770  * Paints text and/or and icon with an optional frame around them. The
3771  * available frames includes one that follows the default Plasma theme and
3772  * another that doesn't.
3773  * It is recommended to use this class whenever displaying text.
3774  */
3775 class KWINEFFECTS_EXPORT EffectFrame
3776 {
3777 public:
3778     EffectFrame();
3779     virtual ~EffectFrame();
3780 
3781     /**
3782      * Delete any existing textures to free up graphics memory. They will
3783      * be automatically recreated the next time they are required.
3784      */
3785     virtual void free() = 0;
3786 
3787     /**
3788      * Render the frame.
3789      */
3790     virtual void render(const QRegion &region = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0) = 0;
3791 
3792     virtual void setPosition(const QPoint &point) = 0;
3793     /**
3794      * Set the text alignment for static frames and the position alignment
3795      * for non-static.
3796      */
3797     virtual void setAlignment(Qt::Alignment alignment) = 0;
3798     virtual Qt::Alignment alignment() const = 0;
3799     virtual void setGeometry(const QRect &geometry, bool force = false) = 0;
3800     virtual const QRect &geometry() const = 0;
3801 
3802     virtual void setText(const QString &text) = 0;
3803     virtual const QString &text() const = 0;
3804     virtual void setFont(const QFont &font) = 0;
3805     virtual const QFont &font() const = 0;
3806     /**
3807      * Set the icon that will appear on the left-hand size of the frame.
3808      */
3809     virtual void setIcon(const QIcon &icon) = 0;
3810     virtual const QIcon &icon() const = 0;
3811     virtual void setIconSize(const QSize &size) = 0;
3812     virtual const QSize &iconSize() const = 0;
3813 
3814     /**
3815      * @returns The style of this EffectFrame.
3816      */
3817     virtual EffectFrameStyle style() const = 0;
3818 
3819     /**
3820      * If @p enable is @c true cross fading between icons and text is enabled
3821      * By default disabled. Use setCrossFadeProgress to cross fade.
3822      * Cross Fading is currently only available if OpenGL is used.
3823      * @param enable @c true enables cross fading, @c false disables it again
3824      * @see isCrossFade
3825      * @see setCrossFadeProgress
3826      * @since 4.6
3827      */
3828     virtual void enableCrossFade(bool enable) = 0;
3829     /**
3830      * @returns @c true if cross fading is enabled, @c false otherwise
3831      * @see enableCrossFade
3832      * @since 4.6
3833      */
3834     virtual bool isCrossFade() const = 0;
3835     /**
3836      * Sets the current progress for cross fading the last used icon/text
3837      * with current icon/text to @p progress.
3838      * A value of 0.0 means completely old icon/text, a value of 1.0 means
3839      * completely current icon/text.
3840      * Default value is 1.0. You have to enable cross fade before using it.
3841      * Cross Fading is currently only available if OpenGL is used.
3842      * @see enableCrossFade
3843      * @see isCrossFade
3844      * @see crossFadeProgress
3845      * @since 4.6
3846      */
3847     virtual void setCrossFadeProgress(qreal progress) = 0;
3848     /**
3849      * @returns The current progress for cross fading
3850      * @see setCrossFadeProgress
3851      * @see enableCrossFade
3852      * @see isCrossFade
3853      * @since 4.6
3854      */
3855     virtual qreal crossFadeProgress() const = 0;
3856 
3857 private:
3858     const std::unique_ptr<EffectFramePrivate> d;
3859 };
3860 
3861 /**
3862  * The TimeLine class is a helper for controlling animations.
3863  */
3864 class KWINEFFECTS_EXPORT TimeLine
3865 {
3866 public:
3867     /**
3868      * Direction of the timeline.
3869      *
3870      * When the direction of the timeline is Forward, the progress
3871      * value will go from 0.0 to 1.0.
3872      *
3873      * When the direction of the timeline is Backward, the progress
3874      * value will go from 1.0 to 0.0.
3875      */
3876     enum Direction {
3877         Forward,
3878         Backward
3879     };
3880 
3881     /**
3882      * Constructs a new instance of TimeLine.
3883      *
3884      * @param duration Duration of the timeline, in milliseconds
3885      * @param direction Direction of the timeline
3886      * @since 5.14
3887      */
3888     explicit TimeLine(std::chrono::milliseconds duration = std::chrono::milliseconds(1000),
3889                       Direction direction = Forward);
3890     TimeLine(const TimeLine &other);
3891     ~TimeLine();
3892 
3893     /**
3894      * Returns the current value of the timeline.
3895      *
3896      * @since 5.14
3897      */
3898     qreal value() const;
3899 
3900     /**
3901      * Advances the timeline to the specified @a timestamp.
3902      */
3903     void advance(std::chrono::milliseconds timestamp);
3904 
3905     /**
3906      * Returns the number of elapsed milliseconds.
3907      *
3908      * @see setElapsed
3909      * @since 5.14
3910      */
3911     std::chrono::milliseconds elapsed() const;
3912 
3913     /**
3914      * Sets the number of elapsed milliseconds.
3915      *
3916      * This method overwrites previous value of elapsed milliseconds.
3917      * If the new value of elapsed milliseconds is greater or equal
3918      * to duration of the timeline, the timeline will be finished, i.e.
3919      * proceeding TimeLine::done method calls will return @c true.
3920      * Please don't use it. Instead, use TimeLine::update.
3921      *
3922      * @note The new number of elapsed milliseconds should be a non-negative
3923      * number, i.e. it should be greater or equal to 0.
3924      *
3925      * @param elapsed The new number of elapsed milliseconds
3926      * @see elapsed
3927      * @since 5.14
3928      */
3929     void setElapsed(std::chrono::milliseconds elapsed);
3930 
3931     /**
3932      * Returns the duration of the timeline.
3933      *
3934      * @returns Duration of the timeline, in milliseconds
3935      * @see setDuration
3936      * @since 5.14
3937      */
3938     std::chrono::milliseconds duration() const;
3939 
3940     /**
3941      * Sets the duration of the timeline.
3942      *
3943      * In addition to setting new value of duration, the timeline will
3944      * try to retarget the number of elapsed milliseconds to match
3945      * as close as possible old progress value. If the new duration
3946      * is much smaller than old duration, there is a big chance that
3947      * the timeline will be finished after setting new duration.
3948      *
3949      * @note The new duration should be a positive number, i.e. it
3950      * should be greater or equal to 1.
3951      *
3952      * @param duration The new duration of the timeline, in milliseconds
3953      * @see duration
3954      * @since 5.14
3955      */
3956     void setDuration(std::chrono::milliseconds duration);
3957 
3958     /**
3959      * Returns the direction of the timeline.
3960      *
3961      * @returns Direction of the timeline(TimeLine::Forward or TimeLine::Backward)
3962      * @see setDirection
3963      * @see toggleDirection
3964      * @since 5.14
3965      */
3966     Direction direction() const;
3967 
3968     /**
3969      * Sets the direction of the timeline.
3970      *
3971      * @param direction The new direction of the timeline
3972      * @see direction
3973      * @see toggleDirection
3974      * @since 5.14
3975      */
3976     void setDirection(Direction direction);
3977 
3978     /**
3979      * Toggles the direction of the timeline.
3980      *
3981      * If the direction of the timeline was TimeLine::Forward, it becomes
3982      * TimeLine::Backward, and vice verca.
3983      *
3984      * @see direction
3985      * @see setDirection
3986      * @since 5.14
3987      */
3988     void toggleDirection();
3989 
3990     /**
3991      * Returns the easing curve of the timeline.
3992      *
3993      * @see setEasingCurve
3994      * @since 5.14
3995      */
3996     QEasingCurve easingCurve() const;
3997 
3998     /**
3999      * Sets new easing curve.
4000      *
4001      * @param easingCurve An easing curve to be set
4002      * @see easingCurve
4003      * @since 5.14
4004      */
4005     void setEasingCurve(const QEasingCurve &easingCurve);
4006 
4007     /**
4008      * Sets new easing curve by providing its type.
4009      *
4010      * @param type Type of the easing curve(e.g. QEasingCurve::InCubic, etc)
4011      * @see easingCurve
4012      * @since 5.14
4013      */
4014     void setEasingCurve(QEasingCurve::Type type);
4015 
4016     /**
4017      * Returns whether the timeline is currently in progress.
4018      *
4019      * @see done
4020      * @since 5.14
4021      */
4022     bool running() const;
4023 
4024     /**
4025      * Returns whether the timeline is finished.
4026      *
4027      * @see reset
4028      * @since 5.14
4029      */
4030     bool done() const;
4031 
4032     /**
4033      * Resets the timeline to initial state.
4034      *
4035      * @since 5.14
4036      */
4037     void reset();
4038 
4039     enum class RedirectMode {
4040         Strict,
4041         Relaxed
4042     };
4043 
4044     /**
4045      * Returns the redirect mode for the source position.
4046      *
4047      * The redirect mode controls behavior of the timeline when its direction is
4048      * changed at the source position, e.g. what should we do when the timeline
4049      * initially goes forward and we change its direction to go backward.
4050      *
4051      * In the strict mode, the timeline will stop.
4052      *
4053      * In the relaxed mode, the timeline will go in the new direction. For example,
4054      * if the timeline goes forward(from 0 to 1), then with the new direction it
4055      * will go backward(from 1 to 0).
4056      *
4057      * The default is RedirectMode::Relaxed.
4058      *
4059      * @see targetRedirectMode
4060      * @since 5.15
4061      */
4062     RedirectMode sourceRedirectMode() const;
4063 
4064     /**
4065      * Sets the redirect mode for the source position.
4066      *
4067      * @param mode The new mode.
4068      * @since 5.15
4069      */
4070     void setSourceRedirectMode(RedirectMode mode);
4071 
4072     /**
4073      * Returns the redirect mode for the target position.
4074      *
4075      * The redirect mode controls behavior of the timeline when its direction is
4076      * changed at the target position.
4077      *
4078      * In the strict mode, subsequent update calls won't have any effect on the
4079      * current value of the timeline.
4080      *
4081      * In the relaxed mode, the timeline will go in the new direction.
4082      *
4083      * The default is RedirectMode::Strict.
4084      *
4085      * @see sourceRedirectMode
4086      * @since 5.15
4087      */
4088     RedirectMode targetRedirectMode() const;
4089 
4090     /**
4091      * Sets the redirect mode for the target position.
4092      *
4093      * @param mode The new mode.
4094      * @since 5.15
4095      */
4096     void setTargetRedirectMode(RedirectMode mode);
4097 
4098     TimeLine &operator=(const TimeLine &other);
4099 
4100     /**
4101      * @returns a value between 0 and 1 defining the progress of the timeline
4102      *
4103      * @since 5.23
4104      */
4105     qreal progress() const;
4106 
4107 private:
4108     class Data;
4109     QSharedDataPointer<Data> d;
4110 };
4111 
4112 /**
4113  * Pointer to the global EffectsHandler object.
4114  */
4115 extern KWINEFFECTS_EXPORT EffectsHandler *effects;
4116 
4117 /***************************************************************
4118  WindowVertex
4119 ***************************************************************/
4120 
4121 inline WindowVertex::WindowVertex()
4122     : px(0)
4123     , py(0)
4124     , tx(0)
4125     , ty(0)
4126 {
4127 }
4128 
4129 inline WindowVertex::WindowVertex(double _x, double _y, double _tx, double _ty)
4130     : px(_x)
4131     , py(_y)
4132     , tx(_tx)
4133     , ty(_ty)
4134 {
4135 }
4136 
4137 inline WindowVertex::WindowVertex(const QPointF &position, const QPointF &texturePosition)
4138     : px(position.x())
4139     , py(position.y())
4140     , tx(texturePosition.x())
4141     , ty(texturePosition.y())
4142 {
4143 }
4144 
4145 inline void WindowVertex::move(double x, double y)
4146 {
4147     px = x;
4148     py = y;
4149 }
4150 
4151 inline void WindowVertex::setX(double x)
4152 {
4153     px = x;
4154 }
4155 
4156 inline void WindowVertex::setY(double y)
4157 {
4158     py = y;
4159 }
4160 
4161 /***************************************************************
4162  WindowQuad
4163 ***************************************************************/
4164 
4165 inline WindowQuad::WindowQuad()
4166 {
4167 }
4168 
4169 inline WindowVertex &WindowQuad::operator[](int index)
4170 {
4171     Q_ASSERT(index >= 0 && index < 4);
4172     return verts[index];
4173 }
4174 
4175 inline const WindowVertex &WindowQuad::operator[](int index) const
4176 {
4177     Q_ASSERT(index >= 0 && index < 4);
4178     return verts[index];
4179 }
4180 
4181 inline double WindowQuad::left() const
4182 {
4183     return std::min(verts[0].px, std::min(verts[1].px, std::min(verts[2].px, verts[3].px)));
4184 }
4185 
4186 inline double WindowQuad::right() const
4187 {
4188     return std::max(verts[0].px, std::max(verts[1].px, std::max(verts[2].px, verts[3].px)));
4189 }
4190 
4191 inline double WindowQuad::top() const
4192 {
4193     return std::min(verts[0].py, std::min(verts[1].py, std::min(verts[2].py, verts[3].py)));
4194 }
4195 
4196 inline double WindowQuad::bottom() const
4197 {
4198     return std::max(verts[0].py, std::max(verts[1].py, std::max(verts[2].py, verts[3].py)));
4199 }
4200 
4201 inline QRectF WindowQuad::bounds() const
4202 {
4203     return QRectF(QPointF(left(), top()), QPointF(right(), bottom()));
4204 }
4205 
4206 /***************************************************************
4207  Motion
4208 ***************************************************************/
4209 
4210 template<typename T>
4211 Motion<T>::Motion(T initial, double strength, double smoothness)
4212     : m_value(initial)
4213     , m_start(initial)
4214     , m_target(initial)
4215     , m_velocity()
4216     , m_strength(strength)
4217     , m_smoothness(smoothness)
4218 {
4219 }
4220 
4221 template<typename T>
4222 Motion<T>::Motion(const Motion &other)
4223     : m_value(other.value())
4224     , m_start(other.target())
4225     , m_target(other.target())
4226     , m_velocity(other.velocity())
4227     , m_strength(other.strength())
4228     , m_smoothness(other.smoothness())
4229 {
4230 }
4231 
4232 template<typename T>
4233 Motion<T>::~Motion()
4234 {
4235 }
4236 
4237 template<typename T>
4238 void Motion<T>::calculate(const int msec)
4239 {
4240     if (m_value == m_target && m_velocity == T()) { // At target and not moving
4241         return;
4242     }
4243 
4244     // Poor man's time independent calculation
4245     int steps = std::max(1, msec / 5);
4246     for (int i = 0; i < steps; i++) {
4247         T diff = m_target - m_value;
4248         T strength = diff * m_strength;
4249         m_velocity = (m_smoothness * m_velocity + strength) / (m_smoothness + 1.0);
4250         m_value += m_velocity;
4251     }
4252 }
4253 
4254 template<typename T>
4255 void Motion<T>::finish()
4256 {
4257     m_value = m_target;
4258     m_velocity = T();
4259 }
4260 
4261 /***************************************************************
4262  Effect
4263 ***************************************************************/
4264 template<typename T>
4265 int Effect::animationTime(int defaultDuration)
4266 {
4267     return animationTime(T::duration() != 0 ? T::duration() : defaultDuration);
4268 }
4269 
4270 template<typename T>
4271 void Effect::initConfig()
4272 {
4273     T::instance(effects->config());
4274 }
4275 
4276 /***************************************************************
4277  EffectWindow
4278 ***************************************************************/
4279 
4280 inline void EffectWindow::addRepaint(int x, int y, int w, int h)
4281 {
4282     addRepaint(QRect(x, y, w, h));
4283 }
4284 
4285 inline void EffectWindow::addLayerRepaint(int x, int y, int w, int h)
4286 {
4287     addLayerRepaint(QRect(x, y, w, h));
4288 }
4289 
4290 } // namespace
4291 Q_DECLARE_METATYPE(KWin::EffectWindow *)
4292 Q_DECLARE_METATYPE(KWin::EffectWindowList)
4293 Q_DECLARE_METATYPE(KWin::TimeLine)
4294 Q_DECLARE_METATYPE(KWin::TimeLine::Direction)
4295 
4296 /** @} */