File indexing completed on 2025-02-16 05:03:08
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 ®ion, 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 ®ion, 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 ¶meter) 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 ®ion, 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