/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2007 Philip Falkner This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "fade.h" #include namespace KWin { KWIN_EFFECT( fade, FadeEffect ) FadeEffect::FadeEffect() : m_proxy( this ) { reconfigure( ReconfigureAll ); } void* FadeEffect::proxy() { return &m_proxy; } void FadeEffect::reconfigure( ReconfigureFlags ) { KConfigGroup conf = effects->effectConfig( "Fade" ); fadeInTime = animationTime( conf, "FadeInTime", 150 ); fadeOutTime = animationTime( conf, "FadeOutTime", 150 ); fadeWindows = conf.readEntry( "FadeWindows", true ); // Add all existing windows to the window list // TODO: Enabling desktop effects should trigger windowAdded() on all windows windows.clear(); if( !fadeWindows ) return; foreach( EffectWindow *w, effects->stackingOrder() ) if( w && isFadeWindow( w )) // TODO: Apparently w can == NULL here? windows[ w ] = WindowInfo(); } void FadeEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) { fadeInStep = time / double( fadeInTime ); fadeOutStep = time / double( fadeOutTime ); } effects->prePaintScreen( data, time ); } void FadeEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { windows[ w ].fadeInStep += fadeInStep; windows[ w ].fadeOutStep += fadeOutStep; if( windows[ w ].opacity < 1.0 ) data.setTranslucent(); if( windows[ w ].deleted ) { if( windows[ w ].opacity <= 0.0 ) { windows.remove( w ); w->unrefWindow(); } else w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); } } effects->prePaintWindow( w, data, time ); if( windows.contains( w ) && !w->isPaintingEnabled() && !effects->activeFullScreenEffect() ) { // if the window isn't to be painted, then let's make sure // to track its progress if( windows[ w ].fadeInStep < 1.0 || windows[ w ].fadeOutStep < 1.0 ) { // but only if the total change is less than the // maximum possible change w->addRepaintFull(); } } } void FadeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) { if( windows.contains( w )) { if( windows[ w ].deleted || windows[ w ].opacity != data.opacity || windows[ w ].saturation != data.saturation || windows[ w ].brightness != data.brightness ) { WindowPaintData new_data = data; if( windows[ w ].deleted ) new_data.opacity = 0.0; if( new_data.opacity > windows[ w ].opacity ) { windows[ w ].opacity = qMin( new_data.opacity, windows[ w ].opacity + windows[ w ].fadeInStep ); } else if( new_data.opacity < windows[ w ].opacity ) { windows[ w ].opacity = qMax( new_data.opacity, windows[ w ].opacity - windows[ w ].fadeOutStep ); } if( new_data.saturation > windows[ w ].saturation ) { windows[ w ].saturation = qMin( new_data.saturation, windows[ w ].saturation + windows[ w ].fadeInStep ); } else if( new_data.saturation < windows[ w ].saturation ) { windows[ w ].saturation = qMax( new_data.saturation, windows[ w ].saturation - windows[ w ].fadeOutStep ); } if( new_data.brightness > windows[ w ].brightness ) { windows[ w ].brightness = qMin( new_data.brightness, windows[ w ].brightness + windows[ w ].fadeInStep ); } else if( new_data.brightness < windows[ w ].brightness ) { windows[ w ].brightness = qMax( new_data.brightness, windows[ w ].brightness - windows[ w ].fadeOutStep ); } windows[ w ].opacity = qBound( 0.0, windows[ w ].opacity, 1.0 ); windows[ w ].saturation = qBound( 0.0, windows[ w ].saturation, 1.0 ); windows[ w ].brightness = qBound( 0.0, windows[ w ].brightness, 1.0 ); windows[ w ].fadeInStep = 0.0; windows[ w ].fadeOutStep = 0.0; new_data.opacity = windows[ w ].opacity; new_data.saturation = windows[ w ].saturation; new_data.brightness = windows[ w ].brightness; effects->paintWindow( w, mask, region, new_data ); if( windows[ w ].opacity != data.opacity || windows[ w ].saturation != data.saturation || windows[ w ].brightness != data.brightness ) w->addRepaintFull(); return; } windows[ w ].fadeInStep = 0.0; windows[ w ].fadeOutStep = 0.0; } effects->paintWindow( w, mask, region, data ); } void FadeEffect::windowOpacityChanged( EffectWindow* w, double old_opacity ) { if( !windows.contains( w )) windows[ w ].opacity = old_opacity; if( windows[ w ].opacity == 1.0 ) windows[ w ].opacity -= 0.1 / fadeOutTime; w->addRepaintFull(); } void FadeEffect::windowAdded( EffectWindow* w ) { if( !fadeWindows || !isFadeWindow( w )) return; windows[ w ].opacity = 0.0; w->addRepaintFull(); } void FadeEffect::windowClosed( EffectWindow* w ) { if( !fadeWindows || !isFadeWindow( w )) return; if( !windows.contains( w )) windows[ w ].opacity = w->opacity(); if( windows[ w ].opacity == 1.0 ) windows[ w ].opacity -= 0.1 / fadeOutTime; windows[ w ].deleted = true; w->refWindow(); w->addRepaintFull(); } void FadeEffect::windowDeleted( EffectWindow* w ) { windows.remove( w ); ignoredWindows.remove( w ); } void FadeEffect::setWindowIgnored( EffectWindow* w, bool ignore ) { if (ignore) { ignoredWindows.insert( w ); } else { ignoredWindows.remove( w ); } } bool FadeEffect::isFadeWindow( EffectWindow* w ) { if( w->windowClass() == "ksplashx ksplashx" || w->windowClass() == "ksplashsimple ksplashsimple" || ignoredWindows.contains( w ) ) { // see login effect return false; } return ( !w->isDesktop() && !w->isUtility() ); } } // namespace