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
* check Scene::updateTimeDiff() - should the time be 0 or 1?
Effects TODO
===============================

View file

@ -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<EffectWindowImpl*>(c)->window()))

View file

@ -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 );

View file

@ -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<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 )
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()

View file

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

View file

@ -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 );

View file

@ -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();

View file

@ -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();;
}