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

List:       kwin
Subject:    [Review Request] coverswitch rework
From:       Martin Graesslin <ubuntu () martin-graesslin ! com>
Date:       2008-08-30 10:26:06
Message-ID: 200808301226.14937.ubuntu () martin-graesslin ! com
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


I worked on coverswitch the last few days and did some changes:

- uses RotationData instead of glRotate
- uses x/y/zTranslate instead of glTranslate
- does not define own projection matrix
- changed the direction of the animation (Lubos will like it ;-) )
- no special code for start/stop animations. That's now covered in the code 
for "normal" switching, thanks to not using glTranslate any more. Therefore 
minimized windows are faded instead of moved from panel.

currently not working: multi screen setups. I will fix that when I'm back from 
vacations (yes I won't be around next week).

So please take a look at the changes. Hope everything is still working - 
except twin view.

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

diff --git a/effects/coverswitch.cpp b/effects/coverswitch.cpp
index ec7e4e4..4836cb0 100644
--- a/effects/coverswitch.cpp
+++ b/effects/coverswitch.cpp
@@ -45,11 +45,13 @@ CoverSwitchEffect::CoverSwitchEffect()
     , animation( false )
     , start( false )
     , stop( false )
-    , forward( true )
-    , rearrangeWindows( 0 )
     , stopRequested( false )
     , startRequested( false )
     , twinview( false )
+    , zPosition( 900.0 )
+    , scaleFactor( 0.0 )
+    , direction( Left )
+    , selected_window( 0 )
     {
     KConfigGroup conf = effects->effectConfig( "CoverSwitch" );
     animationDuration = conf.readEntry( "Duration", 200 );
@@ -84,7 +86,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  
     if( mActivated || stop || stopRequested )
         {
-        glMatrixMode( GL_PROJECTION );
+/*        glMatrixMode( GL_PROJECTION );
         glPushMatrix();
         glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
         glLoadIdentity();
@@ -146,7 +148,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  glMatrixMode( GL_MODELVIEW );
         glLoadIdentity();
         glPushMatrix();
-        glTranslatef(left, bottom, -7.5);
+        glTranslatef(left, bottom, -7.5);*/
     
         QList< EffectWindow* > tempList = effects->currentTabBoxWindowList();
         int index = tempList.indexOf( effects->currentTabBoxWindow() );
@@ -154,23 +156,33 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  {
             if( !start && !stop )
                 {
-                if( forward )
-                    index--;
+                if( direction == Right )
+                    index++;
                 else
+                    index--;
+                if( index < 0 )
+                    index = tempList.count() + index;
+                if( index >= tempList.count() )
+                    index = index % tempList.count();
+                }
+            foreach( Direction direction, scheduled_directions )
+                {
+                if( direction == Right )
                     index++;
+                else
+                    index--;
+                if( index < 0 )
+                    index = tempList.count() + index;
+                if( index >= tempList.count() )
+                    index = index % tempList.count();
                 }
-            index += rearrangeWindows;
-            if( index < 0 )
-                index = tempList.count() + index;
-            if( index >= tempList.count() )
-                index = index % tempList.count();
             }
-        int rightIndex = index -1;
-        if( rightIndex < 0 )
-            rightIndex = tempList.count() -1;
-        int leftIndex = index +1;
-        if( leftIndex == tempList.count() )
-            leftIndex = 0;
+        int leftIndex = index -1;
+        if( leftIndex < 0 )
+            leftIndex = tempList.count() -1;
+        int rightIndex = index +1;
+        if( rightIndex == tempList.count() )
+            rightIndex = 0;
 
         EffectWindow* frontWindow = tempList[ index ];
         QList< EffectWindow* > leftWindows;
@@ -179,24 +191,24 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  bool evenWindows = ( tempList.count() % 2 == 0 ) ? true : false;
         int leftWindowCount = 0;
         if( evenWindows )
-            leftWindowCount = tempList.count()/2;
+            leftWindowCount = tempList.count()/2 - 1;
         else
             leftWindowCount = ( tempList.count() - 1 )/2;
         for( int i=0; i < leftWindowCount; i++ )
             {
-            int tempIndex = ( leftIndex + i ) % tempList.count();
+            int tempIndex = ( leftIndex - i );
+            if( tempIndex < 0 )
+                tempIndex = tempList.count() + tempIndex;
             leftWindows.prepend( tempList[ tempIndex ] );
             }
         int rightWindowCount = 0;
         if( evenWindows )
-            rightWindowCount = tempList.count()/2 - 1;
+            rightWindowCount = tempList.count()/2;
         else
             rightWindowCount = ( tempList.count() - 1 )/2;
         for( int i=0; i < rightWindowCount; i++ )
             {
-            int tempIndex = ( rightIndex - i );
-            if( tempIndex < 0 )
-                tempIndex = tempList.count() + tempIndex;
+            int tempIndex = ( rightIndex + i ) % tempList.count();
             rightWindows.prepend( tempList[ tempIndex ] );
             }
 
@@ -209,21 +221,21 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  glBlendFunc( GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA );
             glPolygonMode( GL_FRONT, GL_FILL );
             glPushMatrix();
-            float leftVertex = 0.0;
-            if( twinview && ( start || stop ) )
-                {
-                leftVertex = area.x();
-                glTranslatef( 0.0, area.y() + area.height(), 7.5);
-                }
-            else
+            QRect rect = effects->clientArea( FullScreenArea, \
effects->activeScreen(), effects->currentDesktop()); +            if( \
effects->numScreens() > 1 ) +                rect = effects->clientArea( FullArea, \
effects->activeScreen(), effects->currentDesktop() ); +            QRect fullRect = \
effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop() ); \
+            float reflectionScaleFactor = 10000 * tan( 60.0 * M_PI / 360.0f \
)/rect.height(); +            if( effects->numScreens() > 1 && rect.width() != \
fullRect.width() )  {
-                glTranslatef( 0.0, area.height(), 7.5);
+                // have to change the reflection area in horizontal layout and right \
screen +                glTranslatef( -rect.width(), 0.0, 0.0 );
                 }
             float vertices[] = {
-                leftVertex, 0.0, -10.0,
-                leftVertex + area.width(), 0.0, -10.0,
-                leftVertex + area.width()*3, 0.0, -50.0,
-                leftVertex - area.width()*2, 0.0, -50.0 };
+                rect.x(), rect.height(), 0.0,
+                rect.x()+rect.width(), rect.height(), 0.0,
+                (rect.x()+rect.width())*reflectionScaleFactor, rect.height(), -5000,
+                (-rect.x()-rect.width())*reflectionScaleFactor, rect.height(), -5000 \
};  // foreground
             float alpha = 1.0;
             if( start )
@@ -245,12 +257,12 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, \
ScreenPaintData&  }
         paintScene( frontWindow, &leftWindows, &rightWindows );
 
-        glPopMatrix();
+        /*glPopMatrix();
         glPopAttrib();
         glMatrixMode( GL_PROJECTION );
         glPopMatrix();
         glMatrixMode( GL_MODELVIEW );
-        glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );
+        glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );*/
 
         // caption of selected window
         QColor color_frame;
@@ -332,19 +344,15 @@ void CoverSwitchEffect::postPaintScreen()
                     startRequested = false;
                     mActivated = true;
                     effects->refTabBox();
-                    selectedWindow = \
effects->currentTabBoxWindowList().indexOf(effects->currentTabBoxWindow());  if( \
animateStart )  {
                         start = true;
                         }
                     }
                 }
-            else if( rearrangeWindows != 0 )
+            else if( !scheduled_directions.isEmpty() )
                 {
-                if( rearrangeWindows < 0 )
-                    rearrangeWindows++;
-                else
-                    rearrangeWindows--;
+                direction = scheduled_directions.dequeue();
                 if( start )
                     {
                     animation = true;
@@ -385,9 +393,10 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, \
QList< EffectWind  // appears transparent on left side and becomes totally opaque \
again  // backward (alt+shift+tab) same as forward but opposite direction
     int width = area.width();
-    int height = area.height();
     int leftWindowCount = leftWindows->count();
     int rightWindowCount = rightWindows->count();
+    RotationData rot;
+    rot.axis = RotationData::YAxis;
 
 
     // Problem during animation: a window which is painted after another window
@@ -396,95 +405,7 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, \
QList< EffectWind  // paint sequence no animation: left, right, front
     // paint sequence forward animation: right, front, left
 
-    if( start || stop )
-        {
-        // start or stop animation
-        float radian = angle * timeLine.value() * ( 2 * M_PI / 360 );
-        if( stop )
-            radian = ( angle - angle * timeLine.value() ) * ( 2 * M_PI / 360 );
-        int x, y;
-        // left windows
-        for( int i=0; i< leftWindowCount; i++ )
-            {
-            EffectWindow* window = leftWindows->at( i );
-            if( window == NULL )
-                continue;
-            x = window->x();
-            y = window->y();
-            if( window->isMinimized() )
-                {
-                // use icon instead of window
-                x = window->iconGeometry().x();
-                y = window->iconGeometry().y();
-                }
-            glPushMatrix();
-            int windowHeight = window->geometry().height();
-            float distance = -width*0.25f + ( width * 0.25f * i )/leftWindowCount - \
                x + area.x();
-            float distanceY = height - windowHeight - y + area.y();
-            if( start )
-                glTranslatef( distance*timeLine.value() + x, distanceY * \
                timeLine.value() + y, -5 * timeLine.value() - 2.5);
-            else if( stop )
-                glTranslatef( distance*( 1.0 - timeLine.value() ) + x, distanceY * ( \
                1.0 -timeLine.value() ) + y, -5 * ( 1.0 - timeLine.value() ) - 2.5);
-            glRotatef( radian, 0.0, 1.0, 0.0 );
-            int windowWidth = window->geometry().width() * cos( radian );
-            QRect windowRect = QRect( 0, 0, windowWidth, windowHeight );
-            paintWindowCover( window, windowRect, reflectedWindows );
-            glPopMatrix();
-            }
-
-        // right windows
-        for( int i=0; i < rightWindowCount; i++ )
-            {
-            EffectWindow* window = rightWindows->at( i );
-            if( window == NULL )
-                continue;
-            x = window->x();
-            y = window->y();
-            if( window->isMinimized() )
-                {
-                // use icon instead of window
-                x = window->iconGeometry().x();
-                y = window->iconGeometry().y();
-                }
-            glPushMatrix();
-            int windowWidth = window->geometry().width() * cos( radian );
-            int windowHeight = window->geometry().height();
-            float distance = width*1.25f - ( width * 0.25f * i )/rightWindowCount - \
                x - windowWidth + area.x();
-            float distanceY = height - windowHeight - y + area.y();
-            if( start )
-                glTranslatef( distance*timeLine.value() + x + windowWidth, distanceY \
                * timeLine.value() + y, -5 * timeLine.value() - 2.5);
-            else if( stop )
-                glTranslatef( distance*( 1.0 - timeLine.value() ) + x + windowWidth, \
                distanceY * ( 1.0 - timeLine.value() ) + y, -5 * ( 1.0 - \
                timeLine.value() ) - 2.5);
-            glRotatef( -radian, 0.0, 1.0, 0.0 );
-            QRect windowRect = QRect( -windowWidth, 0, windowWidth, windowHeight );
-            paintWindowCover( window, windowRect, reflectedWindows );
-            glPopMatrix();
-            }
-
-        // front window
-        if( frontWindow == NULL )
-            return;
-        glPushMatrix();
-        x = frontWindow->x();
-        y = frontWindow->y();
-        if( frontWindow->isMinimized() )
-            {
-            // use icon instead of window
-            x = frontWindow->iconGeometry().x();
-            y = frontWindow->iconGeometry().y();
-            }
-        int windowHeight = frontWindow->geometry().height();
-        float distance = (width - frontWindow->geometry().width())*0.5f - x + \
                area.x();
-        float distanceY = height - windowHeight - y + area.y();
-        if( start )
-            glTranslatef( distance * timeLine.value() + x, distanceY * \
                timeLine.value() + y, -5*timeLine.value() - 2.5 );
-        else if( stop )
-            glTranslatef( distance * ( 1.0 - timeLine.value() ) + x, distanceY * ( \
                1.0 - timeLine.value() ) + y, -5 * ( 1.0 - timeLine.value() ) - 2.5 \
                );
-        QRect windowRect = QRect( 0, 0, frontWindow->geometry().width(), \
                windowHeight );
-        paintWindowCover( frontWindow, windowRect, reflectedWindows );
-        glPopMatrix();
-        }
-    else if( !animation )
+    if( !animation )
         {
         paintWindows( leftWindows, true, reflectedWindows );
         paintWindows( rightWindows, false, reflectedWindows );
@@ -492,7 +413,7 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, \
QList< EffectWind  }
     else
         {
-        if( forward )
+        if( direction == Right )
             {
             if( timeLine.value() < 0.5 )
                 {
@@ -504,15 +425,8 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, \
QList< EffectWind  else
                 {
                 paintWindows( rightWindows, false, reflectedWindows );
-                EffectWindow* rightWindow;
-                if( rightWindowCount > 0)
-                    {
-                    rightWindow = rightWindows->at( 0 );
-                    paintFrontWindow( frontWindow, width, leftWindowCount, \
                rightWindowCount, reflectedWindows );
-                    }
-                else
-                    rightWindow = frontWindow;
-                paintWindows( leftWindows, true, reflectedWindows, rightWindow );
+                paintFrontWindow( frontWindow, width, leftWindowCount, \
rightWindowCount, reflectedWindows ); +                paintWindows( leftWindows, \
true, reflectedWindows, rightWindows->at( 0 ) );  }
             }
         else
@@ -525,8 +439,15 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, \
QList< EffectWind  }
             else
                 {
-                paintFrontWindow( frontWindow, width, leftWindowCount, \
                rightWindowCount, reflectedWindows );
-                paintWindows( rightWindows, false, reflectedWindows, \
leftWindows->at( 0 ) ); +                EffectWindow* leftWindow;
+                if( leftWindowCount > 0)
+                    {
+                    leftWindow = leftWindows->at( 0 );
+                    paintFrontWindow( frontWindow, width, leftWindowCount, \
rightWindowCount, reflectedWindows ); +                    }
+                else
+                    leftWindow = frontWindow;
+                paintWindows( rightWindows, false, reflectedWindows, leftWindow );
                 }
             }
         }
@@ -571,8 +492,9 @@ void CoverSwitchEffect::tabBoxAdded( int mode )
                 {
                 effects->refTabBox();
                 effects->setActiveFullScreenEffect( this );
-                input = effects->createFullScreenInputWindow( this, Qt::BlankCursor \
                );
-                selectedWindow = \
effects->currentTabBoxWindowList().indexOf(effects->currentTabBoxWindow()); +         \
scheduled_directions.clear(); +                selected_window = \
effects->currentTabBoxWindow(); +                direction = Left;
                 mActivated = true;
                 if( animateStart )
                     {
@@ -582,6 +504,7 @@ void CoverSwitchEffect::tabBoxAdded( int mode )
                 // Calculation of correct area
                 area = effects->clientArea( FullScreenArea, effects->activeScreen(), \
                effects->currentDesktop());
                 QRect fullArea = effects->clientArea( FullArea, \
effects->activeScreen(), effects->currentDesktop()); +                scaleFactor = \
(zPosition+1100) * 2.0 * tan( 60.0 * M_PI / 360.0f )/area.width();  // twinview?
                 if( area.height() != fullArea.height() || area.width() != \
fullArea.width() )  twinview = true;
@@ -594,6 +517,7 @@ void CoverSwitchEffect::tabBoxAdded( int mode )
                 {
                 startRequested = true;
                 }
+            input = effects->createFullScreenInputWindow( this, Qt::BlankCursor );
             }
         }
     }
@@ -608,7 +532,7 @@ void CoverSwitchEffect::tabBoxClosed()
                 {
                 stop = true;
                 }
-            else if( start && rearrangeWindows == 0 )
+            else if( start && scheduled_directions.isEmpty() )
                 {
                 start = false;
                 stop = true;
@@ -635,80 +559,112 @@ void CoverSwitchEffect::tabBoxUpdated()
         if( animateSwitch && effects->currentTabBoxWindowList().count() > 1)
             {
             // determine the switch direction
-            int index = \
                effects->currentTabBoxWindowList().indexOf(effects->currentTabBoxWindow());
                
-            bool direction = false;
-            int windowCount = effects->currentTabBoxWindowList().count();
-            if( index > selectedWindow )
+            if( selected_window != effects->currentTabBoxWindow() )
                 {
-                if( index == windowCount-1 && selectedWindow == 0 )
-                    direction = false;
-                else
-                    direction = true;
-                }
-            else if( index == 0 && ( selectedWindow == windowCount-1 ) )
-                {
-                direction = true;
-                }
-            else if( index == selectedWindow )
-                return; // nothing changed
-            else
-                {
-                direction = false;
-                }
-
-            // for two windows direction is always forward
-            if( windowCount == 2 )
-                direction = true;
-            selectedWindow = index;
-            if( !animation && !start )
-                {
-                forward = direction;
-                animation = true;
-                }
-            else
-                {
-                if( direction )
-                    rearrangeWindows--;
-                else
-                    rearrangeWindows++;
-                if( rearrangeWindows >= windowCount )
-                    rearrangeWindows = rearrangeWindows % windowCount;
-                else if( (-1*rearrangeWindows) >= windowCount )
-                    rearrangeWindows = -1*((-1*rearrangeWindows) % windowCount);
+                if( selected_window != NULL )
+                    {
+                    int old_index = effects->currentTabBoxWindowList().indexOf( \
selected_window ); +                    int new_index = \
effects->currentTabBoxWindowList().indexOf( effects->currentTabBoxWindow() ); +       \
Direction new_direction; +                    int distance = new_index - old_index;
+                    if( distance > 0 )
+                        new_direction = Left;
+                    if( distance < 0 )
+                        new_direction = Right;
+                    if( effects->currentTabBoxWindowList().count() == 2 )
+                        {
+                        new_direction = Left;
+                        distance = 1;
+                        }
+                    if( distance != 0 )
+                        {
+                        distance = abs( distance );
+                        int tempDistance = \
effects->currentTabBoxWindowList().count() - distance; +                        if( \
tempDistance < abs( distance ) ) +                            {
+                            distance = tempDistance;
+                            if( new_direction == Left )
+                                new_direction = Right;
+                            else
+                                new_direction = Left;
+                            }
+                        if( !animation && !start )
+                            {
+                            animation = true;
+                            direction = new_direction;
+                            distance--;
+                            }
+                        for( int i=0; i<distance; i++ )
+                            {
+                            if( !scheduled_directions.isEmpty() && \
scheduled_directions.last() != new_direction ) +                                \
scheduled_directions.pop_back(); +                            else
+                                scheduled_directions.enqueue( new_direction );
+                            if( scheduled_directions.count() == \
effects->currentTabBoxWindowList().count() ) +                                \
scheduled_directions.clear(); +                            }
+                        }
+                    }
+                selected_window = effects->currentTabBoxWindow();
                 }
             }
         effects->addRepaintFull();
         }
     }
 
-void CoverSwitchEffect::paintWindowCover( EffectWindow* w, QRect windowRect, bool \
reflectedWindow, float opacity ) +void CoverSwitchEffect::paintWindowCover( \
EffectWindow* w, bool reflectedWindow, WindowPaintData& data )  {
-    WindowPaintData data( w );
-
-    data.opacity *= opacity;
+    QRect windowRect = w->geometry();
+    data.yTranslate = area.height() - windowRect.y() - windowRect.height();
+    data.zTranslate = -zPosition;
+    if( start )
+        {
+        if( w->isMinimized() )
+            {
+            data.opacity *= timeLine.value();
+            }
+        else
+            {
+            data.xTranslate *= timeLine.value();
+            data.yTranslate *= timeLine.value();
+            data.zTranslate *= timeLine.value();
+            if( data.rotation )
+                data.rotation->angle *= timeLine.value();
+            }
+        }
+    if( stop )
+        {
+        if( w->isMinimized() && w != effects->activeWindow() )
+            {
+            data.opacity *= (1.0 - timeLine.value());
+            }
+        else
+            {
+            data.xTranslate *= (1.0 - timeLine.value());
+            data.yTranslate *= (1.0 - timeLine.value());
+            data.zTranslate *= (1.0 - timeLine.value());
+            if( data.rotation )
+                data.rotation->angle *= (1.0 - timeLine.value());
+            }
+        }
 
     QRect thumbnail = infiniteRegion();
-    setPositionTransformations( data,
-        thumbnail, w,
-        windowRect,
-        Qt::IgnoreAspectRatio );
-    thumbnail = infiniteRegion();
 
     if( reflectedWindow )
         {
         glPushMatrix();
         glScalef( 1.0, -1.0, 1.0 );
-        glTranslatef( 0.0, - area.height() - windowRect.y() - windowRect.height(), \
0.0 ); +        data.yTranslate = - area.height() - windowRect.y() - \
windowRect.height();  effects->paintWindow( w,
             PAINT_WINDOW_TRANSFORMED,
-            thumbnail, data );
+            infiniteRegion(), data );
         glPopMatrix();
         }
     else
         {
         effects->paintWindow( w,
             PAINT_WINDOW_TRANSFORMED,
-            thumbnail, data );
+            infiniteRegion(), data );
         }
     }
 
@@ -716,125 +672,125 @@ void CoverSwitchEffect::paintFrontWindow( EffectWindow* \
frontWindow, int width,  {
     if( frontWindow == NULL )
         return;
-    glPushMatrix();
-    glTranslatef((width - frontWindow->geometry().width())*0.5f, 0.0, -7.5);
-    int windowWidth = frontWindow->geometry().width();
-    int windowHeight = frontWindow->geometry().height();;
     float distance = 0.0;
-    int height = area.height();
-    int x = 0;
     bool specialHandlingForward = false;
+    WindowPaintData data( frontWindow );
+    data.xTranslate = area.x() + area.width()*0.5 - frontWindow->geometry().x() - \
frontWindow->geometry().width()*0.5;  if( leftWindows == 0 )
+        {
         leftWindows = 1;
+        if( !start && !stop )
+            specialHandlingForward = true;
+        }
     if( rightWindows == 0 )
         {
         rightWindows = 1;
-        specialHandlingForward = true;
         }
     if( animation )
         {
-        float radian = 0.0;
-        radian = angle * timeLine.value() * ( 2 * M_PI / 360 );
-        windowWidth = frontWindow->geometry().width() * cos( radian );
-        if( forward )
+        if( direction == Right )
             {
-            x = - windowWidth;
-            glTranslatef( frontWindow->geometry().width(), 0.0, 0.0 );
             // move to right
-            // we are at: (width + frontWindow->geometry().width())*0.5f
-            // we want to: width*1.25 - ( width * 0.25 *  (rightWindowCount -1) \
                )/rightWindowCount
-            distance = width*1.25 - ( width * 0.25 *  ( rightWindows - 1 ) \
                )/rightWindows -
-                (width + frontWindow->geometry().width())*0.5f;
-            glTranslatef( distance * timeLine.value(), 0.0, 0.0 );
-            glRotatef(-radian, 0.0, 1.0, 0.0);
+            distance = -frontWindow->geometry().width()*0.5f + area.width()*0.5f +
+                (((float)area.width()*0.5*scaleFactor)-(float)area.width()*0.5f)/rightWindows;
 +            data.xTranslate += distance * timeLine.value();
+            RotationData rot;
+            rot.axis = RotationData::YAxis;
+            rot.angle = -angle*timeLine.value();
+            rot.xRotationPoint = frontWindow->geometry().width();
+            data.rotation = &rot;
             }
         else
             {
             // move to left
-            // we are at: (width - frontWindow->geometry().width())*0.5f
-            // we want to: -width*0.25 + ( width * 0.25 * leftWindowCount - 1 \
                )/leftWindowCount
-            distance = ( width - frontWindow->geometry().width() ) * 0.5f +
-                width*0.25 - ( width * 0.25 * ( leftWindows - 1 ) )/leftWindows;
-            glTranslatef( - distance * timeLine.value(), 0.0, 0.0 );
-            glRotatef(radian, 0.0, 1.0, 0.0);
+            distance = frontWindow->geometry().width()*0.5f - area.width()*0.5f +
+                ((float)width*0.5f-((float)width*0.5*scaleFactor))/leftWindows;
+            float factor = 1.0;
+            if( specialHandlingForward )
+                factor = 2.0;
+            data.xTranslate += distance * timeLine.value() * factor;
+            RotationData rot;
+            rot.axis = RotationData::YAxis;
+            rot.angle = angle*timeLine.value();
+            data.rotation = &rot;
             }
         }
-    QRect windowRect = QRect( x, height - windowHeight, windowWidth, windowHeight );
     if( specialHandlingForward )
-        paintWindowCover( frontWindow, windowRect, reflectedWindow, 1.0 - \
timeLine.value() * 2 ); +        {
+        data.opacity *= (1.0 - timeLine.value() * 2.0);
+        paintWindowCover( frontWindow, reflectedWindow, data );
+        }
     else
-        paintWindowCover( frontWindow, windowRect, reflectedWindow );
-    glPopMatrix();
+        paintWindowCover( frontWindow, reflectedWindow, data );
     }
 
 void CoverSwitchEffect::paintWindows( QList< EffectWindow* >* windows, bool left, \
bool reflectedWindows, EffectWindow* additionalWindow )  {
     int width = area.width();
-    int height = area.height();
-    float radian = angle * ( 2 * M_PI / 360 );
     int windowCount = windows->count();
-    int windowWidth = 0;
-    int windowHeight = 0;
-    QRect windowRect;
     EffectWindow* window;
     
     int rotateFactor = 1;
-    float widthFactor = -0.25;
-    float widthFactorSingle = 0.25;
     if( !left )
         {
         rotateFactor = -1;
-        widthFactor = 1.25;
-        widthFactorSingle = - 0.25;
         }
-    
-    glPushMatrix();
-    glTranslatef( width*widthFactor, 0.0, -7.5 );
+
+    float xTranslate = -((float)width*0.5f-((float)width*0.5*scaleFactor));
+    if( !left )
+        xTranslate = ((float)width*0.5*scaleFactor)-(float)width*0.5f;
     // handling for additional window from other side
     // has to appear on this side after half of the time
     if( animation && timeLine.value() >= 0.5 && additionalWindow != NULL )
         {
-        // window has to appear on left side
-        glPushMatrix();
-        glRotatef( radian * rotateFactor, 0.0, 1.0, 0.0 );
-        windowWidth = additionalWindow->geometry().width() * cos( radian );
-        windowHeight = additionalWindow->geometry().height();
-        int x = 0;
-        if( !left )
+        RotationData rot;
+        rot.axis = RotationData::YAxis;
+        rot.angle = angle;
+        rot.angle = angle*rotateFactor;        
+        WindowPaintData data( additionalWindow );
+        if( left )
+            data.xTranslate += -xTranslate - additionalWindow->geometry().x();
+        else
             {
-            x = -windowWidth;
+            data.xTranslate += xTranslate + area.width() - 
+                additionalWindow->geometry().x() - \
additionalWindow->geometry().width(); +            rot.xRotationPoint = \
additionalWindow->geometry().width();  }
-        windowRect = QRect( x, height - windowHeight, windowWidth, windowHeight );
-        paintWindowCover( additionalWindow, windowRect, reflectedWindows, ( \
                timeLine.value() - 0.5 ) * 2 );
-        glPopMatrix();
+        data.rotation = &rot;
+        data.opacity *= ( timeLine.value() - 0.5 ) * 2.0;
+        paintWindowCover( additionalWindow, reflectedWindows, data );
         }
+    RotationData rot;
+    rot.axis = RotationData::YAxis;
     // normal behaviour
     for( int i=0; i < windowCount; i++ )
         {
         window = windows->at( i );
         if( window == NULL )
             continue;
-        glPushMatrix();
-        glTranslatef( ( width * widthFactorSingle * i )/windowCount, 0.0, 0.0 );
+        WindowPaintData data( window );
+        rot.angle = angle;
+        if( left )
+            data.xTranslate += -xTranslate + xTranslate*i/windowCount - \
window->geometry().x(); +        else
+            data.xTranslate += xTranslate + width - xTranslate*i/windowCount - \
window->geometry().x() - window->geometry().width();  if( animation )
             {
-            if( forward )
+            if( direction == Right )
                 {
                 if( ( i == windowCount - 1 ) && left )
                     {
                     // right most window on left side -> move to front
-                    // we are at: -width*0.25 + ( width * 0.25 * i )/leftWindowCount
-                    // we want to: (width - leftWindow->geometry().width())*0.5f
-                    float distance = (width - window->geometry().width())*0.5f + \
                width*(-widthFactor) - ( width * widthFactorSingle * i )/windowCount;
-                    glTranslatef( distance * timeLine.value() , 0.0, 0.0 );
-                    radian = ( angle - angle * timeLine.value() )  * ( 2 * M_PI / \
360 ); +                    // have to move one window distance plus half the \
difference between the window and the desktop size +                    \
data.xTranslate += (xTranslate/windowCount + (width - \
window->geometry().width())*0.5f)*timeLine.value(); +                    rot.angle = \
( angle - angle * timeLine.value() );  }
                 // right most window does not have to be moved
                 else if( !left && ( i == 0 ) ); // do nothing
                 else
                     {
                     // all other windows - move to next position
-                    glTranslatef( ( width * 0.25 * timeLine.value() )/windowCount, \
0.0, 0.0 ); +                    data.xTranslate += xTranslate/windowCount * \
timeLine.value();  }
                 }
             else
@@ -842,43 +798,39 @@ void CoverSwitchEffect::paintWindows( QList< EffectWindow* >* \
windows, bool left  if( ( i == windowCount - 1 ) && !left )
                     {
                     // left most window on right side -> move to front
-                    // we are at: width*1.25 - ( width * 0.25 *  i \
                )/rightWindowCount
-                    // we want to: (width + rightWindow->geometry().width())*0.5f
-                    float distance = width*1.25 - ( width * 0.25 *  i )/windowCount \
                - 
-                        (width + window->geometry().width())*0.5f;
-                    glTranslatef( - distance * timeLine.value(), 0.0, 0.0 );
-                    radian = ( angle - angle * timeLine.value() ) * ( 2 * M_PI / 360 \
); +                    data.xTranslate -= (xTranslate/windowCount + (width - \
window->geometry().width())*0.5f)*timeLine.value(); +                    rot.angle = \
( angle - angle * timeLine.value() );  }
                 // left most window does not have to be moved
                 else if( i==0 && left); // do nothing
                 else
                     {
                     // all other windows - move to next position
-                    glTranslatef( - ( width * 0.25 * timeLine.value() )/windowCount, \
0.0, 0.0 ); +                    data.xTranslate -= xTranslate/windowCount * \
timeLine.value();  }
                 }
             }
-        glRotatef( rotateFactor * radian, 0.0, 1.0, 0.0 );
-        windowWidth = window->geometry().width() * cos( radian );
-        windowHeight = window->geometry().height();
-        int x = 0;
-        if( !left )
-            {
-            x = -windowWidth;
-            }
-        windowRect = QRect( x, height - windowHeight, windowWidth, windowHeight );
+        if( left )
+            rot.xRotationPoint = 0.0;
+        else
+            rot.xRotationPoint = window->geometry().width();
+        rot.angle *= rotateFactor;
+        data.rotation = &rot;
         // make window most to edge transparent if animation
-        if( animation && i == 0 && ( ( !forward && left ) || ( forward && !left ) ) \
) +        if( animation && i == 0 && ( ( direction == Left && left ) || ( direction \
== Right && !left ) ) )  {
             // only for the first half of the animation
             if( timeLine.value() < 0.5 )
-                paintWindowCover( window, windowRect, reflectedWindows, 1.0 - \
timeLine.value() * 2 ); +                {
+                data.opacity *= (1.0 - timeLine.value() * 2.0);
+                paintWindowCover( window, reflectedWindows, data );
+                }
             }
         else
-            paintWindowCover( window, windowRect, reflectedWindows );
-        glPopMatrix();
+            {
+            paintWindowCover( window, reflectedWindows, data );
+            }
         }
-    glPopMatrix();
     }
 
 } // namespace
diff --git a/effects/coverswitch.h b/effects/coverswitch.h
index fc650f3..241d42a 100644
--- a/effects/coverswitch.h
+++ b/effects/coverswitch.h
@@ -22,6 +22,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #define KWIN_COVERSWITCH_H
 
 #include <kwineffects.h>
+#include <qqueue.h>
 
 namespace KWin
 {
@@ -44,7 +45,7 @@ class CoverSwitchEffect
     private:
         void paintScene( EffectWindow* frontWindow, QList< EffectWindow* >* \
leftWindows, QList< EffectWindow* >* rightWindows,  bool reflectedWindows = false );
-        void paintWindowCover( EffectWindow* w, QRect windowRect, bool \
reflectedWindow, float opacity = 1.0 ); +        void paintWindowCover( EffectWindow* \
                w, bool reflectedWindow, WindowPaintData& data );
         void paintFrontWindow( EffectWindow* frontWindow, int width, int \
                leftWindows, int rightWindows, bool reflectedWindow  );
         void paintWindows( QList< EffectWindow* >* windows, bool left, bool \
reflectedWindows, EffectWindow* additionalWindow = NULL );  bool mActivated;
@@ -55,17 +56,24 @@ class CoverSwitchEffect
         bool animation;
         bool start;
         bool stop;
-        bool forward;
         bool reflection;
         int animationDuration;
-        int selectedWindow;
-        int rearrangeWindows;
         bool stopRequested;
         bool startRequested;
         TimeLine timeLine;
         QRect area;
         bool twinview;
         Window input;
+        float zPosition;
+        float scaleFactor;
+        enum Direction
+            {
+            Left,
+            Right
+            };
+        Direction direction;
+        QQueue<Direction> scheduled_directions;
+        EffectWindow* selected_window;
     };
 
 } // namespace


["signature.asc" (application/pgp-signature)]

_______________________________________________
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