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
This commit is contained in:
Luboš Luňák 2007-04-14 15:33:12 +00:00
parent 23c579452e
commit 10bfb82e8c
8 changed files with 61 additions and 15 deletions

View file

@ -177,6 +177,8 @@ Effects framework TODO
+ API for tabbox for effects should be cleaned up + API for tabbox for effects should be cleaned up
* check Scene::updateTimeDiff() - should the time be 0 or 1?
Effects TODO Effects TODO
=============================== ===============================

View file

@ -231,6 +231,12 @@ bool EffectsHandlerImpl::borderActivated( ElectricBorder border )
return ret; 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 ) void EffectsHandlerImpl::activateWindow( EffectWindow* c )
{ {
if( Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(c)->window())) if( Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(c)->window()))

View file

@ -90,6 +90,7 @@ class EffectsHandlerImpl : public EffectsHandler
void tabBoxClosed(); void tabBoxClosed();
void tabBoxUpdated(); void tabBoxUpdated();
bool borderActivated( ElectricBorder border ); bool borderActivated( ElectricBorder border );
void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons );
void loadEffect( const QString& name ); void loadEffect( const QString& name );
void unloadEffect( const QString& name ); void unloadEffect( const QString& name );

View file

@ -27,11 +27,12 @@ namespace KWin
KWIN_EFFECT( PresentWindows, PresentWindowsEffect ) 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 ); KActionCollection* actionCollection = new KActionCollection( this );
KAction* a = (KAction*)actionCollection->addAction( "Expose" ); KAction* a = (KAction*)actionCollection->addAction( "Expose" );
@ -126,11 +127,15 @@ void PresentWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion regio
void PresentWindowsEffect::postPaintScreen() void PresentWindowsEffect::postPaintScreen()
{ {
// If mActiveness is between 0 and 1, the effect is still in progress and the if( mActivated && mActiveness < 1.0 ) // activating effect
// workspace has to be repainted during the next pass effects->addRepaintFull();
if( mActiveness > 0.0 && mActiveness < 1.0 ) if( !mActivated && mActiveness > 0.0 ) // deactivating effect
effects->addRepaintFull(); // trigger next animation repaint effects->addRepaintFull();
foreach( const WindowData& d, mWindowData )
{
if( d.hover > 0 && d.hover < 1 ) // changing highlight
effects->addRepaintFull();
}
// Call the next effect. // Call the next effect.
effects->postPaintScreen(); effects->postPaintScreen();
} }
@ -138,6 +143,25 @@ void PresentWindowsEffect::postPaintScreen()
void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e ) void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e )
{ {
assert( w == mInput ); 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<EffectWindow*, WindowData>::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 ) if( e->type() != QEvent::MouseButtonPress )
return; return;
@ -164,17 +188,23 @@ void PresentWindowsEffect::windowActivated( EffectWindow* )
rearrangeWindows(); rearrangeWindows();
} }
void PresentWindowsEffect::windowClosed( EffectWindow* ) void PresentWindowsEffect::windowClosed( EffectWindow* w )
{ {
if( mHoverWindow == w )
mHoverWindow = NULL;
rearrangeWindows(); rearrangeWindows();
} }
void PresentWindowsEffect::setActive(bool active) void PresentWindowsEffect::setActive(bool active)
{ {
if( mActivated == active )
return;
mActivated = active; mActivated = active;
mHoverWindow = NULL;
rearrangeWindows(); rearrangeWindows();
if( mActivated && mActiveness == 0.0f ) if( mActivated && mActiveness == 0.0f )
effectActivated(); effectActivated();
effects->addRepaintFull(); // trigger next animation repaint
} }
void PresentWindowsEffect::effectActivated() void PresentWindowsEffect::effectActivated()

View file

@ -78,6 +78,7 @@ class PresentWindowsEffect
float hover; float hover;
}; };
QHash<EffectWindow*, WindowData> mWindowData; QHash<EffectWindow*, WindowData> mWindowData;
EffectWindow* mHoverWindow;
ElectricBorder borderActivate; ElectricBorder borderActivate;
ElectricBorder borderActivateAll; ElectricBorder borderActivateAll;

View file

@ -114,6 +114,10 @@ bool Effect::borderActivated( ElectricBorder )
return false; return false;
} }
void Effect::cursorMoved( const QPoint&, Qt::MouseButtons )
{
}
void Effect::prePaintScreen( int* mask, QRegion* region, int time ) void Effect::prePaintScreen( int* mask, QRegion* region, int time )
{ {
effects->prePaintScreen( mask, region, time ); effects->prePaintScreen( mask, region, time );

View file

@ -98,6 +98,7 @@ class KWIN_EXPORT Effect
virtual void desktopChanged( int old ); virtual void desktopChanged( int old );
virtual void windowDamaged( EffectWindow* w, const QRect& r ); virtual void windowDamaged( EffectWindow* w, const QRect& r );
virtual void windowGeometryShapeChanged( EffectWindow* w, const QRect& old ); virtual void windowGeometryShapeChanged( EffectWindow* w, const QRect& old );
virtual void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons );
virtual void tabBoxAdded( int mode ); virtual void tabBoxAdded( int mode );
virtual void tabBoxClosed(); virtual void tabBoxClosed();

View file

@ -129,13 +129,14 @@ void Scene::updateTimeDiff()
{ {
// Painting has been idle (optimized out) for some time, // Painting has been idle (optimized out) for some time,
// which means time_diff would be huge and would break animations. // which means time_diff would be huge and would break animations.
// Simply set it to zero. // Simply set it to one (zero would mean no change at all and could
time_diff = 0; // cause problems).
time_diff = 1;
} }
else else
time_diff = last_time.elapsed(); time_diff = last_time.elapsed();
if( time_diff < 0 ) // check time rollback if( time_diff < 0 ) // check time rollback
time_diff = 0; time_diff = 1;
last_time.start();; last_time.start();;
} }