File indexing completed on 2024-05-19 05:31:40

0001 /*
0002     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0003     SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
0004     SPDX-FileCopyrightText: 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
0005     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "effect/globals.h"
0013 
0014 #include <QRegion>
0015 
0016 #include <KPluginFactory>
0017 #include <KSharedConfig>
0018 
0019 class QKeyEvent;
0020 class QTabletEvent;
0021 
0022 namespace KWin
0023 {
0024 
0025 class EffectWindow;
0026 class Output;
0027 class PaintDataPrivate;
0028 class RenderTarget;
0029 class RenderViewport;
0030 class WindowPaintDataPrivate;
0031 
0032 /** @defgroup kwineffects KWin effects library
0033  * KWin effects library contains necessary classes for creating new KWin
0034  * compositing effects.
0035  *
0036  * @section creating Creating new effects
0037  * This example will demonstrate the basics of creating an effect. We'll use
0038  *  CoolEffect as the class name, cooleffect as internal name and
0039  *  "Cool Effect" as user-visible name of the effect.
0040  *
0041  * This example doesn't demonstrate how to write the effect's code. For that,
0042  *  see the documentation of the Effect class.
0043  *
0044  * @subsection creating-class CoolEffect class
0045  * First you need to create CoolEffect class which has to be a subclass of
0046  *  @ref KWin::Effect. In that class you can reimplement various virtual
0047  *  methods to control how and where the windows are drawn.
0048  *
0049  * @subsection creating-macro KWIN_EFFECT_FACTORY macro
0050  * This library provides a specialized KPluginFactory subclass and macros to
0051  * create a sub class. This subclass of KPluginFactory has to be used, otherwise
0052  * KWin won't load the plugin. Use the @ref KWIN_EFFECT_FACTORY macro to create the
0053  * plugin factory. This macro will take the embedded json metadata filename as the second argument.
0054  *
0055  * @subsection creating-buildsystem Buildsystem
0056  * To build the effect, you can use the kcoreaddons_add_plugin cmake macro which
0057  *  takes care of creating the library and installing it.
0058  *  The first parameter is the name of the library, this is the same as the id of the plugin.
0059  *  If our effect's source is in cooleffect.cpp, we'd use following:
0060  * @code
0061  *     kcoreaddons_add_plugin(cooleffect SOURCES cooleffect.cpp INSTALL_NAMESPACE "kwin/effects/plugins")
0062  * @endcode
0063  *
0064  * @subsection creating-json-metadata Effect's .json file for embedded metadata
0065  * The format follows the one of the @see KPluginMetaData class.
0066  *
0067  * Example cooleffect.json file:
0068  * @code
0069 {
0070     "KPlugin": {
0071         "Authors": [
0072             {
0073                 "Email": "my@email.here",
0074                 "Name": "My Name"
0075             }
0076         ],
0077         "Category": "Misc",
0078         "Description": "The coolest effect you've ever seen",
0079         "Icon": "preferences-system-windows-effect-cooleffect",
0080         "Name": "Cool Effect"
0081     }
0082 }
0083  * @endcode
0084  *
0085  * @section accessing Accessing windows and workspace
0086  * Effects can gain access to the properties of windows and workspace via
0087  *  EffectWindow and EffectsHandler classes.
0088  *
0089  * There is one global EffectsHandler object which you can access using the
0090  *  @ref effects pointer.
0091  * For each window, there is an EffectWindow object which can be used to read
0092  *  window properties such as position and also to change them.
0093  *
0094  * For more information about this, see the documentation of the corresponding
0095  *  classes.
0096  *
0097  * @{
0098  */
0099 
0100 #define KWIN_EFFECT_API_MAKE_VERSION(major, minor) ((major) << 8 | (minor))
0101 #define KWIN_EFFECT_API_VERSION_MAJOR 0
0102 #define KWIN_EFFECT_API_VERSION_MINOR 236
0103 #define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
0104     KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR)
0105 
0106 class KWIN_EXPORT PaintData
0107 {
0108 public:
0109     virtual ~PaintData();
0110     /**
0111      * @returns scale factor in X direction.
0112      * @since 4.10
0113      */
0114     qreal xScale() const;
0115     /**
0116      * @returns scale factor in Y direction.
0117      * @since 4.10
0118      */
0119     qreal yScale() const;
0120     /**
0121      * @returns scale factor in Z direction.
0122      * @since 4.10
0123      */
0124     qreal zScale() const;
0125     /**
0126      * Sets the scale factor in X direction to @p scale
0127      * @param scale The scale factor in X direction
0128      * @since 4.10
0129      */
0130     void setXScale(qreal scale);
0131     /**
0132      * Sets the scale factor in Y direction to @p scale
0133      * @param scale The scale factor in Y direction
0134      * @since 4.10
0135      */
0136     void setYScale(qreal scale);
0137     /**
0138      * Sets the scale factor in Z direction to @p scale
0139      * @param scale The scale factor in Z direction
0140      * @since 4.10
0141      */
0142     void setZScale(qreal scale);
0143     /**
0144      * Sets the scale factor in X and Y direction.
0145      * @param scale The scale factor for X and Y direction
0146      * @since 4.10
0147      */
0148     void setScale(const QVector2D &scale);
0149     /**
0150      * Sets the scale factor in X, Y and Z direction
0151      * @param scale The scale factor for X, Y and Z direction
0152      * @since 4.10
0153      */
0154     void setScale(const QVector3D &scale);
0155     const QVector3D &scale() const;
0156     const QVector3D &translation() const;
0157     /**
0158      * @returns the translation in X direction.
0159      * @since 4.10
0160      */
0161     qreal xTranslation() const;
0162     /**
0163      * @returns the translation in Y direction.
0164      * @since 4.10
0165      */
0166     qreal yTranslation() const;
0167     /**
0168      * @returns the translation in Z direction.
0169      * @since 4.10
0170      */
0171     qreal zTranslation() const;
0172     /**
0173      * Sets the translation in X direction to @p translate.
0174      * @since 4.10
0175      */
0176     void setXTranslation(qreal translate);
0177     /**
0178      * Sets the translation in Y direction to @p translate.
0179      * @since 4.10
0180      */
0181     void setYTranslation(qreal translate);
0182     /**
0183      * Sets the translation in Z direction to @p translate.
0184      * @since 4.10
0185      */
0186     void setZTranslation(qreal translate);
0187     /**
0188      * Performs a translation by adding the values component wise.
0189      * @param x Translation in X direction
0190      * @param y Translation in Y direction
0191      * @param z Translation in Z direction
0192      * @since 4.10
0193      */
0194     void translate(qreal x, qreal y = 0.0, qreal z = 0.0);
0195     /**
0196      * Performs a translation by adding the values component wise.
0197      * Overloaded method for convenience.
0198      * @param translate The translation
0199      * @since 4.10
0200      */
0201     void translate(const QVector3D &translate);
0202 
0203     /**
0204      * Sets the rotation angle.
0205      * @param angle The new rotation angle.
0206      * @since 4.10
0207      * @see rotationAngle()
0208      */
0209     void setRotationAngle(qreal angle);
0210     /**
0211      * Returns the rotation angle.
0212      * Initially 0.0.
0213      * @returns The current rotation angle.
0214      * @since 4.10
0215      * @see setRotationAngle
0216      */
0217     qreal rotationAngle() const;
0218     /**
0219      * Sets the rotation origin.
0220      * @param origin The new rotation origin.
0221      * @since 4.10
0222      * @see rotationOrigin()
0223      */
0224     void setRotationOrigin(const QVector3D &origin);
0225     /**
0226      * Returns the rotation origin. That is the point in space which is fixed during the rotation.
0227      * Initially this is 0/0/0.
0228      * @returns The rotation's origin
0229      * @since 4.10
0230      * @see setRotationOrigin()
0231      */
0232     QVector3D rotationOrigin() const;
0233     /**
0234      * Sets the rotation axis.
0235      * Set a component to 1.0 to rotate around this axis and to 0.0 to disable rotation around the
0236      * axis.
0237      * @param axis A vector holding information on which axis to rotate
0238      * @since 4.10
0239      * @see rotationAxis()
0240      */
0241     void setRotationAxis(const QVector3D &axis);
0242     /**
0243      * Sets the rotation axis.
0244      * Overloaded method for convenience.
0245      * @param axis The axis around which should be rotated.
0246      * @since 4.10
0247      * @see rotationAxis()
0248      */
0249     void setRotationAxis(Qt::Axis axis);
0250     /**
0251      * The current rotation axis.
0252      * By default the rotation is (0/0/1) which means a rotation around the z axis.
0253      * @returns The current rotation axis.
0254      * @since 4.10
0255      * @see setRotationAxis
0256      */
0257     QVector3D rotationAxis() const;
0258 
0259     /**
0260      * Returns the corresponding transform matrix.
0261      *
0262      * The transform matrix is converted to device coordinates using the
0263      * supplied deviceScale.
0264      */
0265     QMatrix4x4 toMatrix(qreal deviceScale) const;
0266 
0267 protected:
0268     PaintData();
0269     PaintData(const PaintData &other);
0270 
0271 private:
0272     const std::unique_ptr<PaintDataPrivate> d;
0273 };
0274 
0275 class KWIN_EXPORT WindowPrePaintData
0276 {
0277 public:
0278     int mask;
0279     /**
0280      * Region that will be painted, in screen coordinates.
0281      */
0282     QRegion paint;
0283     /**
0284      * Region indicating the opaque content. It can be used to avoid painting
0285      * windows occluded by the opaque region.
0286      */
0287     QRegion opaque;
0288     /**
0289      * Simple helper that sets data to say the window will be painted as non-opaque.
0290      * Takes also care of changing the regions.
0291      */
0292     void setTranslucent();
0293     /**
0294      * Helper to mark that this window will be transformed
0295      */
0296     void setTransformed();
0297 };
0298 
0299 class KWIN_EXPORT WindowPaintData : public PaintData
0300 {
0301 public:
0302     WindowPaintData();
0303     explicit WindowPaintData(const QMatrix4x4 &projectionMatrix);
0304     WindowPaintData(const WindowPaintData &other);
0305     ~WindowPaintData() override;
0306     /**
0307      * Scales the window by @p scale factor.
0308      * Multiplies all three components by the given factor.
0309      * @since 4.10
0310      */
0311     WindowPaintData &operator*=(qreal scale);
0312     /**
0313      * Scales the window by @p scale factor.
0314      * Performs a component wise multiplication on x and y components.
0315      * @since 4.10
0316      */
0317     WindowPaintData &operator*=(const QVector2D &scale);
0318     /**
0319      * Scales the window by @p scale factor.
0320      * Performs a component wise multiplication.
0321      * @since 4.10
0322      */
0323     WindowPaintData &operator*=(const QVector3D &scale);
0324     /**
0325      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
0326      * @since 4.10
0327      */
0328     WindowPaintData &operator+=(const QPointF &translation);
0329     /**
0330      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
0331      * Overloaded method for convenience.
0332      * @since 4.10
0333      */
0334     WindowPaintData &operator+=(const QPoint &translation);
0335     /**
0336      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
0337      * Overloaded method for convenience.
0338      * @since 4.10
0339      */
0340     WindowPaintData &operator+=(const QVector2D &translation);
0341     /**
0342      * Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
0343      * Overloaded method for convenience.
0344      * @since 4.10
0345      */
0346     WindowPaintData &operator+=(const QVector3D &translation);
0347     /**
0348      * Window opacity, in range 0 = transparent to 1 = fully opaque
0349      * @see setOpacity
0350      * @since 4.10
0351      */
0352     qreal opacity() const;
0353     /**
0354      * Sets the window opacity to the new @p opacity.
0355      * If you want to modify the existing opacity level consider using multiplyOpacity.
0356      * @param opacity The new opacity level
0357      * @since 4.10
0358      */
0359     void setOpacity(qreal opacity);
0360     /**
0361      * Multiplies the current opacity with the @p factor.
0362      * @param factor Factor with which the opacity should be multiplied
0363      * @return New opacity level
0364      * @since 4.10
0365      */
0366     qreal multiplyOpacity(qreal factor);
0367     /**
0368      * Saturation of the window, in range [0; 1]
0369      * 1 means that the window is unchanged, 0 means that it's completely
0370      *  unsaturated (greyscale). 0.5 would make the colors less intense,
0371      *  but not completely grey
0372      * Use EffectsHandler::saturationSupported() to find out whether saturation
0373      * is supported by the system, otherwise this value has no effect.
0374      * @return The current saturation
0375      * @see setSaturation()
0376      * @since 4.10
0377      */
0378     qreal saturation() const;
0379     /**
0380      * Sets the window saturation level to @p saturation.
0381      * If you want to modify the existing saturation level consider using multiplySaturation.
0382      * @param saturation The new saturation level
0383      * @since 4.10
0384      */
0385     void setSaturation(qreal saturation) const;
0386     /**
0387      * Multiplies the current saturation with @p factor.
0388      * @param factor with which the saturation should be multiplied
0389      * @return New saturation level
0390      * @since 4.10
0391      */
0392     qreal multiplySaturation(qreal factor);
0393     /**
0394      * Brightness of the window, in range [0; 1]
0395      * 1 means that the window is unchanged, 0 means that it's completely
0396      * black. 0.5 would make it 50% darker than usual
0397      */
0398     qreal brightness() const;
0399     /**
0400      * Sets the window brightness level to @p brightness.
0401      * If you want to modify the existing brightness level consider using multiplyBrightness.
0402      * @param brightness The new brightness level
0403      */
0404     void setBrightness(qreal brightness);
0405     /**
0406      * Multiplies the current brightness level with @p factor.
0407      * @param factor with which the brightness should be multiplied.
0408      * @return New brightness level
0409      * @since 4.10
0410      */
0411     qreal multiplyBrightness(qreal factor);
0412     /**
0413      * The screen number for which the painting should be done.
0414      * This affects color correction (different screens may need different
0415      * color correction lookup tables because they have different ICC profiles).
0416      * @return screen for which painting should be done
0417      */
0418     int screen() const;
0419     /**
0420      * @param screen New screen number
0421      * A value less than 0 will indicate that a default profile should be done.
0422      */
0423     void setScreen(int screen) const;
0424     /**
0425      * @brief Sets the cross fading @p factor to fade over with previously sized window.
0426      * If @c 1.0 only the current window is used, if @c 0.0 only the previous window is used.
0427      *
0428      * By default only the current window is used. This factor can only make any visual difference
0429      * if the previous window get referenced.
0430      *
0431      * @param factor The cross fade factor between @c 0.0 (previous window) and @c 1.0 (current window)
0432      * @see crossFadeProgress
0433      */
0434     void setCrossFadeProgress(qreal factor);
0435     /**
0436      * @see setCrossFadeProgress
0437      */
0438     qreal crossFadeProgress() const;
0439 
0440     /**
0441      * Sets the projection matrix that will be used when painting the window.
0442      *
0443      * The default projection matrix can be overridden by setting this matrix
0444      */
0445     void setProjectionMatrix(const QMatrix4x4 &matrix);
0446 
0447     /**
0448      * Returns the current projection matrix.
0449      */
0450     QMatrix4x4 projectionMatrix() const;
0451 
0452     /**
0453      * Returns a reference to the projection matrix.
0454      */
0455     QMatrix4x4 &rprojectionMatrix();
0456 
0457 private:
0458     const std::unique_ptr<WindowPaintDataPrivate> d;
0459 };
0460 
0461 class KWIN_EXPORT ScreenPrePaintData
0462 {
0463 public:
0464     int mask;
0465     QRegion paint;
0466     Output *screen = nullptr;
0467 };
0468 
0469 /**
0470  * @short Base class for all KWin effects
0471  *
0472  * This is the base class for all effects. By reimplementing virtual methods
0473  *  of this class, you can customize how the windows are painted.
0474  *
0475  * The virtual methods are used for painting and need to be implemented for
0476  * custom painting.
0477  *
0478  * In order to react to state changes (e.g. a window gets closed) the effect
0479  * should provide slots for the signals emitted by the EffectsHandler.
0480  *
0481  * @section Chaining
0482  * Most methods of this class are called in chain style. This means that when
0483  *  effects A and B area active then first e.g. A::paintWindow() is called and
0484  *  then from within that method B::paintWindow() is called (although
0485  *  indirectly). To achieve this, you need to make sure to call corresponding
0486  *  method in EffectsHandler class from each such method (using @ref effects
0487  *  pointer):
0488  * @code
0489  *  void MyEffect::postPaintScreen()
0490  *  {
0491  *      // Do your own processing here
0492  *      ...
0493  *      // Call corresponding EffectsHandler method
0494  *      effects->postPaintScreen();
0495  *  }
0496  * @endcode
0497  *
0498  * @section Effectsptr Effects pointer
0499  * @ref effects pointer points to the global EffectsHandler object that you can
0500  *  use to interact with the windows.
0501  *
0502  * @section painting Painting stages
0503  * Painting of windows is done in three stages:
0504  * @li First, the prepaint pass.<br>
0505  *  Here you can specify how the windows will be painted, e.g. that they will
0506  *  be translucent and transformed.
0507  * @li Second, the paint pass.<br>
0508  *  Here the actual painting takes place. You can change attributes such as
0509  *  opacity of windows as well as apply transformations to them. You can also
0510  *  paint something onto the screen yourself.
0511  * @li Finally, the postpaint pass.<br>
0512  *  Here you can mark windows, part of windows or even the entire screen for
0513  *  repainting to create animations.
0514  *
0515  * For each stage there are *Screen() and *Window() methods. The window method
0516  *  is called for every window while the screen method is usually called just
0517  *  once.
0518  *
0519  * @section OpenGL
0520  * Effects can use OpenGL if EffectsHandler::isOpenGLCompositing() returns @c true.
0521  * The OpenGL context may not always be current when code inside the effect is
0522  * executed. The framework ensures that the OpenGL context is current when the Effect
0523  * gets created, destroyed or reconfigured and during the painting stages. All virtual
0524  * methods which have the OpenGL context current are documented.
0525  *
0526  * If OpenGL code is going to be executed outside the painting stages, e.g. in reaction
0527  * to a global shortcut, it is the task of the Effect to make the OpenGL context current:
0528  * @code
0529  * effects->makeOpenGLContextCurrent();
0530  * @endcode
0531  *
0532  * There is in general no need to call the matching doneCurrent method.
0533  */
0534 class KWIN_EXPORT Effect : public QObject
0535 {
0536     Q_OBJECT
0537 public:
0538     /** Flags controlling how painting is done. */
0539     // TODO: is that ok here?
0540     enum {
0541         /**
0542          * Window (or at least part of it) will be painted opaque.
0543          */
0544         PAINT_WINDOW_OPAQUE = 1 << 0,
0545         /**
0546          * Window (or at least part of it) will be painted translucent.
0547          */
0548         PAINT_WINDOW_TRANSLUCENT = 1 << 1,
0549         /**
0550          * Window will be painted with transformed geometry.
0551          */
0552         PAINT_WINDOW_TRANSFORMED = 1 << 2,
0553         /**
0554          * Paint only a region of the screen (can be optimized, cannot
0555          * be used together with TRANSFORMED flags).
0556          */
0557         PAINT_SCREEN_REGION = 1 << 3,
0558         /**
0559          * The whole screen will be painted with transformed geometry.
0560          * Forces the entire screen to be painted.
0561          */
0562         PAINT_SCREEN_TRANSFORMED = 1 << 4,
0563         /**
0564          * At least one window will be painted with transformed geometry.
0565          * Forces the entire screen to be painted.
0566          */
0567         PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
0568         /**
0569          * Clear whole background as the very first step, without optimizing it
0570          */
0571         PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
0572     };
0573 
0574     enum Feature {
0575         Nothing = 0,
0576         ScreenInversion,
0577         Blur,
0578         Contrast,
0579         HighlightWindows
0580     };
0581 
0582     /**
0583      * Constructs new Effect object.
0584      *
0585      * In OpenGL based compositing, the frameworks ensures that the context is current
0586      * when the Effect is constructed.
0587      */
0588     Effect(QObject *parent = nullptr);
0589     /**
0590      * Destructs the Effect object.
0591      *
0592      * In OpenGL based compositing, the frameworks ensures that the context is current
0593      * when the Effect is destroyed.
0594      */
0595     ~Effect() override;
0596 
0597     /**
0598      * Flags describing which parts of configuration have changed.
0599      */
0600     enum ReconfigureFlag {
0601         ReconfigureAll = 1 << 0 /// Everything needs to be reconfigured.
0602     };
0603     Q_DECLARE_FLAGS(ReconfigureFlags, ReconfigureFlag)
0604 
0605     /**
0606      * Called when configuration changes (either the effect's or KWin's global).
0607      *
0608      * In OpenGL based compositing, the frameworks ensures that the context is current
0609      * when the Effect is reconfigured. If this method is called from within the Effect it is
0610      * required to ensure that the context is current if the implementation does OpenGL calls.
0611      */
0612     virtual void reconfigure(ReconfigureFlags flags);
0613 
0614     /**
0615      * Called before starting to paint the screen.
0616      * In this method you can:
0617      * @li set whether the windows or the entire screen will be transformed
0618      * @li change the region of the screen that will be painted
0619      * @li do various housekeeping tasks such as initing your effect's variables
0620             for the upcoming paint pass or updating animation's progress
0621      *
0622      * @a presentTime specifies the expected monotonic time when the rendered frame
0623      * will be displayed on the screen.
0624     */
0625     virtual void prePaintScreen(ScreenPrePaintData &data,
0626                                 std::chrono::milliseconds presentTime);
0627     /**
0628      * In this method you can:
0629      * @li paint something on top of the windows (by painting after calling
0630      *      effects->paintScreen())
0631      * @li paint multiple desktops and/or multiple copies of the same desktop
0632      *      by calling effects->paintScreen() multiple times
0633      *
0634      * In OpenGL based compositing, the frameworks ensures that the context is current
0635      * when this method is invoked.
0636      */
0637     virtual void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen);
0638     /**
0639      * Called after all the painting has been finished.
0640      * In this method you can:
0641      * @li schedule next repaint in case of animations
0642      * You shouldn't paint anything here.
0643      *
0644      * In OpenGL based compositing, the frameworks ensures that the context is current
0645      * when this method is invoked.
0646      */
0647     virtual void postPaintScreen();
0648 
0649     /**
0650      * Called for every window before the actual paint pass
0651      * In this method you can:
0652      * @li enable or disable painting of the window (e.g. enable paiting of minimized window)
0653      * @li set window to be painted with translucency
0654      * @li set window to be transformed
0655      * @li request the window to be divided into multiple parts
0656      *
0657      * In OpenGL based compositing, the frameworks ensures that the context is current
0658      * when this method is invoked.
0659      *
0660      * @a presentTime specifies the expected monotonic time when the rendered frame
0661      * will be displayed on the screen.
0662      */
0663     virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
0664                                 std::chrono::milliseconds presentTime);
0665     /**
0666      * This is the main method for painting windows.
0667      * In this method you can:
0668      * @li do various transformations
0669      * @li change opacity of the window
0670      * @li change brightness and/or saturation, if it's supported
0671      *
0672      * In OpenGL based compositing, the frameworks ensures that the context is current
0673      * when this method is invoked.
0674      */
0675     virtual void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data);
0676     /**
0677      * Called for every window after all painting has been finished.
0678      * In this method you can:
0679      * @li schedule next repaint for individual window(s) in case of animations
0680      * You shouldn't paint anything here.
0681      *
0682      * In OpenGL based compositing, the frameworks ensures that the context is current
0683      * when this method is invoked.
0684      */
0685     virtual void postPaintWindow(EffectWindow *w);
0686 
0687     /**
0688      * Called on Transparent resizes.
0689      * return true if your effect substitutes questioned feature
0690      */
0691     virtual bool provides(Feature);
0692 
0693     /**
0694      * Performs the @p feature with the @p arguments.
0695      *
0696      * This allows to have specific protocols between KWin core and an Effect.
0697      *
0698      * The method is supposed to return @c true if it performed the features,
0699      * @c false otherwise.
0700      *
0701      * The default implementation returns @c false.
0702      * @since 5.8
0703      */
0704     virtual bool perform(Feature feature, const QVariantList &arguments);
0705 
0706     /**
0707      * Can be called to draw multiple copies (e.g. thumbnails) of a window.
0708      * You can change window's opacity/brightness/etc here, but you can't
0709      *  do any transformations.
0710      *
0711      * In OpenGL based compositing, the frameworks ensures that the context is current
0712      * when this method is invoked.
0713      */
0714     virtual void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
0715 
0716     virtual void windowInputMouseEvent(QEvent *e);
0717     virtual void grabbedKeyboardEvent(QKeyEvent *e);
0718 
0719     /**
0720      * Overwrite this method to indicate whether your effect will be doing something in
0721      * the next frame to be rendered. If the method returns @c false the effect will be
0722      * excluded from the chained methods in the next rendered frame.
0723      *
0724      * This method is called always directly before the paint loop begins. So it is totally
0725      * fine to e.g. react on a window event, issue a repaint to trigger an animation and
0726      * change a flag to indicate that this method returns @c true.
0727      *
0728      * As the method is called each frame, you should not perform complex calculations.
0729      * Best use just a boolean flag.
0730      *
0731      * The default implementation of this method returns @c true.
0732      * @since 4.8
0733      */
0734     virtual bool isActive() const;
0735 
0736     /**
0737      * Reimplement this method to provide online debugging.
0738      * This could be as trivial as printing specific detail information about the effect state
0739      * but could also be used to move the effect in and out of a special debug modes, clear bogus
0740      * data, etc.
0741      * Notice that the functions is const by intent! Whenever you alter the state of the object
0742      * due to random user input, you should do so with greatest care, hence const_cast<> your
0743      * object - signalling "let me alone, i know what i'm doing"
0744      * @param parameter A freeform string user input for your effect to interpret.
0745      * @since 4.11
0746      */
0747     virtual QString debug(const QString &parameter) const;
0748 
0749     /**
0750      * Reimplement this method to indicate where in the Effect chain the Effect should be placed.
0751      *
0752      * A low number indicates early chain position, thus before other Effects got called, a high
0753      * number indicates a late position. The returned number should be in the interval [0, 100].
0754      * The default value is 0.
0755      *
0756      * In KWin4 this information was provided in the Effect's desktop file as property
0757      * X-KDE-Ordering. In the case of Scripted Effects this property is still used.
0758      *
0759      * @since 5.0
0760      */
0761     virtual int requestedEffectChainPosition() const;
0762 
0763     /**
0764      * A touch point was pressed.
0765      *
0766      * If the effect wants to exclusively use the touch event it should return @c true.
0767      * If @c false is returned the touch event is passed to further effects.
0768      *
0769      * In general an Effect should only return @c true if it is the exclusive effect getting
0770      * input events. E.g. has grabbed mouse events.
0771      *
0772      * Default implementation returns @c false.
0773      *
0774      * @param id The unique id of the touch point
0775      * @param pos The position of the touch point in global coordinates
0776      * @param time Timestamp
0777      *
0778      * @see touchMotion
0779      * @see touchUp
0780      * @since 5.8
0781      */
0782     virtual bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0783     /**
0784      * A touch point moved.
0785      *
0786      * If the effect wants to exclusively use the touch event it should return @c true.
0787      * If @c false is returned the touch event is passed to further effects.
0788      *
0789      * In general an Effect should only return @c true if it is the exclusive effect getting
0790      * input events. E.g. has grabbed mouse events.
0791      *
0792      * Default implementation returns @c false.
0793      *
0794      * @param id The unique id of the touch point
0795      * @param pos The position of the touch point in global coordinates
0796      * @param time Timestamp
0797      *
0798      * @see touchDown
0799      * @see touchUp
0800      * @since 5.8
0801      */
0802     virtual bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time);
0803     /**
0804      * A touch point was released.
0805      *
0806      * If the effect wants to exclusively use the touch event it should return @c true.
0807      * If @c false is returned the touch event is passed to further effects.
0808      *
0809      * In general an Effect should only return @c true if it is the exclusive effect getting
0810      * input events. E.g. has grabbed mouse events.
0811      *
0812      * Default implementation returns @c false.
0813      *
0814      * @param id The unique id of the touch point
0815      * @param time Timestamp
0816      *
0817      * @see touchDown
0818      * @see touchMotion
0819      * @since 5.8
0820      */
0821     virtual bool touchUp(qint32 id, std::chrono::microseconds time);
0822 
0823     /**
0824      * There has been an event from a drawing tablet tool
0825      *
0826      * i.e. a pen and the likes.
0827      *
0828      * @param event the event information
0829      * @see QTabletEvent
0830      *
0831      * @since 5.25
0832      */
0833     virtual bool tabletToolEvent(QTabletEvent *event);
0834 
0835     /**
0836      * There has been an event from a button on a drawing tablet tool
0837      *
0838      * @param button which button
0839      * @param pressed true if pressed, false when released
0840      * @param tabletToolId the identifier of the tool id
0841      *
0842      * @since 5.25
0843      */
0844     virtual bool tabletToolButtonEvent(uint button, bool pressed, quint64 tabletToolId);
0845 
0846     /**
0847      * There has been an event from a button on a drawing tablet pad
0848      *
0849      * @param button which button
0850      * @param pressed true if pressed, false when released
0851      * @param tabletPadId the identifier of the tool id
0852      *
0853      * @since 5.25
0854      */
0855     virtual bool tabletPadButtonEvent(uint button, bool pressed, void *tabletPadId);
0856 
0857     /**
0858      * There has been an event from a input strip on a drawing tablet pad
0859      *
0860      * @param number which strip
0861      * @param position the value within the strip that was selected
0862      * @param isFinger if it was activated with a finger
0863      * @param tabletPadId the identifier of the tool id
0864      *
0865      * @since 5.25
0866      */
0867     virtual bool tabletPadStripEvent(int number, int position, bool isFinger, void *tabletPadId);
0868 
0869     /**
0870      * There has been an event from a input ring on a drawing tablet pad
0871      *
0872      * @param number which ring
0873      * @param position the value within the ring that was selected
0874      * @param isFinger if it was activated with a finger
0875      * @param tabletPadId the identifier of the tool id
0876      *
0877      * @since 5.25
0878      */
0879     virtual bool tabletPadRingEvent(int number, int position, bool isFinger, void *tabletPadId);
0880 
0881     static QPointF cursorPos();
0882 
0883     /**
0884      * Read animation time from the configuration and possibly adjust using animationTimeFactor().
0885      * The configuration value in the effect should also have special value 'default' (set using
0886      * QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted
0887      * using the global animation speed, otherwise the exact time configured is returned.
0888      * @param cfg configuration group to read value from
0889      * @param key configuration key to read value from
0890      * @param defaultTime default animation time in milliseconds
0891      */
0892     // return type is intentionally double so that one can divide using it without losing data
0893     static double animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime);
0894     /**
0895      * @overload Use this variant if the animation time is hardcoded and not configurable
0896      * in the effect itself.
0897      */
0898     static double animationTime(int defaultTime);
0899     /**
0900      * @overload Use this variant if animation time is provided through a KConfigXT generated class
0901      * having a property called "duration".
0902      */
0903     template<typename T>
0904     int animationTime(int defaultDuration);
0905     /**
0906      * Linearly interpolates between @p x and @p y.
0907      *
0908      * Returns @p x when @p a = 0; returns @p y when @p a = 1.
0909      */
0910     static double interpolate(double x, double y, double a)
0911     {
0912         return x * (1 - a) + y * a;
0913     }
0914     /** Helper to set WindowPaintData and QRegion to necessary transformations so that
0915      * a following drawWindow() would put the window at the requested geometry (useful for thumbnails)
0916      */
0917     static void setPositionTransformations(WindowPaintData &data, QRect &region, EffectWindow *w,
0918                                            const QRect &r, Qt::AspectRatioMode aspect);
0919 
0920     /**
0921      * overwrite this method to return false if your effect does not need to be drawn over opaque fullscreen windows
0922      */
0923     virtual bool blocksDirectScanout() const;
0924 
0925 public Q_SLOTS:
0926     virtual bool borderActivated(ElectricBorder border);
0927 };
0928 
0929 template<typename T>
0930 int Effect::animationTime(int defaultDuration)
0931 {
0932     return animationTime(T::duration() != 0 ? T::duration() : defaultDuration);
0933 }
0934 
0935 /**
0936  * Prefer the KWIN_EFFECT_FACTORY macros.
0937  */
0938 class KWIN_EXPORT EffectPluginFactory : public KPluginFactory
0939 {
0940     Q_OBJECT
0941 public:
0942     EffectPluginFactory();
0943     ~EffectPluginFactory() override;
0944     /**
0945      * Returns whether the Effect is supported.
0946      *
0947      * An Effect can implement this method to determine at runtime whether the Effect is supported.
0948      *
0949      * If the current compositing backend is not supported it should return @c false.
0950      *
0951      * This method is optional, by default @c true is returned.
0952      */
0953     virtual bool isSupported() const;
0954     /**
0955      * Returns whether the Effect should get enabled by default.
0956      *
0957      * This function provides a way for an effect to override the default at runtime,
0958      * e.g. based on the capabilities of the hardware.
0959      *
0960      * This method is optional; the effect doesn't have to provide it.
0961      *
0962      * Note that this function is only called if the supported() function returns true,
0963      * and if X-KDE-PluginInfo-EnabledByDefault is set to true in the .desktop file.
0964      *
0965      * This method is optional, by default @c true is returned.
0966      */
0967     virtual bool enabledByDefault() const;
0968     /**
0969      * This method returns the created Effect.
0970      */
0971     virtual KWin::Effect *createEffect() const = 0;
0972 };
0973 
0974 #define EffectPluginFactory_iid "org.kde.kwin.EffectPluginFactory" KWIN_PLUGIN_VERSION_STRING
0975 #define KWIN_PLUGIN_FACTORY_NAME KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME
0976 
0977 /**
0978  * Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.
0979  *
0980  * If the Effect to be created does not need the isSupported or enabledByDefault methods prefer
0981  * the simplified KWIN_EFFECT_FACTORY, KWIN_EFFECT_FACTORY_SUPPORTED or KWIN_EFFECT_FACTORY_ENABLED
0982  * macros which create an EffectPluginFactory with a useable default value.
0983  *
0984  * This API is not providing binary compatibility and thus the effect plugin must be compiled against
0985  * the same kwineffects library version as KWin.
0986  *
0987  * @param factoryName The name to be used for the EffectPluginFactory
0988  * @param className The class name of the Effect sub class which is to be created by the factory
0989  * @param jsonFile Name of the json file to be compiled into the plugin as metadata
0990  * @param supported Source code to go into the isSupported() method, must return a boolean
0991  * @param enabled Source code to go into the enabledByDefault() method, must return a boolean
0992  */
0993 #define KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, supported, enabled) \
0994     class KWIN_PLUGIN_FACTORY_NAME : public KWin::EffectPluginFactory                  \
0995     {                                                                                  \
0996         Q_OBJECT                                                                       \
0997         Q_PLUGIN_METADATA(IID EffectPluginFactory_iid FILE jsonFile)                   \
0998         Q_INTERFACES(KPluginFactory)                                                   \
0999     public:                                                                            \
1000         explicit KWIN_PLUGIN_FACTORY_NAME()                                            \
1001         {                                                                              \
1002         }                                                                              \
1003         ~KWIN_PLUGIN_FACTORY_NAME()                                                    \
1004         {                                                                              \
1005         }                                                                              \
1006         bool isSupported() const override                                              \
1007         {                                                                              \
1008             supported                                                                  \
1009         }                                                                              \
1010         bool enabledByDefault() const override{                                        \
1011             enabled} KWin::Effect *createEffect() const override                       \
1012         {                                                                              \
1013             return new className();                                                    \
1014         }                                                                              \
1015     };
1016 
1017 #define KWIN_EFFECT_FACTORY_ENABLED(className, jsonFile, enabled) \
1018     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, return true;, enabled)
1019 
1020 #define KWIN_EFFECT_FACTORY_SUPPORTED(className, jsonFile, supported) \
1021     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, supported, return true;)
1022 
1023 #define KWIN_EFFECT_FACTORY(className, jsonFile) \
1024     KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED(className, jsonFile, return true;, return true;)
1025 
1026 } // namespace KWin