[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    [PATCH] bug #243693  -> glide effect... ouch!
From:       Thomas =?iso-8859-1?q?L=FCbking?= <thomas.luebking () web ! de>
Date:       2010-10-07 14:00:21
Message-ID: 201010071600.21170.thomas.luebking () web ! de
[Download RAW message or body]

a) QHash is not an array (and actually a QMap should be faster in this 
context, since the item number is usually pretty small)
b) Pointers don't magically delete themself when set to NULL... (and there's 
no moc either)
c) the effect kept _all_ mapped (and handled) windows in its internal list and 
if a window was in this list ( what's more or less "if (true)" ) set it to 
TRANSFORMED (this probably blocked the blur effect)
d) i recall that the TRANSFORMED mask has to be set in prePaintWindow and 
*not* in paintWindow, yesno?!
-> set a property for IsGlideWindow (since all deleted aren't managed) and 
stripped down the entire thing


Cheers,
Thomas

["fix_glide_effect.diff" (text/x-patch)]

Index: glide.cpp
===================================================================
--- glide.cpp	(Revision 1183239)
+++ glide.cpp	(Arbeitskopie)
@@ -32,8 +32,9 @@
 KWIN_EFFECT( glide, GlideEffect )
 KWIN_EFFECT_SUPPORTED( glide, GlideEffect::supported() )
 
+static const int IsGlideWindow = 0x22A982D4;
+
 GlideEffect::GlideEffect()
-    : windowCount( 0 )
     {
     reconfigure( ReconfigureAll );
     }
@@ -53,111 +54,116 @@
 
 void GlideEffect::prePaintScreen( ScreenPrePaintData& data, int time )
     {
-    if( windowCount > 0 )
+    if( !windows.isEmpty() )
         data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
     effects->prePaintScreen( data, time );
     }
 
 void GlideEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
     {
-    if( windows.contains( w ) && ( windows[ w ].added || windows[ w ].closed ) )
+    InfoHash::iterator info = windows.find( w );
+    if( info != windows.end() )
         {
-        if( windows[ w ].added )
-            windows[ w ].timeLine->addTime( time );
-        if( windows[ w ].closed )
+        data.setTransformed();
+        if( info->added )
+            info->timeLine.addTime( time );
+        else if( info->closed )
             {
-            windows[ w ].timeLine->removeTime( time );
-            if( windows[ w ].deleted )
-                {
+            info->timeLine.removeTime( time );
+            if( info->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();
-            }
-        }
+    
+    // if the window isn't to be painted, then let's make sure
+    // to track its progress
+    // NOTICE @Martin: it's not like i'd know what this is supposed to be good for...
+    if( info != windows.end() && !w->isPaintingEnabled() && !effects->activeFullScreenEffect() )
+        w->addRepaintFull();
     }
 
 void GlideEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
     {
-    if( windows.contains( w ) )
+    InfoHash::const_iterator info = windows.find( w );
+    if( info != windows.constEnd() )
         {
+        const double progress = info->timeLine.value();
         RotationData rot;
         rot.axis = RotationData::XAxis;
-        rot.angle = angle * ( 1 - windows[ w ].timeLine->value() );
+        rot.angle = angle * ( 1 - progress );
         data.rotation = &rot;
-        data.opacity *= windows[ w ].timeLine->value();
-        if( effect == GlideInOut )
+        data.opacity *= progress;
+        switch ( effect )
             {
-            if( windows[ w ].added )
-                glideIn( w, data );
-            if( windows[ w ].closed )
-                glideOut( w, data );
+            default:
+            case GlideInOut:
+                if( info->added )
+                    glideIn( w, data );
+                else if( info->closed )
+                    glideOut( w, data );
+                break;
+            case GlideOutIn:
+                if( info->added )
+                    glideOut( w, data );
+                if( info->closed )
+                    glideIn( w, data );
+                break;
+            case GlideIn: glideIn( w, data ); break;
+            case GlideOut: glideOut( w, data ); break;
             }
-         if( effect == GlideOutIn )
-            {
-            if( windows[ w ].added )
-                glideOut( w, data );
-            if( windows[ w ].closed )
-                glideIn( w, data );
-            }
-        if( effect == GlideIn )
-                glideIn( w, data );
-        if( effect == GlideOut )
-                glideOut( w, data );
-        effects->paintWindow( w, PAINT_WINDOW_TRANSFORMED, region, data );
         }
-    else
-        effects->paintWindow( w, mask, region, data );
+    effects->paintWindow( w, mask, region, data );
     }
 
 void GlideEffect::glideIn(EffectWindow* w, WindowPaintData& data )
     {
-    data.xScale *= windows[ w ].timeLine->value();
-    data.yScale *= windows[ w ].timeLine->value();
-    data.zScale *= windows[ w ].timeLine->value();
-    data.xTranslate += int( w->width() / 2 * ( 1 - windows[ w ].timeLine->value() ) );
-    data.yTranslate += int( w->height() / 2 * ( 1 - windows[ w ].timeLine->value() ) );
+    InfoHash::const_iterator info = windows.find( w );
+    if ( info == windows.constEnd() )
+        return;
+    const double progress = info->timeLine.value();
+    data.xScale *= progress;
+    data.yScale *= progress;
+    data.zScale *= progress;
+    data.xTranslate += int( w->width() / 2 * ( 1 - progress ) );
+    data.yTranslate += int( w->height() / 2 * ( 1 - progress ) );
     }
 
 void GlideEffect::glideOut(EffectWindow* w, WindowPaintData& data )
     {
-    data.xScale *= ( 2 - windows[ w ].timeLine->value() );
-    data.yScale *= ( 2 - windows[ w ].timeLine->value() );
-    data.zScale *= ( 2 - windows[ w ].timeLine->value() );
-    data.xTranslate -= int( w->width() / 2 * ( 1 - windows[ w ].timeLine->value() ) );
-    data.yTranslate -= int( w->height() / 2 * ( 1 - windows[ w ].timeLine->value() ) );
+    InfoHash::const_iterator info = windows.find( w );
+    if ( info == windows.constEnd() )
+        return;
+    const double progress = info->timeLine.value();
+    data.xScale *= ( 2 - progress );
+    data.yScale *= ( 2 - progress );
+    data.zScale *= ( 2 - progress );
+    data.xTranslate -= int( w->width() / 2 * ( 1 - progress ) );
+    data.yTranslate -= int( w->height() / 2 * ( 1 - progress ) );
     }
 
 void GlideEffect::postPaintWindow( EffectWindow* w )
     {
-    if( windows.contains( w ) )
+    InfoHash::iterator info = windows.find( w );
+    if( info != windows.end() )
         {
-        if( windows[ w ].added && windows[ w ].timeLine->value() == 1.0 )
+        if( info->added && info->timeLine.value() == 1.0 )
             {
-            windows[ w ].added = false;
-            windowCount--;
+            windows.remove( w );
             effects->addRepaintFull();
             }
-        if( windows[ w ].closed && windows[ w ].timeLine->value() == 0.0 )
+        else if( info->closed && info->timeLine.value() == 0.0 )
             {
-            windows[ w ].closed = false;
-            if( windows[ w ].deleted )
+            info->closed = false;
+            if( info->deleted )
                 {
                 windows.remove( w );
                 w->unrefWindow();
                 }
-            windowCount--;
             effects->addRepaintFull();
             }
-        if( windows[ w ].added || windows[ w ].closed )
+        if( info->added || info->closed )
             w->addRepaintFull();
         }
     effects->postPaintWindow( w );
@@ -167,46 +173,59 @@
     {
     if( !isGlideWindow( w ) )
         return;
-
+    w->setData( IsGlideWindow, true );
+    const void *addGrab = w->data( WindowAddedGrabRole ).value<void*>();
+    if ( addGrab && addGrab != this )
+        return;
     w->setData( WindowAddedGrabRole, QVariant::fromValue( static_cast<void*>( this )));
-    windows[ w ] = WindowInfo();
-    windows[ w ].added = true;
-    windows[ w ].closed = false;
-    windows[ w ].deleted = false;
-    windows[ w ].timeLine->setDuration( duration );
-    windows[ w ].timeLine->setCurveShape( TimeLine::EaseOutCurve );
-    windowCount++;
+    
+    InfoHash::iterator it = windows.find( w );
+    WindowInfo *info = ( it == windows.end() ) ? &windows[w] : &it.value();
+    info->added = true;
+    info->closed = false;
+    info->deleted = false;
+    info->timeLine.setDuration( duration );
+    info->timeLine.setCurveShape( TimeLine::EaseOutCurve );
     w->addRepaintFull();
     }
 
 void GlideEffect::windowClosed( EffectWindow* w )
     {
-    if( !windows.contains( w ) )
+    if ( !isGlideWindow( w ) )
         return;
+    const void *closeGrab = w->data( WindowClosedGrabRole ).value<void*>();
+    if ( closeGrab && closeGrab != this )
+        return;
+    w->refWindow();
     w->setData( WindowClosedGrabRole, QVariant::fromValue( static_cast<void*>( this )));
-    windows[ w ].added = false;
-    windows[ w ].closed = true;
-    windows[ w ].deleted = true;
-    windows[ w ].timeLine->setDuration( duration );
-    windows[ w ].timeLine->setCurveShape( TimeLine::EaseInCurve );
-    windowCount++;
-    w->refWindow();
+    
+    InfoHash::iterator it = windows.find( w );
+    WindowInfo *info = ( it == windows.end() ) ? &windows[w] : &it.value();
+    info->added = false;
+    info->closed = true;
+    info->deleted = true;
+    info->timeLine.setDuration( duration );
+    info->timeLine.setCurveShape( TimeLine::EaseInCurve );
+    info->timeLine.setProgress( 1.0 );
     w->addRepaintFull();
     }
 
 void GlideEffect::windowDeleted( EffectWindow* w )
     {
-    //delete windows[ w ].timeLine;
-    windows[ w ].timeLine = NULL;
     windows.remove( w );
     }
 
 bool GlideEffect::isGlideWindow( EffectWindow* w )
     {
-    const void* e = w->data( WindowAddedGrabRole ).value<void*>();
-    // TODO: isSpecialWindow is rather generic, maybe tell windowtypes separately?
-    if ( w->isPopupMenu() || w->isSpecialWindow() || w->isUtility() || ( e && e != this ))
+    if ( effects->activeFullScreenEffect() )
         return false;
+    if ( w->data( IsGlideWindow ).toBool() )
+        return true;
+    if ( w->hasDecoration() )
+        return true;
+    if ( !w->isManaged() || w->isMenu() ||  w->isNotification() || w->isDesktop() || 
+         w->isDock() ||  w->isSplash() || w->isTopMenu() || w->isToolbar() )
+        return false;
     return true;
     }
 } // namespace
Index: glide.h
===================================================================
--- glide.h	(Revision 1183239)
+++ glide.h	(Arbeitskopie)
@@ -45,14 +45,14 @@
 
         static bool supported();
     private:
+        class WindowInfo;
+        typedef QMap< const EffectWindow*, WindowInfo > InfoHash;
         void glideIn( EffectWindow* w, WindowPaintData& data );
         void glideOut( EffectWindow* w, WindowPaintData& data );
-        class WindowInfo;
         bool isGlideWindow( EffectWindow* w );
-        QHash< const EffectWindow*, WindowInfo > windows;
+        InfoHash windows;
         float duration;
         int angle;
-        int windowCount;
         enum EffectStyle
         {
             GlideIn = 0,
@@ -69,18 +69,14 @@
         WindowInfo()
             : deleted( false )
             , added( false )
-            , closed( false )
-            {
-            timeLine = new TimeLine();
-            }
+            , closed( false ) { }
         ~WindowInfo()
         {
-            timeLine = NULL;
         } 
         bool deleted;
         bool added;
         bool closed;
-        TimeLine* timeLine;
+        TimeLine timeLine;
     };
 
 } // namespace


_______________________________________________
kwin mailing list
kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic