Hi all,
At the plasma&kwin bof at akademy one of the things we talked about was a new 
effect that can make popups and panels appear with a slide animation.
today i decided to give it a try here is the result, it seems to work quite 
well.
Now it applies to every window and this is of course bad++, what is needed is 
some way to apply the thing only on windows we want.
that could be the dock type and, if it's on all of popups is way too much, so 
what we need? an atom to apply on windows we need? (for us basically just 
Plasma::Dialog)
or, a new window type? (would it be a type outside Netwm? is this acceptable?)
anyways, how does this patch look? is on the right track?

oh, as usual, please keep answers both on plasma-devel and kwin lists :)

Cheers, 
Marco Martin
Index: slidingpopups/slidingpopups.cpp
===================================================================
--- slidingpopups/slidingpopups.cpp	(revision 0)
+++ slidingpopups/slidingpopups.cpp	(revision 0)
@@ -0,0 +1,176 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Marco Martin notm...@gmail.com
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#include "slidingpopups.h"
+
+#include <kdebug.h>
+
+namespace KWin
+{
+
+KWIN_EFFECT( slidingpopups, SlidingPopupsEffect )
+
+void SlidingPopupsEffect::prePaintScreen( ScreenPrePaintData& data, int time )
+    {
+    if( !mAppearingWindows.isEmpty() || !mDisappearingWindows.isEmpty() )
+        data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
+    effects->prePaintScreen( data, time );
+    }
+
+void SlidingPopupsEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
+    {
+    if( mAppearingWindows.contains( w ) )
+        {
+        mAppearingWindows[ w ].setCurveShape( TimeLine::EaseOutCurve );
+        mAppearingWindows[ w ].addTime( time );
+        if( mAppearingWindows[ w ].value() < 1 )
+            data.setTransformed();
+        else
+            mAppearingWindows.remove( w );
+        }
+    else if( mDisappearingWindows.contains( w ) )
+        {
+        mDisappearingWindows[ w ].setCurveShape( TimeLine::EaseOutCurve );
+        mDisappearingWindows[ w ].addTime( time );
+        if( mDisappearingWindows[ w ].value() < 1 )
+            data.setTransformed();
+        else
+            mDisappearingWindows.remove( w );
+        }
+    effects->prePaintWindow( w, data, time );
+    }
+
+void SlidingPopupsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
+    {
+    bool animating = false;
+    bool appearing = false;
+    QRegion clippedRegion = region;
+
+    if( mAppearingWindows.contains( w ) )
+        {
+        appearing = true;
+        animating = true;
+        }
+    else if( mDisappearingWindows.contains( w ) )
+        {
+        appearing = false;
+        animating = true;
+        }
+
+
+    if( animating )
+        {
+//        data.xTranslate += int( w->width() / 2 * ( 1 - mAppearingWindows[ w ].value() ) );
+        qreal progress = appearing?(1 - mAppearingWindows[ w ].value()):mDisappearingWindows[ w ].value();
+
+        switch (mWindowPositions[ w ])
+            {
+            case West:
+                data.xTranslate -=  w->width() * progress;
+                clippedRegion = clippedRegion.subtracted(QRegion(w->x()-w->width(), w->y(), w->width(), w->height()));
+                break;
+            case North:
+                data.yTranslate -=  w->height() * progress;
+                clippedRegion = clippedRegion.subtracted(QRegion(w->x(), w->y() - w->height(), w->width(), w->height()));
+                break;
+            case East:
+                data.xTranslate +=  w->width() * progress;
+                clippedRegion = clippedRegion.subtracted(QRegion(w->x()+w->width(), w->y(), w->width(), w->height()));
+                break;
+            case South:
+            default:
+                data.yTranslate +=  w->height() * progress;
+                clippedRegion = clippedRegion.subtracted(QRegion(w->x(), w->y() + w->height(), w->width(), w->height()));
+            }
+        }
+
+    effects->paintWindow( w, mask, clippedRegion, data );
+    }
+
+void SlidingPopupsEffect::postPaintWindow( EffectWindow* w )
+    {
+    if( mAppearingWindows.contains( w ) )
+        w->addRepaintFull(); // trigger next animation repaint
+    effects->postPaintWindow( w );
+    }
+
+void SlidingPopupsEffect::windowAdded( EffectWindow* c )
+    {
+    if( c->isOnCurrentDesktop())
+        {
+        mAppearingWindows[ c ].setDuration( animationTime( 250 ));
+        mAppearingWindows[ c ].setProgress( 0.0 );
+
+        QRect screenRect = effects->clientArea( WorkArea, c);
+
+        int left = c->x() - screenRect.x();
+        int top = c->y() - screenRect.y();
+        int right =  screenRect.right() - (c->x() + c->width());
+        int bottom =  screenRect.bottom() - (c->y() + c->height());
+
+        if( left <= top && left <= right && left <= bottom )
+            mWindowPositions[ c ] = West;
+        else if( top <= left && top <= right && top <= bottom )
+            mWindowPositions[ c ] = North;
+        else if( right <= top && right <= left && right <= bottom )
+            mWindowPositions[ c ] = East;
+        else
+            mWindowPositions[ c ] = South;
+
+        c->addRepaintFull();
+        }
+    }
+
+void SlidingPopupsEffect::windowClosed( EffectWindow* c )
+    {
+    if( c->isOnCurrentDesktop())
+        {
+        mAppearingWindows.remove( c );
+        mDisappearingWindows[ c ].setDuration( animationTime( 250 ));
+        mDisappearingWindows[ c ].setProgress( 0.0 );
+
+        QRect screenRect = effects->clientArea( WorkArea, c);
+
+        int left = c->x() - screenRect.x();
+        int top = c->y() - screenRect.y();
+        int right =  screenRect.right() - (c->x() + c->width());
+        int bottom =  screenRect.bottom() - (c->y() + c->height());
+
+        if( left <= top && left <= right && left <= bottom )
+            mWindowPositions[ c ] = West;
+        else if( top <= left && top <= right && top <= bottom )
+            mWindowPositions[ c ] = North;
+        else if( right <= top && right <= left && right <= bottom )
+            mWindowPositions[ c ] = East;
+        else
+            mWindowPositions[ c ] = South;
+
+        c->addRepaintFull();
+        }
+    }
+
+void SlidingPopupsEffect::windowDeleted( EffectWindow* c )
+    {
+    mAppearingWindows.remove( c );
+    mDisappearingWindows.remove( c );
+    mWindowPositions.remove( c );
+    }
+
+} // namespace
Index: slidingpopups/slidingpopups.h
===================================================================
--- slidingpopups/slidingpopups.h	(revision 0)
+++ slidingpopups/slidingpopups.h	(revision 0)
@@ -0,0 +1,57 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Marco Martin notm...@gmail.com
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#ifndef KWIN_SLIDEBACK_H
+#define KWIN_SLIDEBACK_H
+
+// Include with base class for effects.
+#include <kwineffects.h>
+
+namespace KWin
+{
+
+class SlidingPopupsEffect
+    : public Effect
+    {
+    public:
+        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 );
+        // TODO react also on virtual desktop changes
+        virtual void windowAdded( EffectWindow* c );
+        virtual void windowClosed( EffectWindow* c );
+        virtual void windowDeleted( EffectWindow* c );
+    private:
+        enum Position
+            {
+            North = 1,
+            South = 2,
+            East = 3,
+            West = 4
+            };
+        QHash< const EffectWindow*, TimeLine > mAppearingWindows;
+        QHash< const EffectWindow*, TimeLine > mDisappearingWindows;
+        QHash< const EffectWindow*, Position > mWindowPositions;
+    };
+
+} // namespace
+
+#endif
Index: slidingpopups/slidingpopups.desktop
===================================================================
--- slidingpopups/slidingpopups.desktop	(revision 0)
+++ slidingpopups/slidingpopups.desktop	(revision 0)
@@ -0,0 +1,18 @@
+[Desktop Entry]
+Name=Sliding popups
+
+Type=Service
+Comment=Sliding animation for Plasma popups
+
+Icon=preferences-system-windows-effect-slidingpopups
+X-KDE-ServiceTypes=KWin/Effect
+X-KDE-PluginInfo-Author=Marco Martin
+x-kde-plugininfo-email=notm...@gmail.com
+X-KDE-PluginInfo-Name=kwin4_effect_slidingpopups
+X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Category=Appearance
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+X-KDE-Library=kwin4_effect_builtins
+X-KDE-Ordering=50
Index: slidingpopups/CMakeLists.txt
===================================================================
--- slidingpopups/CMakeLists.txt	(revision 0)
+++ slidingpopups/CMakeLists.txt	(revision 0)
@@ -0,0 +1,12 @@
+#######################################
+# Effect
+
+# Source files
+set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
+    slidingpopups/slidingpopups.cpp
+    )
+
+# .desktop files
+install( FILES
+    slidingpopups/slidingpopups.desktop
+    DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 995268)
+++ CMakeLists.txt	(working copy)
@@ -71,6 +71,7 @@
 include( showpaint/CMakeLists.txt )
 include( slide/CMakeLists.txt )
 include( slideback/CMakeLists.txt )
+include( slidingpopups/CMakeLists.txt )
 include( taskbarthumbnail/CMakeLists.txt )
 include( thumbnailaside/CMakeLists.txt )
 include( zoom/CMakeLists.txt )
_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to