diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt
index 16f8fb733e..b3607839f8 100644
--- a/effects/CMakeLists.txt
+++ b/effects/CMakeLists.txt
@@ -96,6 +96,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
SET(kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
blur.cpp
explosioneffect.cpp
+ flipswitch.cpp
invert.cpp
lookingglass.cpp
magnifier.cpp
@@ -108,6 +109,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
install( FILES
blur.desktop
explosion.desktop
+ flipswitch.desktop
invert.desktop
lookingglass.desktop
magnifier.desktop
@@ -139,6 +141,8 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
data/circle-edgy.png
DESTINATION ${DATA_INSTALL_DIR}/kwin )
SET(kwin4_effect_builtins_config_sources ${kwin4_effect_builtins_config_sources}
+ flipswitch_config.cpp
+ flipswitch_config.ui
invert_config.cpp
lookingglass_config.cpp
lookingglass_config.ui
@@ -152,6 +156,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
trackmouse_config.cpp
)
install( FILES
+ flipswitch_config.desktop
invert_config.desktop
lookingglass_config.desktop
magnifier_config.desktop
diff --git a/effects/configs_builtins.cpp b/effects/configs_builtins.cpp
index 669e2c00d2..36f06d9553 100644
--- a/effects/configs_builtins.cpp
+++ b/effects/configs_builtins.cpp
@@ -30,6 +30,7 @@ along with this program. If not, see .
#include "zoom_config.h"
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
+#include "flipswitch_config.h"
#include "invert_config.h"
#include "lookingglass_config.h"
#include "mousemark_config.h"
@@ -56,6 +57,7 @@ KWIN_EFFECT_CONFIG_FACTORY
registerPlugin("zoom");
#define GL_PLUGINS \
+ registerPlugin("flipswitch"); \
registerPlugin("invert"); \
registerPlugin("lookingglass"); \
registerPlugin("mousemark"); \
diff --git a/effects/flipswitch.cpp b/effects/flipswitch.cpp
new file mode 100644
index 0000000000..8323b64e2f
--- /dev/null
+++ b/effects/flipswitch.cpp
@@ -0,0 +1,510 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Martin Gräßlin .
+*********************************************************************/
+#include "flipswitch.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef KWIN_HAVE_OPENGL_COMPOSITING
+#include
+#endif
+
+namespace KWin
+{
+
+KWIN_EFFECT( flipswitch, FlipSwitchEffect )
+
+FlipSwitchEffect::FlipSwitchEffect()
+ : mActivated( 0 )
+ , animateFlip( false )
+ , forward( true )
+ , start( false )
+ , stop( false )
+ , addFullRepaint( false )
+ , rearrangeWindows( 0 )
+ , stopRequested( false )
+ , startRequested( false )
+ {
+ KConfigGroup conf = effects->effectConfig( "FlipSwitch" );
+ mFlipDuration = conf.readEntry( "FlipDuration", 300 );
+ mAnimation = conf.readEntry( "AnimateFlip", true );
+ }
+
+FlipSwitchEffect::~FlipSwitchEffect()
+ {
+ }
+
+void FlipSwitchEffect::prePaintScreen( ScreenPrePaintData& data, int time )
+ {
+ if( mActivated || stopRequested || stop )
+ {
+ data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
+ }
+ effects->prePaintScreen(data, time);
+ }
+
+void FlipSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
+ {
+ effects->paintScreen( mask, region, data );
+ if( mActivated || stopRequested || stop )
+ {
+#ifdef KWIN_HAVE_OPENGL_COMPOSITING
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix();
+ glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable( GL_DEPTH_TEST );
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ glEnable( GL_POLYGON_SMOOTH );
+ glLoadIdentity();
+ glFrustum(-QApplication::desktop()->geometry().width()*0.5f,
+ QApplication::desktop()->geometry().width()*0.5f,
+ QApplication::desktop()->geometry().height()*0.5f,
+ -QApplication::desktop()->geometry().height()*0.5f, 10, 50);
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ float xOffset = QApplication::desktop()->geometry().width()*0.33f;
+ float zOffset = 10.0;
+
+ // bring the selected window to the back of the list
+ QList< EffectWindow* > tempList = effects->currentTabBoxWindowList();
+ int index = tempList.indexOf( effects->currentTabBoxWindow() );
+ QList< EffectWindow* > windowList;
+ for( int i=index; irearrangeWindows; i-- )
+ {
+ EffectWindow* w = windowList.front();
+ windowList.pop_front();
+ windowList.append( w );
+ }
+ }
+ else
+ {
+ for( int i=0; ix()-QApplication::desktop()->geometry().width()*0.5f;
+ float y = -QApplication::desktop()->geometry().height()*1.5f+w->y()+w->height();
+ float z = -10.0;
+ if( w->isMinimized() )
+ {
+ // use icon instead of window
+ x = w->iconGeometry().x()-QApplication::desktop()->geometry().width()*0.5f;
+ y = -QApplication::desktop()->geometry().height()*1.5f+w->iconGeometry().y()+w->height();
+ }
+ // Position of the window in the stack
+ float stackX = -QApplication::desktop()->geometry().width()*0.25f-(xOffset*windowList.count())+xOffset*(i+1);
+ float stackY = -QApplication::desktop()->geometry().height()*0.5f;
+ float stackZ = (-1*zOffset*windowList.count()) -12.5+zOffset*(i+1);
+
+ float timeFactor = (float)((float)elapsed/(float)mFlipDuration);
+ // limit animation to final position
+ if( timeFactor > 1.0 ) timeFactor = 1.0;
+
+ float animateXOffset;
+ float animateYOffset;
+ float animateZOffset;
+ float rotation;
+ // if start move to stack, if stop move from stack
+ if( start )
+ {
+ animateXOffset = x+timeFactor*(stackX-x);
+ animateYOffset = y+timeFactor*(stackY-y);
+ animateZOffset = z+timeFactor*(stackZ-z);
+ rotation = timeFactor*0.25;
+ }
+ else if( stop )
+ {
+ animateXOffset = stackX+timeFactor*(x-stackX);
+ animateYOffset = stackY+timeFactor*(y-stackY);
+ animateZOffset = stackZ+timeFactor*(z-stackZ);
+ rotation = 0.25-timeFactor*0.25;
+ }
+
+ // go to current position and rotate by the time based factor
+ glTranslatef(animateXOffset, animateYOffset, animateZOffset );
+ glRotatef(rotation, 0.0, 1.0, 0.0);
+
+ // top most window has to be painted not drawn.
+ if( i= mFlipDuration )
+ {
+ if( start )
+ {
+ start = false;
+ // more animations have to follow?
+ if( rearrangeWindows != 0 )
+ {
+ animateFlip = true;
+ animationTime.restart();
+ if( rearrangeWindows < 0 )
+ {
+ forward = true;
+ rearrangeWindows++;
+ }
+ else
+ {
+ forward = false;
+ rearrangeWindows--;
+ }
+ }
+ else if( stopRequested )
+ {
+ // no more animations but effect has to stop
+ stop = true;
+ stopRequested = false;
+ animationTime.restart();
+ }
+ }
+ else if( stop )
+ {
+ stop = false;
+ if( startRequested )
+ {
+ // tabbox allready referenced again - so restart
+ start = true;
+ startRequested = false;
+ mActivated = true;
+ animationTime.restart();
+ }
+ else
+ {
+ mActivated = false;
+ // we need one more FullRepaint
+ addFullRepaint = true;
+ }
+ }
+ }
+ }
+ // normal behaviour - no start or stop animation
+ else
+ {
+ glPushMatrix();
+ glTranslatef(-QApplication::desktop()->geometry().width()*0.25f-(xOffset*windowList.count()),
+ -QApplication::desktop()->geometry().height()*0.5f,
+ (-1*zOffset*windowList.count()) -12.5);
+ int elapsed = animationTime.elapsed();
+ float timeFactor = (float)((float)elapsed/(float)mFlipDuration);
+ if( animateFlip && windowList.count() > 1 )
+ {
+ if( elapsed <= mFlipDuration)
+ {
+ float animateXOffset = timeFactor*xOffset;
+ float animateZOffset = timeFactor*zOffset;
+ if( forward )
+ {
+ if( animateXOffset > xOffset ) animateXOffset = xOffset;
+ if( animateZOffset > zOffset ) animateZOffset = zOffset;
+ glTranslatef(animateXOffset, 0.0, animateZOffset);
+ EffectWindow* w = windowList.front();
+ windowList.pop_front();
+ windowList.append( w );
+ }
+ else
+ {
+ animateXOffset = xOffset - animateXOffset;
+ animateZOffset = zOffset - animateZOffset;
+ if( animateXOffset < 0.0 ) animateXOffset = 0.0;
+ if( animateZOffset < 0.0 ) animateZOffset = 0.0;
+ glTranslatef(animateXOffset, 0.0, animateZOffset);
+ }
+ }
+ else
+ {
+ if( rearrangeWindows != 0 )
+ {
+ animateFlip = true;
+ animationTime.restart();
+ if( rearrangeWindows < 0 )
+ {
+ forward = true;
+ rearrangeWindows++;
+ timeFactor = 0.0;
+ }
+ else
+ {
+ forward = false;
+ rearrangeWindows--;
+ timeFactor = 1.0;
+ }
+ }
+ else
+ {
+ animateFlip = false;
+ if( stopRequested )
+ {
+ stop = true;
+ stopRequested = false;
+ animationTime.restart();
+ }
+ }
+ }
+ }
+ for( int i=0; i 1 )
+ {
+ if( forward ) opacity = opacity - timeFactor*opacity;
+ else opacity = timeFactor*opacity;
+ }
+ paintWindowFlip( windowList[i], false, opacity);
+ }
+ glPopMatrix();
+ }
+ glPopMatrix();
+ }
+ glPopAttrib();
+ glMatrixMode( GL_PROJECTION );
+ glPopMatrix();
+ glMatrixMode( GL_MODELVIEW );
+
+ // caption of selected window
+ QColor color_frame;
+ QColor color_text;
+ color_frame = KColorScheme( QPalette::Active, KColorScheme::Window ).background().color();
+ color_frame.setAlphaF( 0.9 );
+ color_text = KColorScheme( QPalette::Active, KColorScheme::Window ).foreground().color();
+ QFont text_font;
+ text_font.setBold( true );
+ text_font.setPointSize( 20 );
+ glPushAttrib( GL_CURRENT_BIT );
+ glColor4f( color_frame.redF(), color_frame.greenF(), color_frame.blueF(), color_frame.alphaF());
+ QRect frameRect = QRect( QApplication::desktop()->geometry().width()*0.25f,
+ QApplication::desktop()->geometry().height()*0.9f,
+ QApplication::desktop()->geometry().width()*0.5f,
+ QFontMetrics( text_font ).height() * 1.2 );
+ renderRoundBoxWithEdge( frameRect );
+ effects->paintText( effects->currentTabBoxWindow()->caption(),
+ frameRect.center(),
+ frameRect.width() - 100,
+ color_text,
+ text_font );
+ glPopAttrib();
+ // icon of selected window
+ GLTexture* icon = new GLTexture( effects->currentTabBoxWindow()->icon() );
+ icon->bind();
+ glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
+ icon->bind();
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ // icon takes 80 % of the height of the frame. So each 10 % space left on the top and botton
+ QRect iconRect = QRect( frameRect.x() + frameRect.height()*0.1f,
+ frameRect.y() + frameRect.height()*0.1f,
+ frameRect.height()*0.8f,
+ frameRect.height()*0.8f );
+ icon->render( false, region, iconRect);
+ icon->unbind();
+ glPopAttrib();
+#endif
+ }
+ }
+
+void FlipSwitchEffect::postPaintScreen()
+ {
+ if( (mActivated && ( animateFlip || start )) || stopRequested || stop )
+ {
+ effects->addRepaintFull();
+ }
+ if( addFullRepaint )
+ {
+ addFullRepaint = false;
+ effects->addRepaintFull();
+ }
+ effects->postPaintScreen();
+ }
+
+void FlipSwitchEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
+ {
+ if( mActivated || stopRequested || stop )
+ {
+ if( !( mask & PAINT_WINDOW_TRANSFORMED ) && ( !w->isDesktop() ) )
+ {
+ return;
+ }
+ }
+ effects->paintWindow( w, mask, region, data );
+ }
+
+void FlipSwitchEffect::tabBoxAdded( int mode )
+ {
+ if( !mActivated )
+ {
+ // only for windows mode
+ if( mode == TabBoxWindowsMode && effects->currentTabBoxWindowList().count() > 0 )
+ {
+ effects->refTabBox();
+ selectedWindow = effects->currentTabBoxWindowList().indexOf(effects->currentTabBoxWindow());
+ if( !stop && !stopRequested )
+ {
+ mActivated = true;
+ start = true;
+ animationTime.restart();
+ effects->addRepaintFull();
+ }
+ else
+ {
+ // last tabbox effect still running - schedule start effect
+ startRequested = true;
+ }
+ }
+ }
+ }
+void FlipSwitchEffect::tabBoxClosed()
+ {
+ if( mActivated )
+ {
+ // if animation than deactivate after animation
+ mActivated = false;
+ effects->unrefTabBox();
+ if( mAnimation )
+ {
+ if ( start || animateFlip ) stopRequested = true;
+ else
+ {
+ stop = true;
+ animationTime.restart();
+ effects->addRepaintFull();
+ }
+ }
+ }
+ }
+
+void FlipSwitchEffect::tabBoxUpdated()
+ {
+ if( mActivated )
+ {
+ if( mAnimation )
+ {
+ // determine the switch direction
+ int index = effects->currentTabBoxWindowList().indexOf(effects->currentTabBoxWindow());
+ bool direction = false;
+ if( index > selectedWindow )
+ {
+ if( index == effects->currentTabBoxWindowList().count()-1 && selectedWindow == 0 ) forward = false;
+ else direction = true;
+ }
+ else if( index == 0 && ( selectedWindow == effects->currentTabBoxWindowList().count()-1 ) )
+ {
+ direction = true;
+ }
+ else if( index == selectedWindow ) return; // nothing changed
+ else
+ {
+ direction = false;
+ }
+ selectedWindow = index;
+ if( !animateFlip && !start )
+ {
+ forward = direction;
+ animateFlip = true;
+ animationTime.restart();
+ }
+ else
+ {
+ if( direction ) rearrangeWindows--;
+ else rearrangeWindows++;
+ }
+ }
+ effects->addRepaintFull();
+ }
+ }
+
+void FlipSwitchEffect::paintWindowFlip( EffectWindow* w, bool draw, float opacity )
+ {
+ WindowPaintData data( w );
+
+ int x = 0;
+ int y = QApplication::desktop()->geometry().height() - w->geometry().height();
+ QRect thumbnail;
+ setPositionTransformations( data,
+ thumbnail, w,
+ QRect( x, y, w->geometry().width(), w->geometry().height() ),
+ Qt::KeepAspectRatio );
+
+ data.opacity = opacity;
+ // if paintWindow() is used the window behind the initial selected window is not painted on the stack,
+ // but painted when it is selected
+ // if drawWindow() is used the front window does not glide through the monitor during animation
+ // so use drawWindow() for all windows but the selected and paintWindow() for the selected window
+ if( draw )
+ effects->drawWindow( w,
+ PAINT_WINDOW_TRANSFORMED,
+ thumbnail, data );
+ else
+ effects->paintWindow( w,
+ PAINT_WINDOW_TRANSFORMED,
+ thumbnail, data );
+ }
+
+} // namespace
diff --git a/effects/flipswitch.desktop b/effects/flipswitch.desktop
new file mode 100644
index 0000000000..ea4076a892
--- /dev/null
+++ b/effects/flipswitch.desktop
@@ -0,0 +1,17 @@
+[Desktop Entry]
+Name=Flip Switch
+Icon=preferences-system-windows-effect-flipswitch
+Comment=Alt-tab window switcher flipping through windows on a stack
+
+Type=Service
+X-KDE-ServiceTypes=KWin/Effect
+X-KDE-PluginInfo-Author=Martin Gräßlin
+X-KDE-PluginInfo-Email=ubuntu@martin-graesslin.com
+X-KDE-PluginInfo-Name=kwin4_effect_flipswitch
+X-KDE-PluginInfo-Version=0.1.0
+X-KDE-PluginInfo-Category=Window Management
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+X-KDE-Library=kwin4_effect_builtins
+X-Ordering=50
diff --git a/effects/flipswitch.h b/effects/flipswitch.h
new file mode 100644
index 0000000000..b5d77fcd1f
--- /dev/null
+++ b/effects/flipswitch.h
@@ -0,0 +1,63 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Martin Gräßlin .
+*********************************************************************/
+
+#ifndef KWIN_FLIPSWITCH_H
+#define KWIN_FLIPSWITCH_H
+
+#include
+#include
+
+namespace KWin
+{
+
+class FlipSwitchEffect
+ : public Effect
+ {
+ public:
+ FlipSwitchEffect();
+ ~FlipSwitchEffect();
+
+ virtual void prePaintScreen( ScreenPrePaintData& data, int time );
+ virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
+ virtual void postPaintScreen();
+ virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
+ virtual void tabBoxAdded( int mode );
+ virtual void tabBoxClosed();
+ virtual void tabBoxUpdated();
+ private:
+ void paintWindowFlip( EffectWindow* w, bool draw = true, float opacity = 0.8 );
+ bool mActivated;
+ bool mAnimation;
+ int mFlipDuration;
+ bool animateFlip;
+ bool forward;
+ QTime animationTime;
+ int selectedWindow;
+ bool start;
+ bool stop;
+ bool addFullRepaint;
+ int rearrangeWindows;
+ bool stopRequested;
+ bool startRequested;
+ };
+
+} // namespace
+
+#endif
diff --git a/effects/flipswitch_config.cpp b/effects/flipswitch_config.cpp
new file mode 100644
index 0000000000..f9f666c784
--- /dev/null
+++ b/effects/flipswitch_config.cpp
@@ -0,0 +1,101 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Martin Gräßlin .
+*********************************************************************/
+#include "flipswitch_config.h"
+#include
+
+#include
+
+#include
+#ifndef KDE_USE_FINAL
+KWIN_EFFECT_CONFIG_FACTORY
+#endif
+
+namespace KWin
+{
+
+FlipSwitchEffectConfigForm::FlipSwitchEffectConfigForm(QWidget* parent) : QWidget(parent)
+{
+ setupUi(this);
+}
+
+FlipSwitchEffectConfig::FlipSwitchEffectConfig(QWidget* parent, const QVariantList& args) :
+ KCModule(EffectFactory::componentData(), parent, args)
+ {
+ m_ui = new FlipSwitchEffectConfigForm(this);
+
+ QGridLayout* layout = new QGridLayout(this);
+
+ layout->addWidget(m_ui, 0, 0);
+
+ connect(m_ui->checkAnimateFlip, SIGNAL(stateChanged(int)), this, SLOT(changed()));
+ connect(m_ui->spinFlipDuration, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+
+ load();
+ }
+
+FlipSwitchEffectConfig::~FlipSwitchEffectConfig()
+ {
+ }
+
+void FlipSwitchEffectConfig::load()
+ {
+ KCModule::load();
+
+ KConfigGroup conf = EffectsHandler::effectConfig( "FlipSwitch" );
+
+ int flipDuration = conf.readEntry( "FlipDuration", 300 );
+ bool animateFlip = conf.readEntry( "AnimateFlip", true );
+ m_ui->spinFlipDuration->setValue( flipDuration );
+ if( animateFlip )
+ {
+ m_ui->checkAnimateFlip->setCheckState( Qt::Checked );
+ }
+ else
+ {
+ m_ui->checkAnimateFlip->setCheckState( Qt::Unchecked );
+ }
+
+ emit changed(false);
+ }
+
+void FlipSwitchEffectConfig::save()
+ {
+ KConfigGroup conf = EffectsHandler::effectConfig( "FlipSwitch" );
+
+ conf.writeEntry( "FlipDuration", m_ui->spinFlipDuration->value() );
+ conf.writeEntry( "AnimateFlip", m_ui->checkAnimateFlip->checkState() == Qt::Checked ? true : false );
+
+ conf.sync();
+
+ emit changed(false);
+ EffectsHandler::sendReloadMessage( "flipswitch" );
+ }
+
+void FlipSwitchEffectConfig::defaults()
+ {
+ m_ui->spinFlipDuration->setValue( 300 );
+ m_ui->checkAnimateFlip->setCheckState( Qt::Checked );
+ emit changed(true);
+ }
+
+
+} // namespace
+
+#include "flipswitch_config.moc"
\ No newline at end of file
diff --git a/effects/flipswitch_config.desktop b/effects/flipswitch_config.desktop
new file mode 100755
index 0000000000..a85138fa7b
--- /dev/null
+++ b/effects/flipswitch_config.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=KCModule
+
+X-KDE-Library=kcm_kwin4_effect_builtins
+X-KDE-ParentComponents=kwin4_effect_flipswitch
+X-KDE-PluginKeyword=flipswitch
+
+Name=Flip Switch
\ No newline at end of file
diff --git a/effects/flipswitch_config.h b/effects/flipswitch_config.h
new file mode 100644
index 0000000000..d5656e1bdb
--- /dev/null
+++ b/effects/flipswitch_config.h
@@ -0,0 +1,58 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+ Copyright (C) 2008 Martin Gräßlin .
+*********************************************************************/
+
+#ifndef KWIN_FLIPSWITCH_CONFIG_H
+#define KWIN_FLIPSWITCH_CONFIG_H
+
+#define KDE3_SUPPORT
+#include
+#undef KDE3_SUPPORT
+
+#include "ui_flipswitch_config.h"
+
+namespace KWin
+{
+
+class FlipSwitchEffectConfigForm : public QWidget, public Ui::FlipSwitchEffectConfigForm
+{
+ Q_OBJECT
+ public:
+ explicit FlipSwitchEffectConfigForm(QWidget* parent);
+};
+
+class FlipSwitchEffectConfig : public KCModule
+ {
+ Q_OBJECT
+ public:
+ explicit FlipSwitchEffectConfig(QWidget* parent = 0, const QVariantList& args = QVariantList());
+ ~FlipSwitchEffectConfig();
+
+ public slots:
+ virtual void save();
+ virtual void load();
+ virtual void defaults();
+
+ private:
+ FlipSwitchEffectConfigForm* m_ui;
+ };
+
+} // namespace
+
+#endif
\ No newline at end of file
diff --git a/effects/flipswitch_config.ui b/effects/flipswitch_config.ui
new file mode 100644
index 0000000000..1e04bcf178
--- /dev/null
+++ b/effects/flipswitch_config.ui
@@ -0,0 +1,60 @@
+
+ KWin::FlipSwitchEffectConfigForm
+
+
+
+ 0
+ 0
+ 400
+ 103
+
+
+
+ -
+
+
+ Appearance
+
+
+
-
+
+
+ Animate &Flip
+
+
+
+ -
+
+
+ F&lip Animation Duration
+
+
+ spinFlipDuration
+
+
+
+ -
+
+
+ msec
+
+
+ 5000
+
+
+ 750
+
+
+
+
+
+
+
+
+
+ checkAnimateFlip
+ spinFlipDuration
+
+
+
+