On Monday 20 July 2009, Martin Gräßlin wrote:
> Am Montag 20 Juli 2009 18:18:48 schrieb Marco Martin:
> > 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.
>
> great :-D
> I just had a look on the code and it looks good. I will try it later on.
>
> Some things I noticed:
yeah, some whoopsie, the attached patch corrects it
>  * in postPaintWindow you probably want to trigger repaints for
> disappearing windows as well. And you could trigger a full repaint for the
> complete screen. Well does not really matter as you set
> PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS 
> * Resetting the curve shape in each frame looks like overkill :-) 
indeed :)
by the way, i did copy the thing from scale in effect, that will have to be 
corrected as well :p
> * Do you really need the clippedRegion?
windows should be clipped to look as they come from the panel, and not slide 
over it, is there another way to achieve that?
maybe if it slides under the panel could make sense, not sure,hmm
in the experiments i done  they always looked as if the windows are always 
painted over the panel..
>  * when the window get's closed you have to w->refWindow(). When your
> animation finishes for that window you have to w->unrefWindow(). Without
> that you cannot use a window which has been closed. That code only worked
> because you had fade effect activated with same animation time ;-)
oh, good to know :)
>  * would excluding minimized windows from closing make sense? When
> restricting to only Plasma dialogs it probably doesn't matter.
>
> > 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?
>
> IIRC we said that adding a special window type would be better. That one
> would of course be outside netwm - nevertheless could be added to netwm
> later on.
yep, i'm wondering if we could want the effect for other types too, hmm

adding (another) new type could also solve my issue with the netbook shell, 
where kwin thinks that window is fullscreen just because has the full size but 
not the fullscreen flag, i'm knda hesitant to add non netwm types but yeah, if 
they aren't up to the job why not :D



-- 
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