Add a global configuration option for animation speed. See description

of Effect::animationTime() for how-to-use.
TODO: Effects need to reload config after doing the change in the kcm.
NOTE: Default TimeLine constructor now creates invalid object, it is
necessary to explicitly call setDuration() in order to ensure all
animations respect this setting.

CCMAIL: kwin@kde.org


svn path=/trunk/KDE/kdebase/workspace/; revision=854690
icc-effect-5.14.5
Luboš Luňák 2008-08-30 07:25:54 +00:00
parent d3bc4b05d5
commit 2a87593638
45 changed files with 214 additions and 80 deletions

View File

@ -188,6 +188,9 @@ Effects framework TODO
Effects TODO
===============================
! add reloadConfig() to effects
- currently changing the global animation speed in the kcm does not change effect
+ minimize/shade effects
- to replace the ones from KWin core
/ - minimizing

View File

@ -419,6 +419,11 @@ int EffectsHandlerImpl::desktopDown( int desktop, bool wrap ) const
return Workspace::self()->desktopDown( desktop, wrap );
}
double EffectsHandlerImpl::animationTimeFactor() const
{
return options->animationTimeFactor();
}
int EffectsHandlerImpl::displayWidth() const
{
return KWin::displayWidth();

View File

@ -99,6 +99,7 @@ class EffectsHandlerImpl : public EffectsHandler
virtual int desktopToRight( int desktop, bool wrap ) const;
virtual int desktopUp( int desktop, bool wrap ) const;
virtual int desktopDown( int desktop, bool wrap ) const;
virtual double animationTimeFactor() const;
virtual Window createInputWindow( Effect* e, int x, int y, int w, int h, const QCursor& cursor );
using EffectsHandler::createInputWindow;

View File

@ -52,7 +52,7 @@ CoverSwitchEffect::CoverSwitchEffect()
, twinview( false )
{
KConfigGroup conf = effects->effectConfig( "CoverSwitch" );
animationDuration = conf.readEntry( "Duration", 200 );
animationDuration = animationTime( conf, "Duration", 200 );
animateSwitch = conf.readEntry( "AnimateSwitch", true );
animateStart = conf.readEntry( "AnimateStart", true );
animateStop = conf.readEntry( "AnimateStop", true );

View File

@ -59,7 +59,7 @@ void CoverSwitchEffectConfig::load()
KConfigGroup conf = EffectsHandler::effectConfig( "CoverSwitch" );
int duration = conf.readEntry( "Duration", 200 );
int duration = conf.readEntry( "Duration", 0 );
bool animateSwitch = conf.readEntry( "AnimateSwitch", true );
bool animateStart = conf.readEntry( "AnimateStart", true );
bool animateStop = conf.readEntry( "AnimateStop", true );
@ -119,7 +119,7 @@ void CoverSwitchEffectConfig::save()
void CoverSwitchEffectConfig::defaults()
{
m_ui->spinDuration->setValue( 200 );
m_ui->spinDuration->setValue( 0 );
m_ui->checkAnimateSwitch->setCheckState( Qt::Checked );
m_ui->checkAnimateStart->setCheckState( Qt::Checked );
m_ui->checkAnimateStop->setCheckState( Qt::Checked );

View File

@ -56,14 +56,17 @@
</item>
<item row="4" column="1" >
<widget class="QSpinBox" name="spinDuration" >
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>200</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>

View File

@ -99,7 +99,7 @@ void CubeEffect::loadConfig( QString config )
cubeOpacity = (float)conf.readEntry( "Opacity", 80 )/100.0f;
displayDesktopName = conf.readEntry( "DisplayDesktopName", true );
reflection = conf.readEntry( "Reflection", true );
rotationDuration = conf.readEntry( "RotationDuration", 500 );
rotationDuration = animationTime( conf, "RotationDuration", 500 );
backgroundColor = conf.readEntry( "BackgroundColor", QColor( Qt::black ) );
animateDesktopChange = conf.readEntry( "AnimateDesktopChange", false );
bigCube = conf.readEntry( "BigCube", false );

View File

@ -103,7 +103,7 @@ void CubeEffectConfig::load()
KConfigGroup conf = EffectsHandler::effectConfig( "Cube" );
int duration = conf.readEntry( "RotationDuration", 500 );
int duration = conf.readEntry( "RotationDuration", 0 );
float opacity = conf.readEntry( "Opacity", 80 );
bool desktopName = conf.readEntry( "DisplayDesktopName", true );
bool reflection = conf.readEntry( "Reflection", true );
@ -230,7 +230,7 @@ void CubeEffectConfig::save()
void CubeEffectConfig::defaults()
{
m_ui->rotationDurationSpin->setValue( 500 );
m_ui->rotationDurationSpin->setValue( 0 );
m_ui->displayDesktopNameBox->setCheckState( Qt::Checked );
m_ui->reflectionBox->setCheckState( Qt::Checked );
m_ui->cubeOpacitySpin->setValue( 80 );

View File

@ -5,7 +5,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<width>568</width>
<height>595</height>
</rect>
</property>
@ -20,8 +20,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>545</width>
<height>553</height>
<width>546</width>
<height>552</height>
</rect>
</property>
<attribute name="title" >
@ -133,14 +133,17 @@
<height>0</height>
</size>
</property>
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>500</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>
@ -444,6 +447,7 @@ Otherwise cube will stay in the position.</string>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KWin::GlobalShortcutsEditor</class>

View File

@ -99,7 +99,7 @@ void CylinderEffectConfig::load()
KConfigGroup conf = EffectsHandler::effectConfig( "Cylinder" );
int duration = conf.readEntry( "RotationDuration", 500 );
int duration = conf.readEntry( "RotationDuration", 0 );
float opacity = conf.readEntry( "Opacity", 80 );
bool desktopName = conf.readEntry( "DisplayDesktopName", true );
bool reflection = conf.readEntry( "Reflection", true );
@ -206,7 +206,7 @@ void CylinderEffectConfig::save()
void CylinderEffectConfig::defaults()
{
m_ui->rotationDurationSpin->setValue( 500 );
m_ui->rotationDurationSpin->setValue( 0 );
m_ui->displayDesktopNameBox->setCheckState( Qt::Checked );
m_ui->reflectionBox->setCheckState( Qt::Checked );
m_ui->cubeOpacitySpin->setValue( 80 );

View File

@ -5,7 +5,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<width>568</width>
<height>595</height>
</rect>
</property>
@ -20,8 +20,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>545</width>
<height>553</height>
<width>546</width>
<height>552</height>
</rect>
</property>
<attribute name="title" >
@ -133,14 +133,17 @@
<height>0</height>
</size>
</property>
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>500</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>
@ -423,6 +426,7 @@ Otherwise cylinder will stay in the position.</string>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KWin::GlobalShortcutsEditor</class>

View File

@ -65,7 +65,7 @@ DesktopGridEffect::DesktopGridEffect()
borderActivate = ElectricBorder( conf.readEntry( "BorderActivate", int( ElectricNone )));
effects->reserveElectricBorder( borderActivate );
zoomDuration = conf.readEntry( "ZoomDuration", 500 );
zoomDuration = animationTime( conf, "ZoomDuration", 500 );
timeline.setCurveShape( TimeLine::EaseInOutCurve );
timeline.setDuration( zoomDuration );
@ -595,7 +595,7 @@ void DesktopGridEffect::setup()
hoverTimeline.clear();
for( int i = 0; i < effects->numberOfDesktops(); i++ )
{
TimeLine newTimeline;
TimeLine newTimeline( animationTime( 250 ));
newTimeline.setCurveShape( TimeLine::EaseInOutCurve );
hoverTimeline.append( newTimeline );
}

View File

@ -120,7 +120,7 @@ void DesktopGridEffectConfig::load()
activateBorder--;
m_ui->screenEdgeCombo->setCurrentIndex( activateBorder );
m_ui->zoomDurationSpin->setValue( conf.readEntry( "ZoomDuration", 500 ));
m_ui->zoomDurationSpin->setValue( conf.readEntry( "ZoomDuration", 0 ));
m_ui->borderWidthSpin->setValue( conf.readEntry( "BorderWidth", 10 ));
Qt::Alignment alignment = Qt::Alignment( conf.readEntry( "DesktopNameAlignment", 0 ));
@ -169,7 +169,7 @@ void DesktopGridEffectConfig::save()
void DesktopGridEffectConfig::defaults()
{
m_ui->screenEdgeCombo->setCurrentIndex( int( ElectricNone - 1 ));
m_ui->zoomDurationSpin->setValue( 500 );
m_ui->zoomDurationSpin->setValue( 0 );
m_ui->borderWidthSpin->setValue( 10 );
m_ui->desktopNameAlignmentCombo->setCurrentIndex( 0 );
m_ui->layoutBox->setCheckState( Qt::Unchecked );

View File

@ -28,14 +28,17 @@
</item>
<item row="2" column="1" >
<widget class="QSpinBox" name="zoomDurationSpin" >
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>500</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>

View File

@ -28,7 +28,7 @@ KWIN_EFFECT( dialogparent, DialogParentEffect )
void DialogParentEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
{
// How long does it take for the effect to get it's full strength (in ms)
const double changeTime = 200;
const double changeTime = animationTime( 200 );
// Check if this window has a modal dialog and change the window's
// effect's strength accordingly

View File

@ -32,7 +32,7 @@ KWIN_EFFECT( dimscreen, DimScreenEffect )
DimScreenEffect::DimScreenEffect()
: mActivated( false )
, animationDuration( 300 )
, animationDuration( Effect::animationTime( 300 ))
, animation( false )
, deactivate( false )
{

View File

@ -127,7 +127,7 @@ void ExplosionEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
mValid = loadData();
if( mValid )
{
mWindows[ w ] += time / 700.0; // complete change in 700ms
mWindows[ w ] += time / animationTime( 700.0 ); // complete change in 700ms
if( mWindows[ w ] < 1 )
{
data.setTranslucent();

View File

@ -30,8 +30,8 @@ KWIN_EFFECT( fade, FadeEffect )
FadeEffect::FadeEffect()
{
KConfigGroup conf = effects->effectConfig( "Fade" );
fadeInTime = qMax( conf.readEntry( "FadeInTime", 150 ), 1 );
fadeOutTime = qMax( conf.readEntry( "FadeOutTime", 150 ), 1 );
fadeInTime = animationTime( conf, "FadeInTime", 150 );
fadeOutTime = animationTime( conf, "FadeOutTime", 150 );
fadeWindows = conf.readEntry( "FadeWindows", true );
}

View File

@ -41,7 +41,7 @@ void FallApartEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
{
if( windows[ w ] < 1 )
{
windows[ w ] += time / 1000.;
windows[ w ] += time / animationTime( 1000. );
data.setTransformed();
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE );
// Request the window to be divided into cells

View File

@ -49,7 +49,7 @@ FlipSwitchEffect::FlipSwitchEffect()
, twinview( false )
{
KConfigGroup conf = effects->effectConfig( "FlipSwitch" );
mFlipDuration = conf.readEntry( "FlipDuration", 200 );
mFlipDuration = animationTime( conf, "FlipDuration", 200 );
mAnimation = conf.readEntry( "AnimateFlip", true );
timeLine.setCurveShape( TimeLine::EaseInOutCurve );
timeLine.setDuration( mFlipDuration );

View File

@ -60,7 +60,7 @@ void FlipSwitchEffectConfig::load()
KConfigGroup conf = EffectsHandler::effectConfig( "FlipSwitch" );
int flipDuration = conf.readEntry( "FlipDuration", 200 );
int flipDuration = conf.readEntry( "FlipDuration", 0 );
bool animateFlip = conf.readEntry( "AnimateFlip", true );
m_ui->spinFlipDuration->setValue( flipDuration );
if( animateFlip )
@ -90,7 +90,7 @@ void FlipSwitchEffectConfig::save()
void FlipSwitchEffectConfig::defaults()
{
m_ui->spinFlipDuration->setValue( 200 );
m_ui->spinFlipDuration->setValue( 0 );
m_ui->checkAnimateFlip->setCheckState( Qt::Checked );
emit changed(true);
}

View File

@ -38,14 +38,17 @@
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="spinFlipDuration" >
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>200</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>

View File

@ -39,7 +39,7 @@ void LoginEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if( progress != 1 )
{
progress = qBound( 0., progress + time / 2000., 1. );
progress = qBound( 0., progress + time / animationTime( 2000. ), 1. );
if( progress == 1 )
{
login_window->unrefWindow();

View File

@ -45,9 +45,9 @@ LogoutEffect::LogoutEffect()
void LogoutEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if( logout_window != NULL )
progress = qBound( 0., progress + time / 2000., 1. );
progress = qBound( 0., progress + time / animationTime( 2000. ), 1. );
else if( progress != 0 )
progress = qBound( 0., progress - time / 500., 1. );
progress = qBound( 0., progress - time / animationTime( 500. ), 1. );
effects->prePaintScreen( data, time );
}

View File

@ -98,7 +98,7 @@ void LookingGlassEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if( zoom != target_zoom )
{
double diff = time / 500.0;
double diff = time / animationTime( 500.0 );
if( target_zoom > zoom )
zoom = qMin( zoom * qMax( 1.0 + diff, 1.2 ), target_zoom );
else

View File

@ -247,14 +247,14 @@ void MagicLampEffect::postPaintScreen()
void MagicLampEffect::windowMinimized( EffectWindow* w )
{
mTimeLineWindows[w].setCurveShape(TimeLine::LinearCurve);
mTimeLineWindows[w].setDuration( 250 );
mTimeLineWindows[w].setDuration( animationTime( 250 ));
mTimeLineWindows[w].setProgress(0.0f);
}
void MagicLampEffect::windowUnminimized( EffectWindow* w )
{
mTimeLineWindows[w].setCurveShape(TimeLine::LinearCurve);
mTimeLineWindows[w].setDuration( 250 );
mTimeLineWindows[w].setDuration( animationTime( 250 ));
mTimeLineWindows[w].setProgress(1.0f);
}

View File

@ -64,7 +64,7 @@ void MagnifierEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if( zoom != target_zoom )
{
double diff = time / 500.0;
double diff = time / animationTime( 500.0 );
if( target_zoom > zoom )
zoom = qMin( zoom * qMax( 1 + diff, 1.2 ), target_zoom );
else

View File

@ -54,9 +54,9 @@ MakeTransparentEffect::MakeTransparentEffect()
}
active = effects->activeWindow();
moveresize_timeline.setCurveShape( TimeLine::EaseOutCurve );
moveresize_timeline.setDuration( conf.readEntry( "Duration", 800 ) );
moveresize_timeline.setDuration( animationTime( conf, "Duration", 800 ) );
activeinactive_timeline.setCurveShape( TimeLine::EaseInOutCurve );
activeinactive_timeline.setDuration( conf.readEntry( "Duration", 800 ) );
activeinactive_timeline.setDuration( animationTime( conf, "Duration", 800 ) );
}
void MakeTransparentEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )

View File

@ -93,7 +93,7 @@ void MakeTransparentEffectConfig::load()
m_ui->dropdownmenus->setValue( (int)( conf.readEntry( "DropdownMenus", 1.0) * 100 ) );
m_ui->popupmenus->setValue( (int)( conf.readEntry( "PopupMenus", 1.0) * 100 ) );
m_ui->tornoffmenus->setValue( (int)( conf.readEntry( "TornOffMenus", 1.0) * 100 ) );
m_ui->duration->setValue( conf.readEntry( "Duration", 1800) );
m_ui->duration->setValue( conf.readEntry( "Duration", 0) );
setIndividualMenuConfig( m_ui->individualmenuconfig->isChecked() ? Qt::Checked : Qt::Unchecked );
emit changed(false);
@ -135,7 +135,7 @@ void MakeTransparentEffectConfig::defaults()
m_ui->dropdownmenus->setValue( 100 );
m_ui->popupmenus->setValue( 100 );
m_ui->tornoffmenus->setValue( 100 );
m_ui->duration->setValue( 1500 );
m_ui->duration->setValue( 0 );
emit changed(true);
}

View File

@ -346,9 +346,6 @@
<property name="pageStep" >
<number>100</number>
</property>
<property name="value" >
<number>1500</number>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
@ -370,6 +367,9 @@
<height>0</height>
</size>
</property>
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string>msec</string>
</property>
@ -379,9 +379,6 @@
<property name="singleStep" >
<number>100</number>
</property>
<property name="value" >
<number>1500</number>
</property>
</widget>
</item>
</layout>
@ -398,8 +395,8 @@
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel" >
<x>433</x>
<y>282</y>
<x>476</x>
<y>280</y>
</hint>
<hint type="destinationlabel" >
<x>246</x>
@ -418,8 +415,8 @@
<y>283</y>
</hint>
<hint type="destinationlabel" >
<x>433</x>
<y>282</y>
<x>476</x>
<y>280</y>
</hint>
</hints>
</connection>

View File

@ -110,12 +110,14 @@ void MinimizeAnimationEffect::postPaintScreen()
void MinimizeAnimationEffect::windowMinimized( EffectWindow* w )
{
mTimeLineWindows[w].setCurveShape(TimeLine::EaseInCurve);
mTimeLineWindows[w].setDuration( animationTime( 250 ));
mTimeLineWindows[w].setProgress(0.0f);
}
void MinimizeAnimationEffect::windowUnminimized( EffectWindow* w )
{
mTimeLineWindows[w].setCurveShape(TimeLine::EaseOutCurve);
mTimeLineWindows[w].setDuration( animationTime( 250 ));
mTimeLineWindows[w].setProgress(1.0f);
}

View File

@ -77,9 +77,9 @@ PresentWindowsEffect::PresentWindowsEffect()
effects->reserveElectricBorder( borderActivateAll );
mActiveness.setCurveShape( TimeLine::EaseInOutCurve );
mActiveness.setDuration( conf.readEntry( "RearrangeDuration", 250 ));
mActiveness.setDuration( animationTime( conf, "RearrangeDuration", 250 ));
mRearranging.setCurveShape( TimeLine::EaseInOutCurve );
mRearranging.setDuration( conf.readEntry( "RearrangeDuration", 250 ));
mRearranging.setDuration( animationTime( conf, "RearrangeDuration", 250 ));
mRearranging.setProgress( 1.0 );
}
@ -129,7 +129,7 @@ void PresentWindowsEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData&
data.setTranslucent();
// Change window's highlight
WindowData& windata = mWindowData[w];
const double highlightchangetime = 100;
const double highlightchangetime = animationTime( 100 );
if( w == mHighlightedWindow )
windata.highlight = qMin(1.0, windata.highlight + time / highlightchangetime);
else

View File

@ -114,7 +114,7 @@ void PresentWindowsEffectConfig::load()
int layoutMode = conf.readEntry( "LayoutMode", int( PresentWindowsEffect::LayoutNatural ));
m_ui->layoutCombo->setCurrentIndex( layoutMode );
m_ui->rearrangeDurationSpin->setValue( conf.readEntry( "RearrangeDuration", 250 ));
m_ui->rearrangeDurationSpin->setValue( conf.readEntry( "RearrangeDuration", 0 ));
bool displayTitle = conf.readEntry( "DrawWindowCaptions", true );
m_ui->displayTitleBox->setChecked( displayTitle );
@ -185,7 +185,7 @@ void PresentWindowsEffectConfig::save()
void PresentWindowsEffectConfig::defaults()
{
m_ui->layoutCombo->setCurrentIndex( int( PresentWindowsEffect::LayoutNatural ));
m_ui->rearrangeDurationSpin->setValue( 250 );
m_ui->rearrangeDurationSpin->setValue( 0 );
m_ui->displayTitleBox->setChecked( true );
m_ui->displayIconBox->setChecked( true );
m_ui->switchingBox->setChecked( false );

View File

@ -28,14 +28,20 @@
</item>
<item row="2" column="1" >
<widget class="QSpinBox" name="rearrangeDurationSpin" >
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="singleStep" >
<number>10</number>
</property>
<property name="value" >
<number>250</number>
<number>0</number>
</property>
</widget>
</item>

View File

@ -78,6 +78,7 @@ void ScaleInEffect::windowAdded( EffectWindow* c )
{
if( c->isOnCurrentDesktop())
{
mTimeLineWindows[ c ].setDuration( animationTime( 250 ));
mTimeLineWindows[ c ].setProgress( 0.0 );
c->addRepaintFull();
}

View File

@ -32,6 +32,7 @@ SlideEffect::SlideEffect()
: slide( false )
{
mTimeLine.setCurveShape(TimeLine::EaseInOutCurve);
mTimeLine.setDuration( animationTime( 250 ));
}
void SlideEffect::prePaintScreen( ScreenPrePaintData& data, int time )

View File

@ -99,7 +99,7 @@ void SphereEffectConfig::load()
KConfigGroup conf = EffectsHandler::effectConfig( "Sphere" );
int duration = conf.readEntry( "RotationDuration", 500 );
int duration = conf.readEntry( "RotationDuration", 0 );
float opacity = conf.readEntry( "Opacity", 80 );
bool desktopName = conf.readEntry( "DisplayDesktopName", true );
int activateBorder = conf.readEntry( "BorderActivate", (int)ElectricNone );
@ -198,7 +198,7 @@ void SphereEffectConfig::save()
void SphereEffectConfig::defaults()
{
m_ui->rotationDurationSpin->setValue( 500 );
m_ui->rotationDurationSpin->setValue( 0 );
m_ui->displayDesktopNameBox->setCheckState( Qt::Checked );
m_ui->cubeOpacitySpin->setValue( 80 );
m_ui->cubeOpacitySlider->setValue( 80 );

View File

@ -5,7 +5,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<width>568</width>
<height>595</height>
</rect>
</property>
@ -20,8 +20,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>545</width>
<height>553</height>
<width>546</width>
<height>552</height>
</rect>
</property>
<attribute name="title" >
@ -126,14 +126,17 @@
<height>0</height>
</size>
</property>
<property name="specialValueText" >
<string>Default</string>
</property>
<property name="suffix" >
<string> msec</string>
</property>
<property name="maximum" >
<number>5000</number>
</property>
<property name="value" >
<number>500</number>
<property name="singleStep" >
<number>10</number>
</property>
</widget>
</item>
@ -486,6 +489,7 @@ Otherwise sphere will stay in the position.</string>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KWin::GlobalShortcutsEditor</class>

View File

@ -47,7 +47,7 @@ void ZoomEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if( zoom != target_zoom )
{
double diff = time / 500.0;
double diff = time / animationTime( 500.0 );
if( target_zoom > zoom )
zoom = qMin( zoom * qMax( 1 + diff, 1.2 ), target_zoom );
else

View File

@ -92,6 +92,7 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
connect(ui.windowSwitchingCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
connect(ui.desktopSwitchingCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
connect(ui.animationSpeedCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
// Open the temporary config file
// Temporary conf file is used to syncronize effect checkboxes with effect
@ -264,6 +265,7 @@ void KWinCompositingConfig::loadGeneralTab()
{
KConfigGroup config(mKWinConfig, "Compositing");
ui.useCompositing->setChecked(config.readEntry("Enabled", mDefaultPrefs.enableCompositing()));
ui.animationSpeedCombo->setCurrentIndex(config.readEntry("AnimationSpeed", 3 ));
// Load effect settings
KConfigGroup effectconfig(mTmpConfig, "Plugins");
@ -340,6 +342,7 @@ void KWinCompositingConfig::saveGeneralTab()
}
config.writeEntry("Enabled", ui.useCompositing->isChecked());
config.writeEntry("AnimationSpeed", ui.animationSpeedCombo->currentIndex());
// Save effects
KConfigGroup effectconfig(mTmpConfig, "Plugins");
@ -489,6 +492,7 @@ void KWinCompositingConfig::defaults()
ui.windowSwitchingCombo->setCurrentIndex( 1 );
ui.desktopSwitchingCombo->setCurrentIndex( 1 );
ui.animationSpeedCombo->setCurrentIndex( 3 );
ui.effectSelector->defaults();
}

View File

@ -20,12 +20,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>591</width>
<height>619</height>
<width>585</width>
<height>618</height>
</rect>
</property>
<attribute name="title" >
<string comment="@option:check">General</string>
<string>General</string>
</attribute>
<layout class="QVBoxLayout" >
<item>
@ -103,13 +103,62 @@
<item row="4" column="1" >
<widget class="QComboBox" name="desktopSwitchingCombo" />
</item>
<item row="5" column="0" colspan="2" >
<item row="6" column="0" colspan="2" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>You can find more effects in the 'All Effects' tab</string>
</property>
</widget>
</item>
<item row="5" column="1" >
<widget class="QComboBox" name="animationSpeedCombo" >
<property name="currentIndex" >
<number>3</number>
</property>
<item>
<property name="text" >
<string>Instant</string>
</property>
</item>
<item>
<property name="text" >
<string>Very fast</string>
</property>
</item>
<item>
<property name="text" >
<string>Fast</string>
</property>
</item>
<item>
<property name="text" >
<string>Normal</string>
</property>
</item>
<item>
<property name="text" >
<string>Slow</string>
</property>
</item>
<item>
<property name="text" >
<string>Very slow</string>
</property>
</item>
<item>
<property name="text" >
<string>Extremely slow</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>Animation speed</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -256,6 +256,17 @@ QPoint Effect::cursorPos()
return effects->cursorPos();
}
double Effect::animationTime( const KConfigGroup& cfg, const QString& key, int defaultTime )
{
int time = cfg.readEntry( key, 0 );
return time != 0 ? time : qMax( defaultTime * effects->animationTimeFactor(), 1. );
}
double Effect::animationTime( int defaultTime )
{ // at least 1ms, otherwise 0ms times can break some things
return qMax( defaultTime * effects->animationTimeFactor(), 1. );
}
//****************************************
// EffectsHandler
//****************************************

View File

@ -163,7 +163,7 @@ X-KDE-Library=kwin4_effect_cooleffect
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
#define KWIN_EFFECT_API_VERSION_MINOR 53
#define KWIN_EFFECT_API_VERSION_MINOR 54
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
@ -372,6 +372,22 @@ class KWIN_EXPORT Effect
static int displayHeight();
static QPoint cursorPos();
/**
* Read animation time from the configuration and possibly adjust using animationTimeFactor().
* The configuration value in the effect should also have special value 'default' (set using
* QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted
* using the global animation speed, otherwise the exact time configured is returned.
* @param cfg configuration group to read value from
* @param key configuration key to read value from
* @param defaultTime default animation time in milliseconds
*/
// return type is intentionally double so that one can divide using it without losing data
static double animationTime( const KConfigGroup& cfg, const QString& key, int defaultTime );
/**
* @overload Use this variant if the animation time is hardcoded and not configurable
* in the effect itself.
*/
static double animationTime( int defaultTime );
/**
* Linearly interpolates between @p x and @p y.
*
@ -488,6 +504,14 @@ class KWIN_EXPORT EffectsHandler
virtual int desktopToRight( int desktop, bool wrap ) const = 0;
virtual int desktopUp( int desktop, bool wrap ) const = 0;
virtual int desktopDown( int desktop, bool wrap ) const = 0;
/**
* Factor by which animation speed in the effect should be modified (multiplied).
* If configurable in the effect itself, the option should have also 'default'
* animation speed. The actual value should be determined using animationTime().
* Note: The factor can be also 0, so make sure your code can cope with 0ms time
* if used manually.
*/
virtual double animationTimeFactor() const = 0;
virtual EffectWindow* findWindow( WId id ) const = 0;
virtual EffectWindowList stackingOrder() const = 0;
@ -1072,12 +1096,12 @@ class KWIN_EXPORT TimeLine
};
/**
* Creates a TimeLine and computes the progress data. The default
* duration can be overridden from the Effect. Usually, for larger
* Creates a TimeLine and computes the progress data. Usually, for larger
* animations you want to choose values more towards 300 milliseconds.
* For small animations, values around 150 milliseconds are sensible.
* Note that duration 0 is not valid.
*/
explicit TimeLine(const int duration = 250);
explicit TimeLine(int duration = 0);
/**
* Creates a copy of the TimeLine so we can have the state copied

View File

@ -235,6 +235,7 @@ void Options::reloadCompositingSettings(const CompositingPrefs& prefs)
hiddenPreviews = HiddenPreviewsAlways;
unredirectFullscreen = config.readEntry( "UnredirectFullscreen", true );
animationSpeed = qBound( 0, config.readEntry( "AnimationSpeed", 3 ), 6 );
}
@ -355,4 +356,10 @@ const char* Options::moveResizeModeToString( MoveResizeMode mode )
return mode == Opaque ? "Opaque" : "Transparent";
}
double Options::animationTimeFactor() const
{
const double factors[] = { 0, 0.2, 0.5, 1, 2, 4, 20 };
return factors[ animationSpeed ];
}
} // namespace

View File

@ -309,6 +309,7 @@ class Options : public KDecorationOptions
bool glDirect;
bool glVSync;
bool glStrictBinding;
double animationTimeFactor() const;
private:
WindowOperation OpTitlebarDblClick;
@ -337,6 +338,7 @@ class Options : public KDecorationOptions
bool desktop_topmenu;
// List of window classes for which not to use focus stealing prevention
QStringList ignoreFocusStealingClasses;
int animationSpeed; // 0 - instant, 5 - very slow
MouseCommand wheelToMouseCommand( MouseWheelCommand com, int delta );
void reloadCompositingSettings(const CompositingPrefs& prefs);