diff --git a/effects/snow.cpp b/effects/snow.cpp index f4d6db9bc2..fe9b01f8a2 100644 --- a/effects/snow.cpp +++ b/effects/snow.cpp @@ -49,6 +49,7 @@ SnowEffect::SnowEffect() : texture( NULL ) , flakes( NULL ) , active( false) + , snowBehindWindows( false ) { srandom( std::time( NULL ) ); lastFlakeTime = QTime::currentTime(); @@ -75,6 +76,7 @@ void SnowEffect::reconfigure( ReconfigureFlags ) mMaxFlakeSize = conf.readEntry("MaxFlakes", 50); mMaxVSpeed = conf.readEntry("MaxVSpeed", 2); mMaxHSpeed = conf.readEntry("MaxHSpeed", 1); + snowBehindWindows = conf.readEntry("BehindWindows", false); } void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time ) @@ -133,42 +135,48 @@ void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time ) void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) { effects->paintScreen( mask, region, data ); // paint normal screen -#ifdef KWIN_HAVE_OPENGL_COMPOSITING - if( active ) - { - if(! texture ) loadTexture(); - if( texture ) - { - glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT ); - texture->bind(); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + if( active && !snowBehindWindows ) + snowing( region ); + } - for (int i=0; icount(); i++) - { - SnowFlake flake = flakes->at(i); - - // save the matrix - glPushMatrix(); - - // translate to the center of the flake - glTranslatef(flake.getWidth()/2 + flake.getX(), flake.getHeight()/2 + flake.getY(), 0); - - // rotate around the Z-axis - glRotatef(flake.getRotationAngle(), 0.0, 0.0, 1.0); - - // translate back to the starting point - glTranslatef(-flake.getWidth()/2 - flake.getX(), -flake.getHeight()/2 - flake.getY(), 0); - - // paint the snowflake - texture->render( region, flake.getRect()); - - // restore the matrix - glPopMatrix(); - } - texture->unbind(); - glPopAttrib(); +void SnowEffect::snowing( QRegion& region ) + { +#ifdef KWIN_HAVE_OPENGL_COMPOSITING + if(! texture ) loadTexture(); + if( texture ) + { + glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT ); + texture->bind(); + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + glNewList( list, GL_COMPILE_AND_EXECUTE ); + for (int i=0; icount(); i++) + { + SnowFlake flake = flakes->at(i); + + // save the matrix + glPushMatrix(); + + // translate to the center of the flake + glTranslatef(flake.getWidth()/2 + flake.getX(), flake.getHeight()/2 + flake.getY(), 0); + + // rotate around the Z-axis + glRotatef(flake.getRotationAngle(), 0.0, 0.0, 1.0); + + // translate back to the starting point + glTranslatef(-flake.getWidth()/2 - flake.getX(), -flake.getHeight()/2 - flake.getY(), 0); + + // paint the snowflake + texture->render( region, flake.getRect()); + + // restore the matrix + glPopMatrix(); } + glEndList(); + glDisable( GL_BLEND ); + texture->unbind(); + glPopAttrib(); } #endif } @@ -182,10 +190,25 @@ void SnowEffect::postPaintScreen() effects->postPaintScreen(); } +void SnowEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + effects->paintWindow( w, mask, region, data ); + if( active && w->isDesktop() && snowBehindWindows ) + snowing( region ); + } + void SnowEffect::toggle() { active = !active; - if (!active) flakes->clear(); + if( active ) + { + list = glGenLists(1); + } + else + { + glDeleteLists( list, 1 ); + flakes->clear(); + } effects->addRepaintFull(); } diff --git a/effects/snow.h b/effects/snow.h index 187153867b..2331e819c8 100644 --- a/effects/snow.h +++ b/effects/snow.h @@ -71,11 +71,13 @@ class SnowEffect virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); private slots: void toggle(); private: void loadTexture(); + void snowing( QRegion& region ); GLTexture* texture; QList* flakes; QTime lastFlakeTime; @@ -86,6 +88,8 @@ class SnowEffect int mMaxVSpeed; int mMaxHSpeed; bool active; + GLuint list; + bool snowBehindWindows; }; } // namespace diff --git a/effects/snow_config.cpp b/effects/snow_config.cpp index ab594836fd..ae86940002 100644 --- a/effects/snow_config.cpp +++ b/effects/snow_config.cpp @@ -56,6 +56,7 @@ SnowEffectConfig::SnowEffectConfig(QWidget* parent, const QVariantList& args) : connect(m_ui->maxSizeFlake, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(m_ui->maxVSpeed, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(m_ui->maxHSpeed, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(m_ui->snowBehindWindows, SIGNAL(stateChanged(int)), this, SLOT(changed())); m_actionCollection = new KActionCollection( this, componentData() ); m_actionCollection->setConfigGroup("Snow"); @@ -88,6 +89,7 @@ void SnowEffectConfig::load() int maxFlake = conf.readEntry("MaxFlakes", 50); int maxVSpeed = conf.readEntry("MaxVSpeed", 2); int maxHSpeed = conf.readEntry("MaxHSpeed", 1); + m_ui->snowBehindWindows->setChecked( conf.readEntry("BehindWindows", false)); m_ui->numberFlakes->setValue( number ); m_ui->minSizeFlake->setValue( minFlake ); m_ui->maxSizeFlake->setValue( maxFlake ); @@ -108,6 +110,7 @@ void SnowEffectConfig::save() conf.writeEntry("MaxFlakes", m_ui->maxSizeFlake->value()); conf.writeEntry("MaxVSpeed", m_ui->maxVSpeed->value()); conf.writeEntry("MaxHSpeed", m_ui->maxHSpeed->value()); + conf.writeEntry("BehindWindows", m_ui->snowBehindWindows->isChecked()); m_ui->editor->save(); // undo() will restore to this state from now on @@ -125,6 +128,7 @@ void SnowEffectConfig::defaults() m_ui->maxSizeFlake->setValue( 50 ); m_ui->maxVSpeed->setValue( 2 ); m_ui->maxHSpeed->setValue( 1 ); + m_ui->snowBehindWindows->setChecked( false ); m_ui->editor->allDefault(); emit changed(true); } diff --git a/effects/snow_config.ui b/effects/snow_config.ui index 4137a8446e..f63f6f4765 100644 --- a/effects/snow_config.ui +++ b/effects/snow_config.ui @@ -179,6 +179,13 @@ + + + + Snow &behind windows + + +