diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt
index 4adba2f521..8ee5aac7b6 100644
--- a/effects/CMakeLists.txt
+++ b/effects/CMakeLists.txt
@@ -109,6 +109,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
sharpen.cpp
snow.cpp
trackmouse.cpp
+ wobblywindows.cpp
)
install( FILES
blur.desktop
@@ -123,6 +124,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
sharpen.desktop
snow.desktop
trackmouse.desktop
+ wobblywindows.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
install( FILES
data/trackmouse.png
@@ -161,6 +163,8 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
snow_config.cpp
snow_config.ui
trackmouse_config.cpp
+ wobblywindows_config.cpp
+ wobblywindows_config.ui
)
install( FILES
coverswitch_config.desktop
@@ -173,6 +177,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
showfps_config.desktop
snow_config.desktop
trackmouse_config.desktop
+ wobblywindows_config.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
endif(KWIN_HAVE_OPENGL_COMPOSITING)
diff --git a/effects/configs_builtins.cpp b/effects/configs_builtins.cpp
index 5a6c9a1279..3cc26ea520 100644
--- a/effects/configs_builtins.cpp
+++ b/effects/configs_builtins.cpp
@@ -39,6 +39,7 @@ along with this program. If not, see .
#include "sharpen_config.h"
#include "snow_config.h"
#include "trackmouse_config.h"
+#include "wobblywindows_config.h"
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
#include "showfps_config.h"
#endif
@@ -73,6 +74,7 @@ KWIN_EFFECT_CONFIG_FACTORY
#define GL_RENDER_PLUGINS \
registerPlugin ("showfps"); \
+ registerPlugin ("wobblywindows"); \
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
K_PLUGIN_FACTORY_DEFINITION(EffectFactory,
diff --git a/effects/wobblywindows.cpp b/effects/wobblywindows.cpp
new file mode 100644
index 0000000000..d7110cfeee
--- /dev/null
+++ b/effects/wobblywindows.cpp
@@ -0,0 +1,1130 @@
+/*****************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2008 Cédric Borgese
+
+You can Freely distribute this program under the GNU General Public
+License. See the file "COPYING" for the exact licensing terms.
+******************************************************************/
+
+
+#include "wobblywindows.h"
+#include "wobblywindows_constants.h"
+
+#include
+#include
+#include
+
+#define USE_ASSERT
+#ifdef USE_ASSERT
+#define ASSERT1 assert
+#else
+#define ASSERT1
+#endif
+
+//#define COMPUTE_STATS
+
+// if you enable it and run kwin in a terminal from the session it manages,
+// be sure to redirect the output of kwin in a file or
+// you'll propably get deadlocks.
+//#define VERBOSE_MODE
+
+#if defined COMPUTE_STATS && !defined VERBOSE_MODE
+# ifdef __GNUC__
+# warning "You enable COMPUTE_STATS without VERBOSE_MODE, computed stats will not be printed."
+# endif
+#endif
+
+namespace KWin
+{
+
+KWIN_EFFECT(wobblywindows, WobblyWindowsEffect)
+
+WobblyWindowsEffect::WobblyWindowsEffect()
+{
+ KConfigGroup conf = effects->effectConfig("Wobbly");
+
+ m_raideur = conf.readEntry("Raideur", RAIDEUR);
+ m_amortissement = conf.readEntry("Amortissement", AMORTISSEMENT);
+ m_move_factor = conf.readEntry("MoveFactor", MOVEFACTOR);
+
+ m_xTesselation = conf.readEntry("XTesselation", XTESSELATION);
+ m_yTesselation = conf.readEntry("YTesselation", YTESSELATION);
+
+ m_minVelocity = conf.readEntry("MinVelocity", MINVELOCITY);
+ m_maxVelocity = conf.readEntry("MaxVelocity", MAXVELOCITY);
+ m_stopVelocity = conf.readEntry("StopVelocity", STOPVELOCITY);
+ m_minAcceleration = conf.readEntry("MinAcceleration", MINACCELERATION);
+ m_maxAcceleration = conf.readEntry("MaxAcceleration", MAXACCELERATION);
+ m_stopAcceleration = conf.readEntry("StopAcceleration", STOPACCELERATION);
+
+ QString velFilter = conf.readEntry("VelocityFilter", VELOCITYFILTER);
+ if (velFilter == "NoFilter")
+ {
+ m_velocityFilter = NoFilter;
+ }
+ else if (velFilter == "FourRingLinearMean")
+ {
+ m_velocityFilter = FourRingLinearMean;
+ }
+ else if (velFilter == "MeanWithMean")
+ {
+ m_velocityFilter = MeanWithMean;
+ }
+ else if (velFilter == "MeanWithMedian")
+ {
+ m_velocityFilter = MeanWithMedian;
+ }
+ else
+ {
+ m_velocityFilter = FourRingLinearMean;
+ kDebug() << "Unknown config value for VelocityFilter : " << velFilter;
+ }
+
+
+ QString accFilter = conf.readEntry("AccelerationFilter", ACCELERATIONFILTER);
+ if (accFilter == "NoFilter")
+ {
+ m_accelerationFilter = NoFilter;
+ }
+ else if (accFilter == "FourRingLinearMean")
+ {
+ m_accelerationFilter = FourRingLinearMean;
+ }
+ else if (accFilter == "MeanWithMean")
+ {
+ m_accelerationFilter = MeanWithMean;
+ }
+ else if (accFilter == "MeanWithMedian")
+ {
+ m_accelerationFilter = MeanWithMedian;
+ }
+ else
+ {
+ m_accelerationFilter = NoFilter;
+ kDebug() << "Unknown config value for accelerationFilter : " << accFilter;
+ }
+
+#if defined VERBOSE_MODE
+ kDebug() << "Parameters :\n" <<
+ "grid(" << m_raideur << ", " << m_amortissement << ", " << m_move_factor << ")\n" <<
+ "velocity(" << m_minVelocity << ", " << m_maxVelocity << ", " << m_stopVelocity << ")\n" <<
+ "acceleration(" << m_minAcceleration << ", " << m_maxAcceleration << ", " << m_stopAcceleration << ")\n" <<
+ "tesselation(" << m_xTesselation << ", " << m_yTesselation << ")";
+#endif
+}
+
+WobblyWindowsEffect::~WobblyWindowsEffect()
+{
+ if (windows.empty())
+ {
+ // we should be empty at this point...
+ // emit a warning and clean the list.
+ kDebug() << "Windows list not empty. Left items : " << windows.count();
+ QHash< const EffectWindow*, WindowWobblyInfos >::iterator i;
+ for (i = windows.begin(); i != windows.end(); ++i)
+ {
+ freeWobblyInfo(i.value());
+ }
+ }
+}
+void WobblyWindowsEffect::setVelocityThreshold(qreal m_minVelocity)
+{
+ this->m_minVelocity = m_minVelocity;
+}
+
+void WobblyWindowsEffect::setMoveFactor(qreal factor)
+{
+ m_move_factor = factor;
+}
+
+void WobblyWindowsEffect::setRaideur(qreal m_raideur)
+{
+ this->m_raideur = m_raideur;
+}
+
+void WobblyWindowsEffect::setVelocityFilter(GridFilter filter)
+{
+ m_velocityFilter = filter;
+}
+
+void WobblyWindowsEffect::setAccelerationFilter(GridFilter filter)
+{
+ m_accelerationFilter = filter;
+}
+
+WobblyWindowsEffect::GridFilter WobblyWindowsEffect::velocityFilter() const
+{
+ return m_velocityFilter;
+}
+
+WobblyWindowsEffect::GridFilter WobblyWindowsEffect::accelerationFilter() const
+{
+ return m_accelerationFilter;
+}
+
+void WobblyWindowsEffect::setAmortissement(qreal m_amortissement)
+{
+ this->m_amortissement = m_amortissement;
+}
+
+void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
+{
+ // We need to mark the screen windows as transformed. Otherwise the whole
+ // screen won't be repainted, resulting in artefacts.
+ // Could we just set a subset of the screen to be repainted ?
+ if (windows.count() != 0)
+ {
+ data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
+ }
+
+ // this set the QRect invalid.
+ m_updateRegion.setWidth(0);
+
+ effects->prePaintScreen(data, time);
+}
+const qreal maxTime = 10.0;
+void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
+{
+ if (windows.contains(w))
+ {
+ data.setTransformed();
+ data.quads = data.quads.makeRegularGrid(m_xTesselation, m_yTesselation);
+ bool stop = false;
+ qreal updateTime = time;
+
+ while (!stop && (updateTime > maxTime))
+ {
+#if defined VERBOSE_MODE
+ kDebug() << "loop time " << updateTime << " / " << time;
+#endif
+ stop = !updateWindowWobblyDatas(w, maxTime);
+ updateTime -= maxTime;
+ }
+ if (!stop && updateTime > 0)
+ {
+ updateWindowWobblyDatas(w, updateTime);
+ }
+ }
+
+ effects->prePaintWindow(w, data, time);
+}
+
+void WobblyWindowsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
+{
+ if(windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ int tx = w->geometry().x();
+ int ty = w->geometry().y();
+ for (int i = 0; i < data.quads.count(); ++i)
+ {
+ for(int j = 0; j < 4; ++j)
+ {
+ WindowVertex& v = data.quads[i][j];
+ Pair oldPos = {tx + v.x(), ty + v.y()};
+ Pair newPos = computeBezierPoint(wwi, oldPos);
+ v.move(newPos.x - tx, newPos.y - ty);
+ }
+ }
+ }
+
+ // Call the next effect.
+ effects->paintWindow(w, mask, region, data);
+}
+
+void WobblyWindowsEffect::postPaintScreen()
+{
+ if (!windows.isEmpty())
+ {
+ effects->addRepaint(m_updateRegion);
+ }
+
+ // Call the next effect.
+ effects->postPaintScreen();
+}
+
+void WobblyWindowsEffect::windowUserMovedResized(EffectWindow* w, bool first, bool last)
+{
+ if (first && !w->isSpecialWindow())
+ {
+ if (!windows.contains(w))
+ {
+ WindowWobblyInfos new_wwi;
+ initWobblyInfo(new_wwi, w->geometry());
+ windows[w] = new_wwi;
+ }
+
+ WindowWobblyInfos& wwi = windows[w];
+ wwi.onConstrain = true;
+ const QRectF& rect = w->geometry();
+
+ qreal x_increment = rect.width() / (wwi.width-1.0);
+ qreal y_increment = rect.height() / (wwi.height-1.0);
+
+ Pair picked = {cursorPos().x(), cursorPos().y()};
+ int indx = (picked.x - rect.x()) / x_increment;
+ int indy = (picked.y - rect.y()) / y_increment;
+ int pickedPointIndex = indy*wwi.width + indx;
+ if (pickedPointIndex < 0)
+ {
+ kDebug() << "Picked index == " << pickedPointIndex << " with (" << cursorPos().x() << "," << cursorPos().y() << ")";
+ pickedPointIndex = 0;
+ }
+ else if (static_cast(pickedPointIndex) > wwi.count - 1)
+ {
+ kDebug() << "Picked index == " << pickedPointIndex << " with (" << cursorPos().x() << "," << cursorPos().y() << ")";
+ pickedPointIndex = wwi.count - 1;
+ }
+#if defined VERBOSE_MODE
+ kDebug() << "Original Picked point -- x : " << picked.x << " - y : " << picked.y;
+#endif
+ wwi.constraint[pickedPointIndex] = true;
+ }
+ else if (last)
+ {
+ if (windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ wwi.onConstrain = false;
+ }
+ }
+}
+
+void WobblyWindowsEffect::windowClosed(EffectWindow* w)
+{
+ if(windows.contains(w))
+ {
+ WindowWobblyInfos& wwi = windows[w];
+ freeWobblyInfo(wwi);
+ windows.remove(w);
+ }
+}
+
+void WobblyWindowsEffect::initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) const
+{
+ wwi.count = 4*4;
+ wwi.width = 4;
+ wwi.height = 4;
+
+ wwi.bezierWidth = m_xTesselation;
+ wwi.bezierHeight = m_yTesselation;
+ wwi.bezierCount = m_xTesselation * m_yTesselation;
+
+ wwi.origin = new Pair[wwi.count];
+ wwi.position = new Pair[wwi.count];
+ wwi.velocity = new Pair[wwi.count];
+ wwi.acceleration = new Pair[wwi.count];
+ wwi.buffer = new Pair[wwi.count];
+ wwi.constraint = new bool[wwi.count];
+
+ wwi.bezierSurface = new Pair[wwi.bezierCount];
+
+ wwi.onConstrain = true;
+
+ qreal x = geometry.x(), y = geometry.y();
+ qreal width = geometry.width(), height = geometry.height();
+
+ Pair initValue = {x, y};
+ static const Pair nullPair = {0.0, 0.0};
+
+ qreal x_increment = width / (wwi.width-1.0);
+ qreal y_increment = height / (wwi.height-1.0);
+
+ for (unsigned int j=0; j<4; ++j)
+ {
+ for (unsigned int i=0; i<4; ++i)
+ {
+ unsigned int idx = j*4 + i;
+ wwi.origin[idx] = initValue;
+ wwi.position[idx] = initValue;
+ wwi.velocity[idx] = nullPair;
+ wwi.constraint[idx] = false;
+ if (i != 4-2) // x grid count - 2, i.e. not the last point
+ {
+ initValue.x += x_increment;
+ }
+ else
+ {
+ initValue.x = width + x;
+ }
+ initValue.x = initValue.x;
+ }
+ initValue.x = x;
+ initValue.x = initValue.x;
+ if (j != 4-2) // y grid count - 2, i.e. not the last point
+ {
+ initValue.y += y_increment;
+ }
+ else
+ {
+ initValue.y = height + y;
+ }
+ initValue.y = initValue.y;
+ }
+}
+
+void WobblyWindowsEffect::freeWobblyInfo(WindowWobblyInfos& wwi) const
+{
+ delete wwi.origin;
+ delete wwi.position;
+ delete wwi.velocity;
+ delete wwi.acceleration;
+ delete wwi.buffer;
+ delete wwi.constraint;
+
+ delete wwi.bezierSurface;
+}
+
+WobblyWindowsEffect::Pair WobblyWindowsEffect::computeBezierPoint(const WindowWobblyInfos& wwi, Pair point) const
+{
+ // compute the input value
+ Pair topleft = wwi.origin[0];
+ Pair bottomright = wwi.origin[wwi.count-1];
+
+ ASSERT1(point.x >= topleft.x);
+ ASSERT1(point.y >= topleft.y);
+ ASSERT1(point.x <= bottomright.x);
+ ASSERT1(point.y <= bottomright.y);
+
+ qreal tx = (point.x - topleft.x) / (bottomright.x - topleft.x);
+ qreal ty = (point.y - topleft.y) / (bottomright.y - topleft.y);
+
+ ASSERT1(tx >= 0);
+ ASSERT1(tx <= 1);
+ ASSERT1(ty >= 0);
+ ASSERT1(ty <= 1);
+
+ // compute polinomial coeff
+
+ qreal px[4];
+ px[0] = (1-tx)*(1-tx)*(1-tx);
+ px[1] = 3*(1-tx)*(1-tx)*tx;
+ px[2] = 3*(1-tx)*tx*tx;
+ px[3] = tx*tx*tx;
+
+ qreal py[4];
+ py[0] = (1-ty)*(1-ty)*(1-ty);
+ py[1] = 3*(1-ty)*(1-ty)*ty;
+ py[2] = 3*(1-ty)*ty*ty;
+ py[3] = ty*ty*ty;
+
+ Pair res = {0.0, 0.0};
+
+ for (unsigned int j = 0; j < 4; ++j)
+ {
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ // this assume the grid is 4*4
+ res.x += px[i] * py[j] * wwi.position[i + j * wwi.width].x;
+ res.y += px[i] * py[j] * wwi.position[i + j * wwi.width].y;
+ }
+ }
+
+ return res;
+}
+namespace
+{
+
+static inline void fixVectorBounds(WobblyWindowsEffect::Pair& vec, qreal min, qreal max)
+{
+ if (fabs(vec.x) < min)
+ {
+ vec.x = 0.0;
+ }
+ else if (fabs(vec.x) > max)
+ {
+ if (vec.x > 0.0)
+ {
+ vec.x = max;
+ }
+ else
+ {
+ vec.x = -max;
+ }
+ }
+
+ if (fabs(vec.y) < min)
+ {
+ vec.y = 0.0;
+ }
+ else if (fabs(vec.y) > max)
+ {
+ if (vec.y > 0.0)
+ {
+ vec.y = max;
+ }
+ else
+ {
+ vec.y = -max;
+ }
+ }
+}
+
+static inline void computeVectorBounds(WobblyWindowsEffect::Pair& vec, WobblyWindowsEffect::Pair& bound)
+{
+ if (fabs(vec.x) < bound.x)
+ {
+ bound.x = fabs(vec.x);
+ }
+ else if (fabs(vec.x) > bound.y)
+ {
+ bound.y = fabs(vec.x);
+ }
+ if (fabs(vec.y) < bound.x)
+ {
+ bound.x = fabs(vec.y);
+ }
+ else if (fabs(vec.y) > bound.y)
+ {
+ bound.y = fabs(vec.y);
+ }
+}
+
+} // close the anonymous namespace
+
+bool WobblyWindowsEffect::updateWindowWobblyDatas(EffectWindow* w, qreal time)
+{
+ const QRectF& rect = w->geometry();
+ WindowWobblyInfos& wwi = windows[w];
+
+ qreal x_length = rect.width() / (wwi.width-1.0);
+ qreal y_length = rect.height() / (wwi.height-1.0);
+
+#if defined VERBOSE_MODE
+ kDebug() << "time " << time;
+ kDebug() << "increment x " << x_length << " // y" << y_length;
+#endif
+
+ Pair origine = {rect.x(), rect.y()};
+
+ for (unsigned int j=0; j bottomRightCorner.x)
+ {
+ bottomRightCorner.x = pos.x;
+ }
+ if (pos.y < topLeftCorner.y)
+ {
+ topLeftCorner.y = pos.y;
+ }
+ if (pos.y > bottomRightCorner.y)
+ {
+ bottomRightCorner.y = pos.y;
+ }
+
+ vel_sum += fabs(vel.x) + fabs(vel.y);
+
+#if defined VERBOSE_MODE
+ if (wwi.constraint[i])
+ {
+ kDebug() << "Constraint point ** vel : " << vel.x << "," << vel.y << " ** move : " << vel.x*time << "," << vel.y*time;
+ }
+#endif
+ }
+
+#if defined VERBOSE_MODE
+# if defined COMPUTE_STATS
+ kDebug() << "Acceleration bounds (" << accBound.x << ", " << accBound.y << ")";
+ kDebug() << "Velocity bounds (" << velBound.x << ", " << velBound.y << ")";
+# endif
+ kDebug() << "sum_acc : " << acc_sum << " *** sum_vel :" << vel_sum;
+#endif
+
+ if (!wwi.onConstrain && acc_sum < m_stopAcceleration && vel_sum < m_stopVelocity)
+ {
+ freeWobblyInfo(wwi);
+ windows.remove(w);
+ return false;
+ }
+
+ QRect windowRect(topLeftCorner.x, topLeftCorner.y,
+ bottomRightCorner.x - topLeftCorner.x, bottomRightCorner.y - topLeftCorner.y);
+ if (m_updateRegion.isValid())
+ {
+ m_updateRegion = m_updateRegion.united(windowRect);
+ }
+ else
+ {
+ m_updateRegion = windowRect;
+ }
+
+ return true;
+}
+
+void WobblyWindowsEffect::fourRingLinearMean(Pair** datas_pointer, WindowWobblyInfos& wwi)
+{
+ Pair* datas = *datas_pointer;
+ Pair neibourgs[4];
+
+ // for corners
+
+ // top-left
+ {
+ Pair& res = wwi.buffer[0];
+ Pair vit = datas[0];
+ neibourgs[0] = datas[1];
+ neibourgs[1] = datas[wwi.width];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.0;
+ }
+
+
+ // top-right
+ {
+ Pair& res = wwi.buffer[wwi.width-1];
+ Pair vit = datas[wwi.width-1];
+ neibourgs[0] = datas[wwi.width-2];
+ neibourgs[1] = datas[2*wwi.width-1];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.0;
+ }
+
+
+ // bottom-left
+ {
+ Pair& res = wwi.buffer[wwi.width*(wwi.height-1)];
+ Pair vit = datas[wwi.width*(wwi.height-1)];
+ neibourgs[0] = datas[wwi.width*(wwi.height-1)+1];
+ neibourgs[1] = datas[wwi.width*(wwi.height-2)];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.0;
+ }
+
+
+ // bottom-right
+ {
+ Pair& res = wwi.buffer[wwi.count-1];
+ Pair vit = datas[wwi.count-1];
+ neibourgs[0] = datas[wwi.count-2];
+ neibourgs[1] = datas[wwi.width*(wwi.height-1)-1];
+
+ res.x = (neibourgs[0].x + neibourgs[1].x + 2.0*vit.x) / 4.0;
+ res.y = (neibourgs[0].y + neibourgs[1].y + 2.0*vit.y) / 4.0;
+ }
+
+
+ // for borders
+
+ // top border
+ for (unsigned int i=1; i xmax)
+ {
+ xmax = datas[i].x;
+ }
+
+ if (datas[i].y < ymin)
+ {
+ ymin = datas[i].y;
+ }
+ if (datas[i].y > ymax)
+ {
+ ymax = datas[i].y;
+ }
+ }
+
+ Pair median = {(xmin + xmax)/2.0, (ymin + ymax)/2.0};
+
+ for (unsigned int i = 0; i < wwi.count; ++i)
+ {
+ wwi.buffer[i].x = (datas[i].x + median.x) / 2.0;
+ wwi.buffer[i].y = (datas[i].y + median.y) / 2.0;
+ }
+
+ Pair* tmp = datas;
+ *datas_pointer = wwi.buffer;
+ wwi.buffer = tmp;
+}
+
+
+} // namespace KWin
+
diff --git a/effects/wobblywindows.desktop b/effects/wobblywindows.desktop
new file mode 100644
index 0000000000..33c0706cc4
--- /dev/null
+++ b/effects/wobblywindows.desktop
@@ -0,0 +1,17 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Wobbly Windows
+Icon=kwin-effect-wavywindows
+
+Type=Service
+ServiceTypes=KWin/Effect
+X-KDE-PluginInfo-Author=Cédric Borgese
+X-KDE-PluginInfo-Email=cedric.borgese@gmail.com
+X-KDE-PluginInfo-Name=kwin4_effect_wobblywindows
+X-KDE-PluginInfo-Version=0.0.1
+X-KDE-PluginInfo-Category=Appearance
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+X-KDE-Library=kwin4_effect_builtins
+X-KDE-Ordering=80
\ No newline at end of file
diff --git a/effects/wobblywindows.h b/effects/wobblywindows.h
new file mode 100644
index 0000000000..bbbf9de6a5
--- /dev/null
+++ b/effects/wobblywindows.h
@@ -0,0 +1,128 @@
+/*****************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2008 Cédric Borgese
+
+You can Freely distribute this program under the GNU General Public
+License. See the file "COPYING" for the exact licensing terms.
+******************************************************************/
+
+#ifndef WOBBLYWINDOWS_H
+#define WOBBLYWINDOWS_H
+
+// Include with base class for effects.
+#include
+
+namespace KWin
+{
+
+/**
+ * Effect which wobble windows
+ **/
+class WobblyWindowsEffect : public Effect
+{
+ public:
+
+ enum GridFilter
+ {
+ NoFilter,
+ FourRingLinearMean,
+ MeanWithMean,
+ MeanWithMedian
+ };
+
+
+ WobblyWindowsEffect();
+ virtual ~WobblyWindowsEffect();
+
+ 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 );
+ virtual void postPaintScreen();
+ virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last );
+ virtual void windowClosed( EffectWindow* c );
+
+ // Wobbly model parameters
+ void setRaideur(qreal raideur);
+ void setAmortissement(qreal amortissement);
+ void setVelocityThreshold(qreal velocityThreshold);
+ void setMoveFactor(qreal factor);
+
+ void setVelocityFilter(GridFilter filter);
+ void setAccelerationFilter(GridFilter filter);
+ GridFilter velocityFilter() const;
+ GridFilter accelerationFilter() const;
+
+ struct Pair
+ {
+ qreal x;
+ qreal y;
+ };
+
+ private:
+
+ bool updateWindowWobblyDatas(EffectWindow* w, qreal time);
+
+ struct WindowWobblyInfos
+ {
+ Pair* origin;
+ Pair* position;
+ Pair* velocity;
+ Pair* acceleration;
+ Pair* buffer;
+
+ // if true, the point is constraint to its "normal" destination
+ // given by the window position.
+ // if false, the point is free (i.e. use the physics system to move it)
+ bool* constraint;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int count;
+
+ Pair* bezierSurface;
+ unsigned int bezierWidth;
+ unsigned int bezierHeight;
+ unsigned int bezierCount;
+
+ bool onConstrain;
+ };
+
+ QHash< const EffectWindow*, WindowWobblyInfos > windows;
+
+ QRect m_updateRegion;
+
+ qreal m_raideur;
+ qreal m_amortissement;
+ qreal m_move_factor;
+
+ // the default tesselation for windows
+ // use qreal instead of int as I really often need
+ // these values as real to do divisions.
+ qreal m_xTesselation;
+ qreal m_yTesselation;
+
+ GridFilter m_velocityFilter;
+ GridFilter m_accelerationFilter;
+
+ qreal m_minVelocity;
+ qreal m_maxVelocity;
+ qreal m_stopVelocity;
+ qreal m_minAcceleration;
+ qreal m_maxAcceleration;
+ qreal m_stopAcceleration;
+
+ void initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry) const;
+ void freeWobblyInfo(WindowWobblyInfos& wwi) const;
+
+ WobblyWindowsEffect::Pair computeBezierPoint(const WindowWobblyInfos& wwi, Pair point) const;
+
+ static void fourRingLinearMean(Pair** datas, WindowWobblyInfos& wwi);
+ static void meanWithMean(Pair** datas, WindowWobblyInfos& wwi);
+ static void meanWithMedian(Pair** datas, WindowWobblyInfos& wwi);
+};
+
+} // namespace KWin
+
+#endif // WOBBLYWINDOWS_H
diff --git a/effects/wobblywindows_config.cpp b/effects/wobblywindows_config.cpp
new file mode 100644
index 0000000000..3bd8a41ce4
--- /dev/null
+++ b/effects/wobblywindows_config.cpp
@@ -0,0 +1,503 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Cédric Borgese
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#include "wobblywindows_config.h"
+#include "wobblywindows_constants.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#ifndef KDE_USE_FINAL
+KWIN_EFFECT_CONFIG_FACTORY
+#endif
+
+namespace KWin
+{
+
+WobblyWindowsEffectConfig::WobblyWindowsEffectConfig(QWidget* parent, const QVariantList& args) :
+KCModule(EffectFactory::componentData(), parent, args)
+{
+ m_ui.setupUi(this);
+
+ connect(m_ui.spRaideur, SIGNAL(valueChanged(double)), this, SLOT(slotSpRaideur(double)));
+ connect(m_ui.slRaideur, SIGNAL(sliderMoved(int)), this, SLOT(slotSlRaideur(int)));
+ connect(m_ui.spAmortissement, SIGNAL(valueChanged(double)), this, SLOT(slotSpAmortissement(double)));
+ connect(m_ui.slAmortissement, SIGNAL(sliderMoved(int)), this, SLOT(slotSlAmortissement(int)));
+ connect(m_ui.spMovFactor, SIGNAL(valueChanged(double)), this, SLOT(slotSpMovFactor(double)));
+ connect(m_ui.slMovFactor, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMovFactor(int)));
+
+ connect(m_ui.cbGridFilter, SIGNAL(activated(int)), this, SLOT(slotGridParameterSelected(int)));
+
+ connect(m_ui.rbNone, SIGNAL(toggled(bool)), this, SLOT(slotRbNone(bool)));
+ connect(m_ui.rbRingMean, SIGNAL(toggled(bool)), this, SLOT(slotRbRingMean(bool)));
+ connect(m_ui.rbMeanMean, SIGNAL(toggled(bool)), this, SLOT(slotRbMeanMean(bool)));
+ connect(m_ui.rbMeanMedian, SIGNAL(toggled(bool)), this, SLOT(slotRbMeanMedian(bool)));
+
+ connect(m_ui.spMinVel, SIGNAL(valueChanged(double)), this, SLOT(slotSpMinVel(double)));
+ connect(m_ui.slMinVel, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMinVel(int)));
+ connect(m_ui.spMaxVel, SIGNAL(valueChanged(double)), this, SLOT(slotSpMaxVel(double)));
+ connect(m_ui.slMaxVel, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMaxVel(int)));
+ connect(m_ui.spStopVel, SIGNAL(valueChanged(double)), this, SLOT(slotSpStopVel(double)));
+ connect(m_ui.slStopVel, SIGNAL(sliderMoved(int)), this, SLOT(slotSlStopVel(int)));
+ connect(m_ui.spMinAcc, SIGNAL(valueChanged(double)), this, SLOT(slotSpMinAcc(double)));
+ connect(m_ui.slMinAcc, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMinAcc(int)));
+ connect(m_ui.spMaxAcc, SIGNAL(valueChanged(double)), this, SLOT(slotSpMaxAcc(double)));
+ connect(m_ui.slMaxAcc, SIGNAL(sliderMoved(int)), this, SLOT(slotSlMaxAcc(int)));
+ connect(m_ui.spStopAcc, SIGNAL(valueChanged(double)), this, SLOT(slotSpStopAcc(double)));
+ connect(m_ui.slStopAcc, SIGNAL(sliderMoved(int)), this, SLOT(slotSlStopAcc(int)));
+
+ load();
+}
+
+WobblyWindowsEffectConfig::~WobblyWindowsEffectConfig()
+{
+}
+
+void WobblyWindowsEffectConfig::load()
+{
+ KCModule::load();
+
+ KConfigGroup conf = EffectsHandler::effectConfig("Wobbly");
+ qreal raideur = conf.readEntry("Raideur", RAIDEUR);
+ qreal amortissement = conf.readEntry("Amortissement", AMORTISSEMENT);
+ qreal move_factor = conf.readEntry("MoveFactor", MOVEFACTOR);
+
+ m_ui.spRaideur->setValue(raideur);
+ m_ui.slRaideur->setSliderPosition(raideur*50);
+
+ m_ui.spAmortissement->setValue(amortissement);
+ m_ui.slAmortissement->setSliderPosition(amortissement*100);
+
+ m_ui.spMovFactor->setValue(move_factor);
+ m_ui.slMovFactor->setValue(move_factor*100);
+
+ int xTesselation = conf.readEntry("XTesselation", XTESSELATION);
+ int yTesselation = conf.readEntry("YTesselation", YTESSELATION);
+
+ m_ui.spHNodes->setValue(xTesselation);
+ m_ui.spVNodes->setValue(yTesselation);
+
+ //squareRootMasterAcceleration = conf.readEntry("SquareRootMasterAcceleration", false);
+
+ QString velFilter = conf.readEntry("VelocityFilter", VELOCITYFILTER);
+ if (velFilter == "NoFilter")
+ {
+ velocityFilter = NoFilter;
+ }
+ else if (velFilter == "FourRingLinearMean")
+ {
+ velocityFilter = FourRingLinearMean;
+ }
+ else if (velFilter == "MeanWithMean")
+ {
+ velocityFilter = MeanWithMean;
+ }
+ else if (velFilter == "MeanWithMedian")
+ {
+ velocityFilter = MeanWithMedian;
+ }
+ else
+ {
+ velocityFilter = FourRingLinearMean;
+ kDebug() << "Unknown config value for VelocityFilter : " << velFilter;
+ }
+
+
+ QString accFilter = conf.readEntry("AccelerationFilter", ACCELERATIONFILTER);
+ if (accFilter == "NoFilter")
+ {
+ accelerationFilter = NoFilter;
+ }
+ else if (accFilter == "FourRingLinearMean")
+ {
+ accelerationFilter = FourRingLinearMean;
+ }
+ else if (accFilter == "MeanWithMean")
+ {
+ accelerationFilter = MeanWithMean;
+ }
+ else if (accFilter == "MeanWithMedian")
+ {
+ accelerationFilter = MeanWithMedian;
+ }
+ else
+ {
+ accelerationFilter = NoFilter;
+ kDebug() << "Unknown config value for accelerationFilter : " << accFilter;
+ }
+
+ qreal minVel = conf.readEntry("MinVelocity", MINVELOCITY);
+ qreal maxVel = conf.readEntry("MaxVelocity", MAXVELOCITY);
+ qreal stopVel = conf.readEntry("StopVelocity", STOPVELOCITY);
+ qreal minAcc = conf.readEntry("MinAcceleration", MINACCELERATION);
+ qreal maxAcc = conf.readEntry("MaxAcceleration", MAXACCELERATION);
+ qreal stopAcc = conf.readEntry("StopAcceleration", STOPACCELERATION);
+
+ m_ui.spMinVel->setValue(minVel);
+ m_ui.slMinVel->setSliderPosition(minVel*100);
+ m_ui.spMaxVel->setValue(maxVel);
+ m_ui.slMaxVel->setSliderPosition(maxVel/10);
+ m_ui.spStopVel->setValue(stopVel);
+ m_ui.slStopVel->setSliderPosition(stopVel*10);
+ m_ui.spMinAcc->setValue(minAcc);
+ m_ui.slMinAcc->setSliderPosition(minAcc*100);
+ m_ui.spMaxAcc->setValue(maxAcc);
+ m_ui.slMaxAcc->setSliderPosition(maxAcc/10);
+ m_ui.spStopAcc->setValue(stopAcc);
+ m_ui.slStopAcc->setSliderPosition(stopAcc*10);
+
+ emit changed(false);
+}
+
+void WobblyWindowsEffectConfig::save()
+{
+ KConfigGroup conf = EffectsHandler::effectConfig("Wobbly");
+
+ conf.writeEntry("Raideur", m_ui.spRaideur->value());
+ conf.writeEntry("Amortissement", m_ui.spAmortissement->value());
+ conf.writeEntry("MoveFactor", m_ui.spMovFactor->value());
+
+ conf.writeEntry("XTesselation", m_ui.spHNodes->value());
+ conf.writeEntry("YTesselation", m_ui.spVNodes->value());
+
+ switch (velocityFilter)
+ {
+ case NoFilter:
+ conf.writeEntry("VelocityFilter", "NoFilter");
+ break;
+
+ case FourRingLinearMean:
+ conf.writeEntry("VelocityFilter", "FourRingLinearMean");
+ break;
+
+ case MeanWithMean:
+ conf.writeEntry("VelocityFilter", "MeanWithMean");
+ break;
+
+ case MeanWithMedian:
+ conf.writeEntry("VelocityFilter", "MeanWithMedian");
+ break;
+ }
+
+ switch (accelerationFilter)
+ {
+ case NoFilter:
+ conf.writeEntry("AccelerationFilter", "NoFilter");
+ break;
+
+ case FourRingLinearMean:
+ conf.writeEntry("AccelerationFilter", "FourRingLinearMean");
+ break;
+
+ case MeanWithMean:
+ conf.writeEntry("AccelerationFilter", "MeanWithMean");
+ break;
+
+ case MeanWithMedian:
+ conf.writeEntry("AccelerationFilter", "MeanWithMedian");
+ break;
+ }
+
+ conf.writeEntry("MinVelocity", m_ui.spMinVel->value());
+ conf.writeEntry("MaxVelocity", m_ui.spMaxVel->value());
+ conf.writeEntry("StopVelocity", m_ui.spStopVel->value());
+ conf.writeEntry("MinAcceleration", m_ui.spMinAcc->value());
+ conf.writeEntry("MaxAcceleration", m_ui.spMaxAcc->value());
+ conf.writeEntry("StopAcceleration", m_ui.spStopAcc->value());
+
+ conf.sync();
+
+ emit changed(false);
+ EffectsHandler::sendReloadMessage("kwin4_effect_wobblywindows");
+}
+
+void WobblyWindowsEffectConfig::defaults()
+{
+ m_ui.spRaideur->setValue(RAIDEUR);
+ m_ui.slRaideur->setSliderPosition(RAIDEUR*50);
+
+ m_ui.spAmortissement->setValue(AMORTISSEMENT);
+ m_ui.slAmortissement->setSliderPosition(AMORTISSEMENT*100);
+
+ m_ui.spMovFactor->setValue(MOVEFACTOR);
+ m_ui.slMovFactor->setValue(MOVEFACTOR*100);
+
+ m_ui.spHNodes->setValue(XTESSELATION);
+ m_ui.spVNodes->setValue(YTESSELATION);
+
+ velocityFilter = FourRingLinearMean;
+ accelerationFilter = NoFilter;
+ slotGridParameterSelected(m_ui.cbGridFilter->currentIndex());
+
+ m_ui.spMinVel->setValue(MINVELOCITY);
+ m_ui.slMinVel->setSliderPosition(MINVELOCITY*100);
+
+ m_ui.spMaxVel->setValue(MAXVELOCITY);
+ m_ui.slMaxVel->setSliderPosition(MAXVELOCITY/10);
+
+ m_ui.spStopVel->setValue(STOPVELOCITY);
+ m_ui.slStopVel->setSliderPosition(STOPVELOCITY*10);
+
+ m_ui.spMinAcc->setValue(MINACCELERATION);
+ m_ui.slMinAcc->setSliderPosition(MINACCELERATION*100);
+
+ m_ui.spMaxAcc->setValue(MAXACCELERATION);
+ m_ui.slMaxAcc->setSliderPosition(MAXACCELERATION/10);
+
+ m_ui.spStopAcc->setValue(STOPACCELERATION);
+ m_ui.slStopAcc->setSliderPosition(STOPACCELERATION*10);
+
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpRaideur(double value)
+{
+ m_ui.slRaideur->setSliderPosition(value*50);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlRaideur(int value)
+{
+ m_ui.spRaideur->setValue(value/50.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpAmortissement(double value)
+{
+ m_ui.slAmortissement->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlAmortissement(int value)
+{
+ m_ui.spAmortissement->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpMovFactor(double value)
+{
+ m_ui.slMovFactor->setValue(value*100);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlMovFactor(int value)
+{
+ m_ui.spMovFactor->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+// filters
+
+void WobblyWindowsEffectConfig::slotRbNone(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = NoFilter;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = NoFilter;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotRbRingMean(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = FourRingLinearMean;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = FourRingLinearMean;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotRbMeanMean(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = MeanWithMean;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = MeanWithMean;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotRbMeanMedian(bool toggled)
+{
+ if (toggled)
+ {
+ if (m_ui.cbGridFilter->currentIndex() == 0) // velocity
+ {
+ velocityFilter = MeanWithMedian;
+ }
+ else if (m_ui.cbGridFilter->currentIndex() == 1) // acceleration
+ {
+ accelerationFilter = MeanWithMedian;
+ }
+ }
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotGridParameterSelected(int index)
+{
+ if (index == 0) // velocity
+ {
+ switch (velocityFilter)
+ {
+ case NoFilter:
+ m_ui.rbNone->setChecked(true);
+ break;
+
+ case FourRingLinearMean:
+ m_ui.rbRingMean->setChecked(true);
+ break;
+
+ case MeanWithMean:
+ m_ui.rbMeanMean->setChecked(true);
+ break;
+
+ case MeanWithMedian:
+ m_ui.rbMeanMedian->setChecked(true);
+ break;
+ }
+ }
+ else if (index == 1) // acceleration
+ {
+ switch (accelerationFilter)
+ {
+ case NoFilter:
+ m_ui.rbNone->setChecked(true);
+ break;
+
+ case FourRingLinearMean:
+ m_ui.rbRingMean->setChecked(true);
+ break;
+
+ case MeanWithMean:
+ m_ui.rbMeanMean->setChecked(true);
+ break;
+
+ case MeanWithMedian:
+ m_ui.rbMeanMedian->setChecked(true);
+ break;
+ }
+ }
+ emit changed(true);
+}
+
+// thresholds
+
+void WobblyWindowsEffectConfig::slotSpMinVel(double value)
+{
+ m_ui.slMinVel->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlMinVel(int value)
+{
+ m_ui.spMinVel->setValue(qreal(value)/100.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpMaxVel(double value)
+{
+ m_ui.slMaxVel->setSliderPosition(value/10);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlMaxVel(int value)
+{
+ m_ui.spMaxVel->setValue(value*10.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpStopVel(double value)
+{
+ m_ui.slStopVel->setSliderPosition(value*10);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlStopVel(int value)
+{
+ m_ui.spStopVel->setValue(value/10.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpMinAcc(double value)
+{
+ m_ui.slMinAcc->setSliderPosition(value*100);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlMinAcc(int value)
+{
+ m_ui.spMinAcc->setValue(value/100.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpMaxAcc(double value)
+{
+ m_ui.slMaxAcc->setSliderPosition(value/10);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlMaxAcc(int value)
+{
+ m_ui.spMaxAcc->setValue(value*10.0);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSpStopAcc(double value)
+{
+ m_ui.slStopAcc->setSliderPosition(value*10);
+ emit changed(true);
+}
+
+void WobblyWindowsEffectConfig::slotSlStopAcc(int value)
+{
+ m_ui.spStopAcc->setValue(value/10.0);
+ emit changed(true);
+}
+
+
+} // namespace
+
+#include "wobblywindows_config.moc"
diff --git a/effects/wobblywindows_config.desktop b/effects/wobblywindows_config.desktop
new file mode 100644
index 0000000000..c47f9289aa
--- /dev/null
+++ b/effects/wobblywindows_config.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=KCModule
+
+X-KDE-Library=kcm_kwin4_effect_builtins
+X-KDE-ParentComponents=kwin4_effect_wobblywindows
+X-KDE-PluginKeyword=wobblywindows
+
+Name=Wobbly Windows
+
diff --git a/effects/wobblywindows_config.h b/effects/wobblywindows_config.h
new file mode 100644
index 0000000000..c88fbbab19
--- /dev/null
+++ b/effects/wobblywindows_config.h
@@ -0,0 +1,93 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Cédric Borgese
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#ifndef KWIN_WOBBLY_CONFIG_H
+#define KWIN_WOBBLY_CONFIG_H
+
+#define KDE3_SUPPORT
+#include
+#undef KDE3_SUPPORT
+
+#include "ui_wobblywindows_config.h"
+
+class KActionCollection;
+
+namespace KWin
+{
+
+class WobblyWindowsEffectConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ explicit WobblyWindowsEffectConfig(QWidget* parent = 0, const QVariantList& args = QVariantList());
+ ~WobblyWindowsEffectConfig();
+
+public slots:
+ virtual void save();
+ virtual void load();
+ virtual void defaults();
+
+private:
+ enum GridFilter
+ {
+ NoFilter,
+ FourRingLinearMean,
+ MeanWithMean,
+ MeanWithMedian
+ };
+
+private slots:
+
+ void slotSpRaideur(double);
+ void slotSlRaideur(int);
+ void slotSpAmortissement(double);
+ void slotSlAmortissement(int);
+ void slotSpMovFactor(double);
+ void slotSlMovFactor(int);
+
+ void slotGridParameterSelected(int);
+ void slotRbNone(bool);
+ void slotRbRingMean(bool);
+ void slotRbMeanMean(bool);
+ void slotRbMeanMedian(bool);
+
+ void slotSpMinVel(double);
+ void slotSlMinVel(int);
+ void slotSpMaxVel(double);
+ void slotSlMaxVel(int);
+ void slotSpStopVel(double);
+ void slotSlStopVel(int);
+ void slotSpMinAcc(double);
+ void slotSlMinAcc(int);
+ void slotSpMaxAcc(double);
+ void slotSlMaxAcc(int);
+ void slotSpStopAcc(double);
+ void slotSlStopAcc(int);
+
+private:
+ Ui::WobblyWindowsEffectConfigForm m_ui;
+
+ GridFilter velocityFilter;
+ GridFilter accelerationFilter;
+};
+
+} // namespace
+
+#endif
diff --git a/effects/wobblywindows_config.ui b/effects/wobblywindows_config.ui
new file mode 100644
index 0000000000..2877c53b1d
--- /dev/null
+++ b/effects/wobblywindows_config.ui
@@ -0,0 +1,642 @@
+
+ KWin::WobblyWindowsEffectConfigForm
+
+
+
+ 0
+ 0
+ 553
+ 383
+
+
+
+ WobblyWindows
+
+
+ -
+
+
+ 0
+
+
+
+ Grid Parameters
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Grid Minimal Tesselation
+
+
+
-
+
+
+ Horizontal Nodes :
+
+
+
+ -
+
+
+ 2
+
+
+ 20
+
+
+
+ -
+
+
+ Vertical Nodes :
+
+
+
+ -
+
+
+ 2
+
+
+ 20
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Grid Parameters
+
+
+
-
+
+
+ Raideur :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 2.000000000000000
+
+
+ 0.020000000000000
+
+
+ 0.500000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 25
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Amortissement :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.010000000000000
+
+
+ 0.940000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 94
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Move Factor :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 16
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.010000000000000
+
+
+ 0.010000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 1
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Grid Filter
+
+
+
-
+
+
-
+
+ Velocity
+
+
+ -
+
+ Acceleration
+
+
+
+
+ -
+
+
+ None
+
+
+ true
+
+
+
+ -
+
+
+ Ring Mean
+
+
+ false
+
+
+
+ -
+
+
+ Mean With Mean
+
+
+
+ -
+
+
+ Mean With Median
+
+
+
+
+
+
+
+
+
+
+ Thresholds
+
+
+ -
+
+
+ Velocity
+
+
+
-
+
+
+ Min Velocity
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.010000000000000
+
+
+ 0.500000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 50
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Max Velocity
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1000.000000000000000
+
+
+ 10.000000000000000
+
+
+ 500.000000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 50
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Velocity Stop
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 10.000000000000000
+
+
+ 0.100000000000000
+
+
+ 3.000000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 30
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+ -
+
+
+ Acceleration
+
+
+
-
+
+
+ Min Acceleration
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.010000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 10
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Max Acceleration
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 21
+ 20
+
+
+
+
+ -
+
+
+ 1000.000000000000000
+
+
+ 10.000000000000000
+
+
+ 500.000000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 50
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Acceleration Stop
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 21
+ 20
+
+
+
+
+ -
+
+
+ 10.000000000000000
+
+
+ 0.100000000000000
+
+
+ 8.000000000000000
+
+
+
+ -
+
+
+ 100
+
+
+ 80
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/effects/wobblywindows_constants.h b/effects/wobblywindows_constants.h
new file mode 100644
index 0000000000..873d4e7b52
--- /dev/null
+++ b/effects/wobblywindows_constants.h
@@ -0,0 +1,38 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Cédric Borgese
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#include
+
+static const qreal RAIDEUR = 0.06;
+static const qreal AMORTISSEMENT = 0.92;
+static const qreal MOVEFACTOR = 0.1;
+
+static const int XTESSELATION = 20;
+static const int YTESSELATION = 20;
+
+static const qreal MINVELOCITY = 0.0;
+static const qreal MAXVELOCITY = 1000.0;
+static const qreal STOPVELOCITY = 3.0;
+static const qreal MINACCELERATION = 0.0;
+static const qreal MAXACCELERATION = 1000.0;
+static const qreal STOPACCELERATION = 5.0;
+
+static const char* VELOCITYFILTER = "FourRingLinearMean";
+static const char* ACCELERATIONFILTER = "FourRingLinearMean";