diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index cd8a276f76..7a9bef0dba 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -85,6 +85,7 @@ if( KWIN_HAVE_OPENGL_COMPOSITING ) include( magnifier/CMakeLists.txt ) include( mousemark/CMakeLists.txt ) include( sharpen/CMakeLists.txt ) + include( sheet/CMakeLists.txt ) include( snaphelper/CMakeLists.txt ) include( snow/CMakeLists.txt ) include( trackmouse/CMakeLists.txt ) diff --git a/effects/sheet/CMakeLists.txt b/effects/sheet/CMakeLists.txt new file mode 100644 index 0000000000..1d01e2530a --- /dev/null +++ b/effects/sheet/CMakeLists.txt @@ -0,0 +1,13 @@ +####################################### +# Effect + +# Source files +set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} + sheet/sheet.cpp + ) + +# .desktop files +install( FILES + sheet/sheet.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) + diff --git a/effects/sheet/sheet.cpp b/effects/sheet/sheet.cpp new file mode 100644 index 0000000000..2f5397bb47 --- /dev/null +++ b/effects/sheet/sheet.cpp @@ -0,0 +1,188 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Philip Falkner +Copyright (C) 2009 Martin Gräßlin + +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 "sheet.h" + +#include + +// Effect is based on fade effect by Philip Falkner + +namespace KWin +{ + +KWIN_EFFECT( sheet, SheetEffect ) +KWIN_EFFECT_SUPPORTED( sheet, SheetEffect::supported() ) + +SheetEffect::SheetEffect() + : windowCount( 0 ) + { + reconfigure( ReconfigureAll ); + } + +bool SheetEffect::supported() + { + return effects->compositingType() == OpenGLCompositing; + } + +void SheetEffect::reconfigure( ReconfigureFlags ) + { + KConfigGroup conf = effects->effectConfig( "Sheet" ); + duration = animationTime( conf, "AnimationTime", 500 ); + } + +void SheetEffect::prePaintScreen( ScreenPrePaintData& data, int time ) + { + if( windowCount > 0 ) + { + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + screenTime = time; + } + effects->prePaintScreen( data, time ); + } + +void SheetEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) + { + if( windows.contains( w ) && ( windows[ w ].added || windows[ w ].closed ) ) + { + if( windows[ w ].added ) + windows[ w ].timeLine->addTime( screenTime ); + if( windows[ w ].closed ) + { + windows[ w ].timeLine->removeTime( screenTime ); + if( windows[ w ].deleted ) + { + 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 ].added || windows[ w ].closed ) + { // but only if the total change is less than the + // maximum possible change + w->addRepaintFull(); + } + } + } + +void SheetEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + if( windows.contains( w ) && ( windows[ w ].added || windows[ w ].closed ) ) + { + RotationData rot; + rot.axis = RotationData::XAxis; + rot.angle = 60.0 * ( 1.0 - windows[ w ].timeLine->value() ); + data.rotation = &rot; + data.yScale *= windows[ w ].timeLine->value(); + data.zScale *= windows[ w ].timeLine->value(); + data.yTranslate -= (w->y()-windows[ w ].parentY) * ( 1.0 - windows[ w ].timeLine->value() ); + effects->paintWindow( w, PAINT_WINDOW_TRANSFORMED, region, data ); + } + else + effects->paintWindow( w, mask, region, data ); + } + +void SheetEffect::postPaintWindow( EffectWindow* w ) + { + if( windows.contains( w ) ) + { + if( windows[ w ].added && windows[ w ].timeLine->value() == 1.0 ) + { + windows[ w ].added = false; + windowCount--; + effects->addRepaintFull(); + } + if( windows[ w ].closed && windows[ w ].timeLine->value() == 0.0 ) + { + windows[ w ].closed = false; + if( windows[ w ].deleted ) + { + windows.remove( w ); + w->unrefWindow(); + } + windowCount--; + effects->addRepaintFull(); + } + if( windows[ w ].added || windows[ w ].closed ) + w->addRepaintFull(); + } + effects->postPaintWindow( w ); + } + +void SheetEffect::windowAdded( EffectWindow* w ) + { + if( !isSheetWindow( w ) ) + return; + windows[ w ] = WindowInfo(); + windows[ w ].added = true; + windows[ w ].closed = false; + windows[ w ].timeLine->setDuration( duration ); + // find parent + foreach( EffectWindow* window, effects->stackingOrder() ) + { + if( window->findModal() == w ) + { + windows[ w ].parentY = window->y(); + break; + } + } + windowCount++; + w->addRepaintFull(); + } + +void SheetEffect::windowClosed( EffectWindow* w ) + { + if( !windows.contains( w ) ) + return; + windows[ w ].added = false; + windows[ w ].closed = true; + windows[ w ].deleted = true; + bool found = false; + // find parent + foreach( EffectWindow* window, effects->stackingOrder() ) + { + if( window->findModal() == w ) + { + windows[ w ].parentY = window->y(); + found = true; + break; + } + } + if( !found ) + windows[ w ].parentY = 0; + windowCount++; + w->refWindow(); + w->addRepaintFull(); + } + +void SheetEffect::windowDeleted( EffectWindow* w ) + { + windows.remove( w ); + } + +bool SheetEffect::isSheetWindow( EffectWindow* w ) + { + return ( w->isModal() ); + } + +} // namespace diff --git a/effects/sheet/sheet.desktop b/effects/sheet/sheet.desktop new file mode 100755 index 0000000000..b5c293c830 --- /dev/null +++ b/effects/sheet/sheet.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Name=Sheet +Icon=preferences-system-windows-effect-sheet +Comment=Make modal dialogs smoothly fly in and out when they are shown or hidden + +Type=Service +X-KDE-ServiceTypes=KWin/Effect +X-KDE-PluginInfo-Author=Martin Gräßlin +X-KDE-PluginInfo-Email=kde@martin-graesslin.com +X-KDE-PluginInfo-Name=kwin4_effect_sheet +X-KDE-PluginInfo-Version=0.1.0 +X-KDE-PluginInfo-Category=Appearance +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false +X-KDE-Library=kwin4_effect_builtins +X-KDE-Ordering=60 diff --git a/effects/sheet/sheet.h b/effects/sheet/sheet.h new file mode 100644 index 0000000000..635464d454 --- /dev/null +++ b/effects/sheet/sheet.h @@ -0,0 +1,75 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Philip Falkner +Copyright (C) 2009 Martin Gräßlin + +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 . +*********************************************************************/ + +#ifndef KWIN_SHEET_H +#define KWIN_SHEET_H + +#include + +namespace KWin +{ + +class SheetEffect + : public Effect + { + public: + SheetEffect(); + virtual void reconfigure( ReconfigureFlags ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); + virtual void postPaintWindow( EffectWindow* w ); + + virtual void windowAdded( EffectWindow* c ); + virtual void windowClosed( EffectWindow* c ); + virtual void windowDeleted( EffectWindow* c ); + + static bool supported(); + private: + class WindowInfo; + bool isSheetWindow( EffectWindow* w ); + QHash< const EffectWindow*, WindowInfo > windows; + float duration; + int windowCount; + int screenTime; + }; + +class SheetEffect::WindowInfo + { + public: + WindowInfo() + : deleted( false ) + , added( false ) + , closed( false ) + , parentY( 0 ) + { + timeLine = new TimeLine(); + } + bool deleted; + bool added; + bool closed; + TimeLine* timeLine; + int parentY; + }; + +} // namespace + +#endif