From 10bfb82e8c822007a2b2566a83a1c0e28158363c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Sat, 14 Apr 2007 15:33:12 +0000 Subject: [PATCH] Make PresentWindows effect work properly even with idle paint passes (i.e. trigger next repaint properly and react on mouse events). svn path=/branches/work/kwin_composite/; revision=653921 --- COMPOSITE_TODO | 2 ++ effects.cpp | 6 +++++ effects.h | 1 + effects/presentwindows.cpp | 54 +++++++++++++++++++++++++++++--------- effects/presentwindows.h | 1 + lib/kwineffects.cpp | 4 +++ lib/kwineffects.h | 1 + scene.cpp | 7 ++--- 8 files changed, 61 insertions(+), 15 deletions(-) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index 78e506af4d..a452fc6501 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -177,6 +177,8 @@ Effects framework TODO + API for tabbox for effects should be cleaned up +* check Scene::updateTimeDiff() - should the time be 0 or 1? + Effects TODO =============================== diff --git a/effects.cpp b/effects.cpp index b9379afb6c..102302d547 100644 --- a/effects.cpp +++ b/effects.cpp @@ -231,6 +231,12 @@ bool EffectsHandlerImpl::borderActivated( ElectricBorder border ) return ret; } +void EffectsHandlerImpl::cursorMoved( const QPoint& pos, Qt::MouseButtons buttons ) + { + foreach( EffectPair ep, loaded_effects ) + ep.second->cursorMoved( pos, buttons ); + } + void EffectsHandlerImpl::activateWindow( EffectWindow* c ) { if( Client* cl = dynamic_cast< Client* >( static_cast(c)->window())) diff --git a/effects.h b/effects.h index 6c14b8351f..5c9dcfccf0 100644 --- a/effects.h +++ b/effects.h @@ -90,6 +90,7 @@ class EffectsHandlerImpl : public EffectsHandler void tabBoxClosed(); void tabBoxUpdated(); bool borderActivated( ElectricBorder border ); + void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons ); void loadEffect( const QString& name ); void unloadEffect( const QString& name ); diff --git a/effects/presentwindows.cpp b/effects/presentwindows.cpp index b2a370fbe4..aab9033a60 100644 --- a/effects/presentwindows.cpp +++ b/effects/presentwindows.cpp @@ -27,11 +27,12 @@ namespace KWin KWIN_EFFECT( PresentWindows, PresentWindowsEffect ) -PresentWindowsEffect::PresentWindowsEffect() : QObject(), Effect() +PresentWindowsEffect::PresentWindowsEffect() + : mShowWindowsFromAllDesktops ( false ) + , mActivated( false ) + , mActiveness( 0.0 ) + , mHoverWindow( NULL ) { - mShowWindowsFromAllDesktops = false; - mActivated = false; - mActiveness = 0.0; KActionCollection* actionCollection = new KActionCollection( this ); KAction* a = (KAction*)actionCollection->addAction( "Expose" ); @@ -126,11 +127,15 @@ void PresentWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion regio void PresentWindowsEffect::postPaintScreen() { - // If mActiveness is between 0 and 1, the effect is still in progress and the - // workspace has to be repainted during the next pass - if( mActiveness > 0.0 && mActiveness < 1.0 ) - effects->addRepaintFull(); // trigger next animation repaint - + if( mActivated && mActiveness < 1.0 ) // activating effect + effects->addRepaintFull(); + if( !mActivated && mActiveness > 0.0 ) // deactivating effect + effects->addRepaintFull(); + foreach( const WindowData& d, mWindowData ) + { + if( d.hover > 0 && d.hover < 1 ) // changing highlight + effects->addRepaintFull(); + } // Call the next effect. effects->postPaintScreen(); } @@ -138,6 +143,25 @@ void PresentWindowsEffect::postPaintScreen() void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e ) { assert( w == mInput ); + if( e->type() == QEvent::MouseMove ) + { // Repaint if the hovered-over window changed. + // (No need to use cursorMoved(), this takes care of it as well) + for( QHash::ConstIterator it = mWindowData.begin(); + it != mWindowData.end(); + ++it ) + { + if( (*it).area.contains( cursorPos())) + { + if( mHoverWindow != it.key()) + { + mHoverWindow = it.key(); + effects->addRepaintFull(); // screen is transformed, so paint all + } + return; + } + } + return; + } if( e->type() != QEvent::MouseButtonPress ) return; @@ -161,20 +185,26 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e ) void PresentWindowsEffect::windowActivated( EffectWindow* ) { - rearrangeWindows(); + rearrangeWindows(); } -void PresentWindowsEffect::windowClosed( EffectWindow* ) +void PresentWindowsEffect::windowClosed( EffectWindow* w ) { - rearrangeWindows(); + if( mHoverWindow == w ) + mHoverWindow = NULL; + rearrangeWindows(); } void PresentWindowsEffect::setActive(bool active) { + if( mActivated == active ) + return; mActivated = active; + mHoverWindow = NULL; rearrangeWindows(); if( mActivated && mActiveness == 0.0f ) effectActivated(); + effects->addRepaintFull(); // trigger next animation repaint } void PresentWindowsEffect::effectActivated() diff --git a/effects/presentwindows.h b/effects/presentwindows.h index 58aba8413b..e1c6f89a89 100644 --- a/effects/presentwindows.h +++ b/effects/presentwindows.h @@ -78,6 +78,7 @@ class PresentWindowsEffect float hover; }; QHash mWindowData; + EffectWindow* mHoverWindow; ElectricBorder borderActivate; ElectricBorder borderActivateAll; diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index 61e2ed8eda..8f98d449ef 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -114,6 +114,10 @@ bool Effect::borderActivated( ElectricBorder ) return false; } +void Effect::cursorMoved( const QPoint&, Qt::MouseButtons ) + { + } + void Effect::prePaintScreen( int* mask, QRegion* region, int time ) { effects->prePaintScreen( mask, region, time ); diff --git a/lib/kwineffects.h b/lib/kwineffects.h index d28c84a150..1764884975 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -98,6 +98,7 @@ class KWIN_EXPORT Effect virtual void desktopChanged( int old ); virtual void windowDamaged( EffectWindow* w, const QRect& r ); virtual void windowGeometryShapeChanged( EffectWindow* w, const QRect& old ); + virtual void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons ); virtual void tabBoxAdded( int mode ); virtual void tabBoxClosed(); diff --git a/scene.cpp b/scene.cpp index 8435df714a..0b30a9df88 100644 --- a/scene.cpp +++ b/scene.cpp @@ -129,13 +129,14 @@ void Scene::updateTimeDiff() { // Painting has been idle (optimized out) for some time, // which means time_diff would be huge and would break animations. - // Simply set it to zero. - time_diff = 0; + // Simply set it to one (zero would mean no change at all and could + // cause problems). + time_diff = 1; } else time_diff = last_time.elapsed(); if( time_diff < 0 ) // check time rollback - time_diff = 0; + time_diff = 1; last_time.start();; }