Alternative Alt+Tab window switcher which displays all windows on a 3D stack and flips through the stack
svn path=/trunk/KDE/kdebase/workspace/; revision=765574
This commit is contained in:
parent
80342f99da
commit
e4834f296b
9 changed files with 825 additions and 0 deletions
|
@ -96,6 +96,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
|
||||||
SET(kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
|
SET(kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
|
||||||
blur.cpp
|
blur.cpp
|
||||||
explosioneffect.cpp
|
explosioneffect.cpp
|
||||||
|
flipswitch.cpp
|
||||||
invert.cpp
|
invert.cpp
|
||||||
lookingglass.cpp
|
lookingglass.cpp
|
||||||
magnifier.cpp
|
magnifier.cpp
|
||||||
|
@ -108,6 +109,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
|
||||||
install( FILES
|
install( FILES
|
||||||
blur.desktop
|
blur.desktop
|
||||||
explosion.desktop
|
explosion.desktop
|
||||||
|
flipswitch.desktop
|
||||||
invert.desktop
|
invert.desktop
|
||||||
lookingglass.desktop
|
lookingglass.desktop
|
||||||
magnifier.desktop
|
magnifier.desktop
|
||||||
|
@ -139,6 +141,8 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
|
||||||
data/circle-edgy.png
|
data/circle-edgy.png
|
||||||
DESTINATION ${DATA_INSTALL_DIR}/kwin )
|
DESTINATION ${DATA_INSTALL_DIR}/kwin )
|
||||||
SET(kwin4_effect_builtins_config_sources ${kwin4_effect_builtins_config_sources}
|
SET(kwin4_effect_builtins_config_sources ${kwin4_effect_builtins_config_sources}
|
||||||
|
flipswitch_config.cpp
|
||||||
|
flipswitch_config.ui
|
||||||
invert_config.cpp
|
invert_config.cpp
|
||||||
lookingglass_config.cpp
|
lookingglass_config.cpp
|
||||||
lookingglass_config.ui
|
lookingglass_config.ui
|
||||||
|
@ -152,6 +156,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
|
||||||
trackmouse_config.cpp
|
trackmouse_config.cpp
|
||||||
)
|
)
|
||||||
install( FILES
|
install( FILES
|
||||||
|
flipswitch_config.desktop
|
||||||
invert_config.desktop
|
invert_config.desktop
|
||||||
lookingglass_config.desktop
|
lookingglass_config.desktop
|
||||||
magnifier_config.desktop
|
magnifier_config.desktop
|
||||||
|
|
|
@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "zoom_config.h"
|
#include "zoom_config.h"
|
||||||
|
|
||||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
#include "flipswitch_config.h"
|
||||||
#include "invert_config.h"
|
#include "invert_config.h"
|
||||||
#include "lookingglass_config.h"
|
#include "lookingglass_config.h"
|
||||||
#include "mousemark_config.h"
|
#include "mousemark_config.h"
|
||||||
|
@ -56,6 +57,7 @@ KWIN_EFFECT_CONFIG_FACTORY
|
||||||
registerPlugin<KWin::ZoomEffectConfig>("zoom");
|
registerPlugin<KWin::ZoomEffectConfig>("zoom");
|
||||||
|
|
||||||
#define GL_PLUGINS \
|
#define GL_PLUGINS \
|
||||||
|
registerPlugin<KWin::FlipSwitchEffectConfig>("flipswitch"); \
|
||||||
registerPlugin<KWin::InvertEffectConfig>("invert"); \
|
registerPlugin<KWin::InvertEffectConfig>("invert"); \
|
||||||
registerPlugin<KWin::LookingGlassEffectConfig>("lookingglass"); \
|
registerPlugin<KWin::LookingGlassEffectConfig>("lookingglass"); \
|
||||||
registerPlugin<KWin::MouseMarkEffectConfig>("mousemark"); \
|
registerPlugin<KWin::MouseMarkEffectConfig>("mousemark"); \
|
||||||
|
|
510
effects/flipswitch.cpp
Normal file
510
effects/flipswitch.cpp
Normal file
|
@ -0,0 +1,510 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*********************************************************************/
|
||||||
|
#include "flipswitch.h"
|
||||||
|
|
||||||
|
#include <kwinconfig.h>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QFont>
|
||||||
|
#include <kapplication.h>
|
||||||
|
#include <kcolorscheme.h>
|
||||||
|
#include <kconfiggroup.h>
|
||||||
|
|
||||||
|
#include <kwinglutils.h>
|
||||||
|
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#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; i<tempList.count(); i++)
|
||||||
|
{
|
||||||
|
windowList.push_front( tempList[i] );
|
||||||
|
}
|
||||||
|
for( int i=0; i<index; i++)
|
||||||
|
{
|
||||||
|
windowList.push_front( tempList[i] );
|
||||||
|
}
|
||||||
|
// do we have to rearrange the windows as an animation has to follow?
|
||||||
|
if( rearrangeWindows != 0 )
|
||||||
|
{
|
||||||
|
if( rearrangeWindows < 0 )
|
||||||
|
{
|
||||||
|
for( int i=0; i>rearrangeWindows; i-- )
|
||||||
|
{
|
||||||
|
EffectWindow* w = windowList.front();
|
||||||
|
windowList.pop_front();
|
||||||
|
windowList.append( w );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( int i=0; i<rearrangeWindows; i++ )
|
||||||
|
{
|
||||||
|
EffectWindow* w = windowList.back();
|
||||||
|
windowList.pop_back();
|
||||||
|
windowList.prepend( w );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have a start or stop animation
|
||||||
|
if( ( start || stop ) && mAnimation )
|
||||||
|
{
|
||||||
|
int elapsed = animationTime.elapsed();
|
||||||
|
for( int i=0; i<windowList.count(); i++)
|
||||||
|
{
|
||||||
|
glPushMatrix();
|
||||||
|
EffectWindow *w = windowList[ i ];
|
||||||
|
// Position of the window in OpenGL
|
||||||
|
float x = w->x()-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<windowList.count()-1 )
|
||||||
|
{
|
||||||
|
paintWindowFlip( windowList[i] );
|
||||||
|
}
|
||||||
|
else paintWindowFlip( windowList[i], false);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
// time elapsed - so no more animation
|
||||||
|
if( elapsed >= 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<windowList.count(); i++)
|
||||||
|
{
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(xOffset*(i+1), 0.0, zOffset*(i+1));
|
||||||
|
glRotatef(0.25, 0.0, 1.0, 0.0);
|
||||||
|
// top most window has to be painted not drawn.
|
||||||
|
if( i<windowList.count()-1 )
|
||||||
|
{
|
||||||
|
paintWindowFlip( windowList[i] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// last window - change opacity if animated
|
||||||
|
float opacity = 0.8;
|
||||||
|
if( animateFlip && windowList.count() > 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
|
17
effects/flipswitch.desktop
Normal file
17
effects/flipswitch.desktop
Normal file
|
@ -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
|
63
effects/flipswitch.h
Normal file
63
effects/flipswitch.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef KWIN_FLIPSWITCH_H
|
||||||
|
#define KWIN_FLIPSWITCH_H
|
||||||
|
|
||||||
|
#include <kwineffects.h>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
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
|
101
effects/flipswitch_config.cpp
Normal file
101
effects/flipswitch_config.cpp
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*********************************************************************/
|
||||||
|
#include "flipswitch_config.h"
|
||||||
|
#include <kwineffects.h>
|
||||||
|
|
||||||
|
#include <kconfiggroup.h>
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#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"
|
9
effects/flipswitch_config.desktop
Executable file
9
effects/flipswitch_config.desktop
Executable file
|
@ -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
|
58
effects/flipswitch_config.h
Normal file
58
effects/flipswitch_config.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef KWIN_FLIPSWITCH_CONFIG_H
|
||||||
|
#define KWIN_FLIPSWITCH_CONFIG_H
|
||||||
|
|
||||||
|
#define KDE3_SUPPORT
|
||||||
|
#include <kcmodule.h>
|
||||||
|
#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
|
60
effects/flipswitch_config.ui
Normal file
60
effects/flipswitch_config.ui
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>KWin::FlipSwitchEffectConfigForm</class>
|
||||||
|
<widget class="QWidget" name="KWin::FlipSwitchEffectConfigForm" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>103</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>Appearance</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" >
|
||||||
|
<item row="0" column="0" colspan="2" >
|
||||||
|
<widget class="QCheckBox" name="checkAnimateFlip" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Animate &Flip</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>F&lip Animation Duration</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>spinFlipDuration</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" >
|
||||||
|
<widget class="QSpinBox" name="spinFlipDuration" >
|
||||||
|
<property name="suffix" >
|
||||||
|
<string> msec</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<number>5000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<number>750</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>checkAnimateFlip</tabstop>
|
||||||
|
<tabstop>spinFlipDuration</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Loading…
Reference in a new issue