1 /* 2 KWin - the KDE window manager 3 This file is part of the KDE project. 4 5 SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org> 6 SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org> 7 8 SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #ifndef KWIN_SCRIPTEDEFFECT_H 12 #define KWIN_SCRIPTEDEFFECT_H 13 14 #include <kwinanimationeffect.h> 15 16 #include <QJSEngine> 17 #include <QJSValue> 18 19 class KConfigLoader; 20 class KPluginMetaData; 21 22 namespace KWin 23 { 24 class KWIN_EXPORT ScriptedEffect : public KWin::AnimationEffect 25 { 26 Q_OBJECT 27 Q_ENUMS(DataRole) 28 Q_ENUMS(Qt::Axis) 29 Q_ENUMS(Anchor) 30 Q_ENUMS(MetaType) 31 Q_ENUMS(EasingCurve) 32 Q_ENUMS(SessionState) 33 /** 34 * The plugin ID of the effect 35 */ 36 Q_PROPERTY(QString pluginId READ pluginId CONSTANT) 37 /** 38 * True if we are the active fullscreen effect 39 */ 40 Q_PROPERTY(bool isActiveFullScreenEffect READ isActiveFullScreenEffect NOTIFY isActiveFullScreenEffectChanged) 41 public: 42 // copied from kwineffects.h 43 enum DataRole { 44 // Grab roles are used to force all other animations to ignore the window. 45 // The value of the data is set to the Effect's `this` value. 46 WindowAddedGrabRole = 1, 47 WindowClosedGrabRole, 48 WindowMinimizedGrabRole, 49 WindowUnminimizedGrabRole, 50 WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows, 51 WindowBlurBehindRole, ///< For single windows to blur behind 52 WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast, 53 WindowBackgroundContrastRole, ///< For single windows to enable Background contrast 54 LanczosCacheRole 55 }; 56 enum EasingCurve { 57 GaussianCurve = 128 58 }; scriptFile()59 const QString &scriptFile() const { 60 return m_scriptFile; 61 } 62 void reconfigure(ReconfigureFlags flags) override; requestedEffectChainPosition()63 int requestedEffectChainPosition() const override { 64 return m_chainPosition; 65 } 66 QString activeConfig() const; 67 void setActiveConfig(const QString &name); 68 static ScriptedEffect *create(const QString &effectName, const QString &pathToScript, int chainPosition); 69 static ScriptedEffect *create(const KPluginMetaData &effect); 70 static bool supported(); 71 ~ScriptedEffect() override; 72 /** 73 * Whether another effect has grabbed the @p w with the given @p grabRole. 74 * @param w The window to check 75 * @param grabRole The grab role to check 76 * @returns @c true if another window has grabbed the effect, @c false otherwise 77 */ 78 Q_SCRIPTABLE bool isGrabbed(KWin::EffectWindow *w, DataRole grabRole); 79 80 /** 81 * Grabs the window with the specified role. 82 * 83 * @param w The window. 84 * @param grabRole The grab role. 85 * @param force By default, if the window is already grabbed by another effect, 86 * then that window won't be grabbed by effect that called this method. If you 87 * would like to grab a window even if it's grabbed by another effect, then 88 * pass @c true. 89 * @returns @c true if the window was grabbed successfully, otherwise @c false. 90 */ 91 Q_SCRIPTABLE bool grab(KWin::EffectWindow *w, DataRole grabRole, bool force = false); 92 93 /** 94 * Ungrabs the window with the specified role. 95 * 96 * @param w The window. 97 * @param grabRole The grab role. 98 * @returns @c true if the window was ungrabbed successfully, otherwise @c false. 99 */ 100 Q_SCRIPTABLE bool ungrab(KWin::EffectWindow *w, DataRole grabRole); 101 102 /** 103 * Reads the value from the configuration data for the given key. 104 * @param key The key to search for 105 * @param defaultValue The value to return if the key is not found 106 * @returns The config value if present 107 */ 108 Q_SCRIPTABLE QJSValue readConfig(const QString &key, const QJSValue &defaultValue = QJSValue()); 109 110 Q_SCRIPTABLE int displayWidth() const; 111 Q_SCRIPTABLE int displayHeight() const; 112 Q_SCRIPTABLE int animationTime(int defaultTime) const; 113 114 Q_SCRIPTABLE void registerShortcut(const QString &objectName, const QString &text, 115 const QString &keySequence, const QJSValue &callback); 116 Q_SCRIPTABLE bool registerScreenEdge(int edge, const QJSValue &callback); 117 Q_SCRIPTABLE bool unregisterScreenEdge(int edge); 118 Q_SCRIPTABLE bool registerTouchScreenEdge(int edge, const QJSValue &callback); 119 Q_SCRIPTABLE bool unregisterTouchScreenEdge(int edge); 120 121 Q_SCRIPTABLE quint64 animate(KWin::EffectWindow *window, Attribute attribute, int ms, 122 const QJSValue &to, const QJSValue &from = QJSValue(), 123 uint metaData = 0, int curve = QEasingCurve::Linear, int delay = 0, 124 bool fullScreen = false, bool keepAlive = true); 125 Q_SCRIPTABLE QJSValue animate(const QJSValue &object); 126 127 Q_SCRIPTABLE quint64 set(KWin::EffectWindow *window, Attribute attribute, int ms, 128 const QJSValue &to, const QJSValue &from = QJSValue(), 129 uint metaData = 0, int curve = QEasingCurve::Linear, int delay = 0, 130 bool fullScreen = false, bool keepAlive = true); 131 Q_SCRIPTABLE QJSValue set(const QJSValue &object); 132 133 Q_SCRIPTABLE bool retarget(quint64 animationId, const QJSValue &newTarget, 134 int newRemainingTime = -1); 135 Q_SCRIPTABLE bool retarget(const QList<quint64> &animationIds, const QJSValue &newTarget, 136 int newRemainingTime = -1); 137 138 Q_SCRIPTABLE bool redirect(quint64 animationId, Direction direction, 139 TerminationFlags terminationFlags = TerminateAtSource); 140 Q_SCRIPTABLE bool redirect(const QList<quint64> &animationIds, Direction direction, 141 TerminationFlags terminationFlags = TerminateAtSource); 142 143 Q_SCRIPTABLE bool complete(quint64 animationId); 144 Q_SCRIPTABLE bool complete(const QList<quint64> &animationIds); 145 146 Q_SCRIPTABLE bool cancel(quint64 animationId); 147 Q_SCRIPTABLE bool cancel(const QList<quint64> &animationIds); 148 screenEdgeCallbacks()149 QHash<int, QJSValueList> &screenEdgeCallbacks() { 150 return m_screenEdgeCallbacks; 151 } 152 153 QString pluginId() const; 154 bool isActiveFullScreenEffect() const; 155 156 public Q_SLOTS: 157 bool borderActivated(ElectricBorder border) override; 158 159 Q_SIGNALS: 160 /** 161 * Signal emitted whenever the effect's config changed. 162 */ 163 void configChanged(); 164 void animationEnded(KWin::EffectWindow *w, quint64 animationId); 165 void isActiveFullScreenEffectChanged(); 166 167 protected: 168 ScriptedEffect(); 169 QJSEngine *engine() const; 170 bool init(const QString &effectName, const QString &pathToScript); 171 void animationEnded(KWin::EffectWindow *w, Attribute a, uint meta) override; 172 173 private: 174 enum class AnimationType { 175 Animate, 176 Set 177 }; 178 179 QJSValue animate_helper(const QJSValue &object, AnimationType animationType); 180 181 QJSEngine *m_engine; 182 QString m_effectName; 183 QString m_scriptFile; 184 QHash<int, QJSValueList> m_screenEdgeCallbacks; 185 KConfigLoader *m_config; 186 int m_chainPosition; 187 QHash<int, QAction*> m_touchScreenEdgeCallbacks; 188 Effect *m_activeFullScreenEffect = nullptr; 189 }; 190 191 } 192 193 #endif // KWIN_SCRIPTEDEFFECT_H 194