diff --git a/effects.cpp b/effects.cpp
index 5efcfd2a0e..bb382e95a0 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -1638,11 +1638,23 @@ QString EffectsHandlerImpl::supportInformation(const QString &name) const
return QString();
}
+
bool EffectsHandlerImpl::isScreenLocked() const
{
return m_screenLockerWatcher->isLocked();
}
+QString EffectsHandlerImpl::debug(const QString& name, const QString& parameter) const
+{
+ QString internalName = name.startsWith("kwin4_effect_") ? name : "kwin4_effect_" + name;
+ for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
+ if ((*it).first == internalName) {
+ return it->second->debug(parameter);
+ }
+ }
+ return QString();
+}
+
//****************************************
// EffectWindowImpl
//****************************************
diff --git a/effects.h b/effects.h
index a513665011..2cd4c43021 100644
--- a/effects.h
+++ b/effects.h
@@ -193,6 +193,7 @@ public Q_SLOTS:
Q_SCRIPTABLE void unloadEffect(const QString& name);
Q_SCRIPTABLE bool isEffectLoaded(const QString& name) const;
Q_SCRIPTABLE QString supportInformation(const QString& name) const;
+ Q_SCRIPTABLE QString debug(const QString& name, const QString& parameter = QString()) const;
protected Q_SLOTS:
void slotDesktopChanged(int old, KWin::Client *withClient);
diff --git a/libkwineffects/anidata.cpp b/libkwineffects/anidata.cpp
index cc0d872e7f..09635b03d6 100644
--- a/libkwineffects/anidata.cpp
+++ b/libkwineffects/anidata.cpp
@@ -22,6 +22,12 @@ along with this program. If not, see .
#include
+QDebug operator<<(QDebug dbg, const KWin::AniData &a)
+{
+ dbg.nospace() << a.debugInfo();
+ return dbg.space();
+}
+
using namespace KWin;
static int Gaussian = 46;
@@ -158,6 +164,22 @@ AniData::AniData(const QString &str) // format: WindowMask:Attribute:Meta:Durati
}
}
+static QString attributeString(KWin::AnimationEffect::Attribute attribute)
+{
+ switch (attribute) {
+ case KWin::AnimationEffect::Opacity: return "Opacity";
+ case KWin::AnimationEffect::Brightness: return "Brightness";
+ case KWin::AnimationEffect::Saturation: return "Saturation";
+ case KWin::AnimationEffect::Scale: return "Scale";
+ case KWin::AnimationEffect::Translation: return "Translation";
+ case KWin::AnimationEffect::Rotation: return "Rotation";
+ case KWin::AnimationEffect::Position: return "Position";
+ case KWin::AnimationEffect::Size: return "Size";
+ case KWin::AnimationEffect::Clip: return "Clip";
+ default: return " ";
+ }
+}
+
QList AniData::list(const QString &str)
{
QList newList;
@@ -172,21 +194,20 @@ QList AniData::list(const QString &str)
QString AniData::toString() const
{
- QString ret = QString::number((uint)windowType) + ':';
- switch (attribute) {
- case AnimationEffect::Opacity: ret += "Opacity:"; break;
- case AnimationEffect::Brightness: ret += "Brightness:"; break;
- case AnimationEffect::Saturation: ret += "Saturation:"; break;
- case AnimationEffect::Scale: ret += "Scale:"; break;
- case AnimationEffect::Translation: ret += "Translation:"; break;
- case AnimationEffect::Rotation: ret += "Rotation:"; break;
- case AnimationEffect::Position: ret += "Position:"; break;
- case AnimationEffect::Size: ret += "Size:"; break;
- case AnimationEffect::Clip: ret += "Clip:"; break;
- default: ret += ':';
- }
- ret += QString::number(meta) + ':' + QString::number(duration) + ':' +
- to.toString() + ':' + QString::number(customCurve) + ':' +
- QString::number(time) + ':' + from.toString();
+ QString ret = QString::number((uint)windowType) + ':' + attributeString(attribute) + ':' +
+ QString::number(meta) + ':' + QString::number(duration) + ':' +
+ to.toString() + ':' + QString::number(customCurve) + ':' +
+ QString::number(time) + ':' + from.toString();
return ret;
}
+
+QString AniData::debugInfo() const
+{
+ return "Animation: " + attributeString(attribute) + '\n' +
+ " From: " + from.toString() + '\n' +
+ " To: " + to.toString() + '\n' +
+ " Started: " + QString::number(AnimationEffect::clock() - startTime) + "ms ago\n" +
+ " Duration: " + QString::number(duration) + "ms\n" +
+ " Passed: " + QString::number(time) + "ms\n" +
+ " Applying: " + QString::number(windowType) + '\n';
+}
diff --git a/libkwineffects/anidata_p.h b/libkwineffects/anidata_p.h
index b2c704912c..75c7f47fb9 100644
--- a/libkwineffects/anidata_p.h
+++ b/libkwineffects/anidata_p.h
@@ -40,6 +40,7 @@ public:
}
static QList list(const QString &str);
QString toString() const;
+ QString debugInfo() const;
AnimationEffect::Attribute attribute;
QEasingCurve curve;
int customCurve;
@@ -53,4 +54,6 @@ public:
} // namespace
+QDebug operator<<(QDebug dbg, const KWin::AniData &a);
+
#endif // ANIDATA_H
diff --git a/libkwineffects/kwinanimationeffect.cpp b/libkwineffects/kwinanimationeffect.cpp
index e8bc44e977..a411b19a61 100644
--- a/libkwineffects/kwinanimationeffect.cpp
+++ b/libkwineffects/kwinanimationeffect.cpp
@@ -23,8 +23,15 @@ along with this program. If not, see .
#include
#include
+#include
#include
+QDebug operator<<(QDebug dbg, const KWin::FPx2 &fpx2)
+{
+ dbg.nospace() << fpx2[0] << "," << fpx2[1] << QString(fpx2.isValid() ? " (valid)" : " (invalid)");
+ return dbg.space();
+}
+
namespace KWin {
QElapsedTimer AnimationEffect::s_clock;
@@ -824,4 +831,26 @@ void AnimationEffect::_windowDeleted( EffectWindow* w )
}
+QString AnimationEffect::debug(const QString &/*parameter*/) const
+{
+ Q_D(const AnimationEffect);
+ QString dbg;
+ if (d->m_animations.isEmpty())
+ dbg = "No window is animated";
+ else {
+ AniMap::const_iterator entry = d->m_animations.constBegin(), mapEnd = d->m_animations.constEnd();
+ for (; entry != mapEnd; ++entry) {
+ QString caption = entry.key()->isDeleted() ? "[Deleted]" : entry.key()->caption();
+ if (caption.isEmpty())
+ caption = "[Untitled]";
+ dbg += "Animating window: " + caption + '\n';
+ QList::const_iterator anim = entry->first.constBegin(), animEnd = entry->first.constEnd();
+ for (; anim != animEnd; ++anim)
+ dbg += anim->debugInfo();
+ }
+ }
+ return dbg;
+}
+
+
#include "moc_kwinanimationeffect.cpp"
diff --git a/libkwineffects/kwinanimationeffect.h b/libkwineffects/kwinanimationeffect.h
index c5e2d2d757..08c34934d3 100644
--- a/libkwineffects/kwinanimationeffect.h
+++ b/libkwineffects/kwinanimationeffect.h
@@ -81,6 +81,7 @@ public:
inline void set(float v) { f[0] = v; valid = true; }
inline void set(float v1, float v2) { f[0] = v1; f[1] = v2; valid = true; }
+
private:
float f[2];
bool valid;
@@ -125,6 +126,7 @@ public:
/**
* Reimplemented from KWIn::Effect
*/
+ QString debug(const QString ¶meter) const;
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
@@ -211,6 +213,7 @@ private:
} // namespace
+QDebug operator<<(QDebug dbg, const KWin::FPx2 &fpx2);
Q_DECLARE_METATYPE(KWin::FPx2)
#endif // ANIMATION_EFFECT_H
diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp
index 191cc52cc8..0cc83c3abe 100644
--- a/libkwineffects/kwineffects.cpp
+++ b/libkwineffects/kwineffects.cpp
@@ -527,6 +527,11 @@ bool Effect::isActive() const
return true;
}
+QString Effect::debug(const QString &) const
+{
+ return QString();
+}
+
void Effect::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
{
effects->drawWindow(w, mask, region, data);
diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h
index 9c66067194..f6a8ed6710 100644
--- a/libkwineffects/kwineffects.h
+++ b/libkwineffects/kwineffects.h
@@ -170,7 +170,7 @@ X-KDE-Library=kwin4_effect_cooleffect
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
-#define KWIN_EFFECT_API_VERSION_MINOR 221
+#define KWIN_EFFECT_API_VERSION_MINOR 222
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
@@ -454,6 +454,19 @@ public:
**/
virtual bool isActive() const;
+ /**
+ * Reimplement this method to provide online debugging.
+ * This could be as trivial as printing specific detail informations about the effect state
+ * but could also be used to move the effect in and out of a special debug modes, clear bogus
+ * data, etc.
+ * Notice that the functions is const by intent! Whenever you alter the state of the object
+ * due to random user input, you should do so with greatest care, hence const_cast<> your
+ * object - signalling "let me alone, i know what i'm doing"
+ * @param parameter A freeform string user input for your effect to interpret.
+ * @since 4.11
+ */
+ virtual QString debug(const QString ¶meter) const;
+
static int displayWidth();
static int displayHeight();
static QPoint cursorPos();
diff --git a/org.kde.kwin.Effects.xml b/org.kde.kwin.Effects.xml
index d060e8e023..4456743973 100644
--- a/org.kde.kwin.Effects.xml
+++ b/org.kde.kwin.Effects.xml
@@ -30,5 +30,10 @@
+
+
+
+
+