diff --git a/composite.cpp b/composite.cpp index 0f2117e154..b266899333 100644 --- a/composite.cpp +++ b/composite.cpp @@ -156,6 +156,7 @@ void Workspace::compositeTimeout() else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] ))) windows.append( c ); } + effects->startPaint(); // TODO when effects cause damage, it should be only enqueued for next repaint QRegion r = damage_region; damage_region = QRegion(); diff --git a/effects.cpp b/effects.cpp index 57bf1a1f26..e5c9feddfb 100644 --- a/effects.cpp +++ b/effects.cpp @@ -39,22 +39,22 @@ void Effect::windowDeleted( Toplevel* ) void Effect::prePaintScreen( int* mask, QRegion* region, int time ) { - effects->nextPrePaintScreen( mask, region, time ); + effects->prePaintScreen( mask, region, time ); } void Effect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) { - effects->nextPaintScreen( mask, region, data ); + effects->paintScreen( mask, region, data ); } void Effect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) { - effects->nextPrePaintWindow( w, mask, region, time ); + effects->prePaintWindow( w, mask, region, time ); } void Effect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) { - effects->nextPaintWindow( w, mask, region, data ); + effects->paintWindow( w, mask, region, data ); } void MakeHalfTransparent::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) @@ -65,7 +65,7 @@ void MakeHalfTransparent::prePaintWindow( Scene::Window* w, int* mask, QRegion* *mask |= Scene::PAINT_WINDOW_TRANSLUCENT; *mask &= ~Scene::PAINT_WINDOW_OPAQUE; } - effects->nextPrePaintWindow( w, mask, region, time ); + effects->prePaintWindow( w, mask, region, time ); } void MakeHalfTransparent::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) @@ -75,7 +75,7 @@ void MakeHalfTransparent::paintWindow( Scene::Window* w, int mask, QRegion regio data.opacity *= 0.8; if( c->isMove() || c->isResize()) data.opacity *= 0.5; - effects->nextPaintWindow( w, mask, region, data ); + effects->paintWindow( w, mask, region, data ); } void MakeHalfTransparent::windowUserMovedResized( Toplevel* c, bool first, bool last ) @@ -96,21 +96,21 @@ void ShakyMove::prePaintScreen( int* mask, QRegion* region, int time ) { if( !windows.isEmpty()) *mask |= Scene::PAINT_WINDOW_TRANSFORMED; - effects->nextPrePaintScreen( mask, region, time ); + effects->prePaintScreen( mask, region, time ); } void ShakyMove::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) { if( windows.contains( w->window())) *mask |= Scene::PAINT_WINDOW_TRANSFORMED; - effects->nextPrePaintWindow( w, mask, region, time ); + effects->prePaintWindow( w, mask, region, time ); } void ShakyMove::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) { if( windows.contains( w->window())) data.xTranslate += shaky_diff[ windows[ w->window() ]]; - effects->nextPaintWindow( w, mask, region, data ); + effects->paintWindow( w, mask, region, data ); } void ShakyMove::windowUserMovedResized( Toplevel* c, bool first, bool last ) @@ -201,14 +201,14 @@ void ShiftWorkspaceUp::prePaintScreen( int* mask, QRegion* region, int time ) } if( diff != 0 ) *mask |= Scene::PAINT_SCREEN_TRANSFORMED; - effects->nextPrePaintScreen( mask, region, time ); + effects->prePaintScreen( mask, region, time ); } void ShiftWorkspaceUp::paintScreen( int mask, QRegion region, ScreenPaintData& data ) { if( diff != 0 ) data.yTranslate -= diff / 100; - effects->nextPaintScreen( mask, region, data ); + effects->paintScreen( mask, region, data ); } void ShiftWorkspaceUp::tick() @@ -234,7 +234,7 @@ void FadeIn::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int t else windows.remove( w->window()); } - effects->nextPrePaintWindow( w, mask, region, time ); + effects->prePaintWindow( w, mask, region, time ); } void FadeIn::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) @@ -243,7 +243,7 @@ void FadeIn::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPain { data.opacity *= windows[ w->window()]; } - effects->nextPaintWindow( w, mask, region, data ); + effects->paintWindow( w, mask, region, data ); } void FadeIn::windowAdded( Toplevel* c ) @@ -277,7 +277,7 @@ void ScaleIn::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int else windows.remove( w->window()); } - effects->nextPrePaintWindow( w, mask, region, time ); + effects->prePaintWindow( w, mask, region, time ); } void ScaleIn::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) @@ -289,7 +289,7 @@ void ScaleIn::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPai data.xTranslate += w->window()->width() / 2 * ( 1 - windows[ w->window()] ); data.yTranslate += w->window()->height() / 2 * ( 1 - windows[ w->window()] ); } - effects->nextPaintWindow( w, mask, region, data ); + effects->paintWindow( w, mask, region, data ); } void ScaleIn::windowAdded( Toplevel* c ) @@ -349,61 +349,54 @@ void EffectsHandler::windowDeleted( Toplevel* c ) e->windowDeleted( c ); } -void EffectsHandler::prePaintScreen( int* mask, QRegion* region, int time, Effect* final ) +// start another painting pass +void EffectsHandler::startPaint() { assert( current_paint_screen == 0 ); - effects.append( final ); - nextPrePaintScreen( mask, region, time ); - effects.pop_back(); - } - -void EffectsHandler::paintScreen( int mask, QRegion region, ScreenPaintData& data, Effect* final ) - { - assert( current_paint_screen == 0 ); - effects.append( final ); - nextPaintScreen( mask, region, data ); - effects.pop_back(); - } - -void EffectsHandler::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time, Effect* final ) - { assert( current_paint_window == 0 ); - effects.append( final ); - nextPrePaintWindow( w, mask, region, time ); - effects.pop_back(); - } - -void EffectsHandler::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data, Effect* final ) - { - assert( current_paint_window == 0 ); - effects.append( final ); - nextPaintWindow( w, mask, region, data ); - effects.pop_back(); } // the idea is that effects call this function again which calls the next one -void EffectsHandler::nextPrePaintScreen( int* mask, QRegion* region, int time ) +void EffectsHandler::prePaintScreen( int* mask, QRegion* region, int time ) { - effects[ current_paint_screen++ ]->prePaintScreen( mask, region, time ); - --current_paint_screen; + if( current_paint_screen < effects.size() - 1 ) + { + effects[ current_paint_screen++ ]->prePaintScreen( mask, region, time ); + --current_paint_screen; + } + // no special final code } -void EffectsHandler::nextPaintScreen( int mask, QRegion region, ScreenPaintData& data ) +void EffectsHandler::paintScreen( int mask, QRegion region, ScreenPaintData& data ) { - effects[ current_paint_screen++ ]->paintScreen( mask, region, data ); - --current_paint_screen; + if( current_paint_screen < effects.size() - 1 ) + { + effects[ current_paint_screen++ ]->paintScreen( mask, region, data ); + --current_paint_screen; + } + else + scene->finalPaintScreen( mask, region, data ); } -void EffectsHandler::nextPrePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) +void EffectsHandler::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) { - effects[ current_paint_window++ ]->prePaintWindow( w, mask, region, time ); - --current_paint_window; + if( current_paint_window < effects.size() - 1 ) + { + effects[ current_paint_window++ ]->prePaintWindow( w, mask, region, time ); + --current_paint_window; + } + // no special final code } -void EffectsHandler::nextPaintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) +void EffectsHandler::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) { - effects[ current_paint_window++ ]->paintWindow( w, mask, region, data ); - --current_paint_window; + if( current_paint_window < effects.size() - 1 ) + { + effects[ current_paint_window++ ]->paintWindow( w, mask, region, data ); + --current_paint_window; + } + else + scene->finalPaintWindow( w, mask, region, data ); } EffectsHandler* effects; diff --git a/effects.h b/effects.h index 3e06916e96..097b980142 100644 --- a/effects.h +++ b/effects.h @@ -64,15 +64,12 @@ class EffectsHandler EffectsHandler( Workspace* ws ); ~EffectsHandler(); // for use by effects - void nextPrePaintScreen( int* mask, QRegion* region, int time ); - void nextPaintScreen( int mask, QRegion region, ScreenPaintData& data ); - void nextPrePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ); - void nextPaintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ); + void prePaintScreen( int* mask, QRegion* region, int time ); + void paintScreen( int mask, QRegion region, ScreenPaintData& data ); + void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ); + void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ); // internal (used by kwin core or compositing code) - void prePaintScreen( int* mask, QRegion* region, int time, Effect* final ); - void paintScreen( int mask, QRegion region, ScreenPaintData& data, Effect* final ); - void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time, Effect* final ); - void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data, Effect* final ); + void startPaint(); void windowUserMovedResized( Toplevel* c, bool first, bool last ); void windowAdded( Toplevel* c ); void windowDeleted( Toplevel* c ); @@ -164,20 +161,6 @@ class ScaleIn QMap< const Toplevel*, double > windows; }; -// a special effect that is last in the order that'll actually call the painting functions -// TODO this should actually be in scene.h -class Scene::WrapperEffect - : public Effect - { - public: - virtual ~WrapperEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); - virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ); - virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ); - }; - - inline WindowPaintData::WindowPaintData() : opacity( 1.0 ) diff --git a/scene.cpp b/scene.cpp index c472f0d9a4..c38c9dee5a 100644 --- a/scene.cpp +++ b/scene.cpp @@ -18,14 +18,6 @@ License. See the file "COPYING" for the exact licensing terms. namespace KWinInternal { -//**************************************** -// Scene::WrapperEffect -//**************************************** - -Scene::WrapperEffect::~WrapperEffect() - { - } - //**************************************** // Scene //**************************************** @@ -46,15 +38,14 @@ void Scene::paintScreen( int* mask, QRegion* region ) { *mask = ( *region == QRegion( 0, 0, displayWidth(), displayHeight())) ? 0 : PAINT_SCREEN_REGION; - WrapperEffect wrapper; updateTimeDiff(); // preparation step - effects->prePaintScreen( mask, region, time_diff, &wrapper ); + effects->prePaintScreen( mask, region, time_diff ); if( *mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED )) *mask &= ~PAINT_SCREEN_REGION; // TODO call also prePaintWindow() for all windows ScreenPaintData data; - effects->paintScreen( *mask, *region, data, &wrapper ); + effects->paintScreen( *mask, *region, data ); } void Scene::updateTimeDiff() @@ -76,18 +67,13 @@ void Scene::idle() last_time = QTime(); } -void Scene::WrapperEffect::prePaintScreen( int*, QRegion*, int ) - { - // nothing, no changes - } - // the function that'll be eventually called by paintScreen() above -void Scene::WrapperEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) +void Scene::finalPaintScreen( int mask, QRegion region, ScreenPaintData& data ) { if( mask & PAINT_SCREEN_REGION ) - scene->paintSimpleScreen( mask, region ); + paintSimpleScreen( mask, region ); else - scene->paintGenericScreen( mask, data ); + paintGenericScreen( mask, data ); } // the generic painting code that should eventually handle even @@ -101,9 +87,8 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData ) continue; int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); QRegion damage = infiniteRegion(); - WrapperEffect wrapper; // preparation step - effects->prePaintWindow( w, &mask, &damage, time_diff, &wrapper ); + effects->prePaintWindow( w, &mask, &damage, time_diff ); paintWindow( w, mask, damage ); } } @@ -127,9 +112,8 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region ) continue; int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); QRegion damage = region; - WrapperEffect wrapper; // preparation step - effects->prePaintWindow( w, &mask, &damage, time_diff, &wrapper ); + effects->prePaintWindow( w, &mask, &damage, time_diff ); if( mask & PAINT_WINDOW_TRANSLUCENT ) phase2.prepend( Phase2Data( w, region, mask )); if( mask & PAINT_WINDOW_OPAQUE ) @@ -151,21 +135,15 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region ) } } -void Scene::WrapperEffect::prePaintWindow( Scene::Window* , int*, QRegion*, int ) - { - // nothing, no changes - } - void Scene::paintWindow( Window* w, int mask, QRegion region ) { WindowPaintData data; data.opacity = w->window()->opacity(); - WrapperEffect wrapper; - effects->paintWindow( w, mask, region, data, &wrapper ); + effects->paintWindow( w, mask, region, data ); } // the function that'll be eventually called by paintWindow() above -void Scene::WrapperEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) +void Scene::finalPaintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) { w->performPaint( mask, region, data ); } diff --git a/scene.h b/scene.h index 2dd13d9dcb..88472c0dad 100644 --- a/scene.h +++ b/scene.h @@ -51,9 +51,12 @@ class Scene void idle(); protected: void paintScreen( int* mask, QRegion* region ); + friend class EffectsHandler; + void finalPaintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void paintGenericScreen( int mask, ScreenPaintData data ); virtual void paintSimpleScreen( int mask, QRegion region ); virtual void paintBackground( QRegion region ) = 0; + void finalPaintWindow( Window* w, int mask, QRegion region, WindowPaintData& data ); virtual void paintWindow( Window* w, int mask, QRegion region ); static QRegion infiniteRegion(); void updateTimeDiff(); @@ -68,7 +71,6 @@ class Scene int time_diff; QTime last_time; Workspace* wspace; - class WrapperEffect; }; class Scene::Window