1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #include "coverswitch.h"
22 #include <kwinconfig.h>
25 #include <kapplication.h>
26 #include <kcolorscheme.h>
27 #include <kconfiggroup.h>
29 #include <kwinglutils.h>
40 KWIN_EFFECT( coverswitch
, CoverSwitchEffect
)
41 KWIN_EFFECT_SUPPORTED( coverswitch
, CoverSwitchEffect::supported() )
43 CoverSwitchEffect::CoverSwitchEffect()
49 , stopRequested( false )
50 , startRequested( false )
54 , selected_window( 0 )
56 reconfigure( ReconfigureAll
);
59 CoverSwitchEffect::~CoverSwitchEffect()
63 bool CoverSwitchEffect::supported()
65 return effects
->compositingType() == OpenGLCompositing
;
68 void CoverSwitchEffect::reconfigure( ReconfigureFlags
)
70 KConfigGroup conf
= effects
->effectConfig( "CoverSwitch" );
71 animationDuration
= animationTime( conf
, "Duration", 200 );
72 animateSwitch
= conf
.readEntry( "AnimateSwitch", true );
73 animateStart
= conf
.readEntry( "AnimateStart", true );
74 animateStop
= conf
.readEntry( "AnimateStop", true );
75 reflection
= conf
.readEntry( "Reflection", true );
76 zPosition
= conf
.readEntry( "ZPosition", 900.0 );
77 thumbnails
= conf
.readEntry( "Thumbnails", true );
78 dynamicThumbnails
= conf
.readEntry( "DynamicThumbnails", true );
79 thumbnailWindows
= conf
.readEntry( "ThumbnailWindows", 8 );
80 timeLine
.setCurveShape( TimeLine::EaseInOutCurve
);
81 timeLine
.setDuration( animationDuration
);
84 color_frame
= KColorScheme( QPalette::Active
, KColorScheme::Window
).background().color();
85 color_frame
.setAlphaF( 0.9 );
86 color_highlight
= KColorScheme( QPalette::Active
, KColorScheme::Selection
).background().color();
87 color_highlight
.setAlphaF( 0.9 );
92 void CoverSwitchEffect::prePaintScreen( ScreenPrePaintData
& data
, int time
)
94 if( mActivated
|| stop
|| stopRequested
)
96 data
.mask
|= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS
;
97 if( animation
|| start
|| stop
)
99 timeLine
.addTime( (double)time
);
100 if( thumbnails
&& (!dynamicThumbnails
||
101 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
)) )
102 calculateItemSizes();
105 effects
->prePaintScreen(data
, time
);
108 void CoverSwitchEffect::paintScreen( int mask
, QRegion region
, ScreenPaintData
& data
)
110 effects
->paintScreen( mask
, region
, data
);
112 if( mActivated
|| stop
|| stopRequested
)
114 if( effects
->numScreens() > 1 )
116 // unfortunatelly we have to change the projection matrix in dual screen mode
117 QRect fullRect
= effects
->clientArea( FullArea
, activeScreen
, effects
->currentDesktop() );
118 glMatrixMode( GL_PROJECTION
);
125 float ymax
= zNear
* tan( fovy
* M_PI
/ 360.0f
);
127 float xmin
= ymin
* aspect
;
128 float xmax
= ymax
* aspect
;
129 float xTranslate
= 0.0;
130 float yTranslate
= 0.0;
131 float xminFactor
= 1.0;
132 float xmaxFactor
= 1.0;
133 float yminFactor
= 1.0;
134 float ymaxFactor
= 1.0;
135 if( area
.x() == 0 && area
.width() != fullRect
.width() )
137 // horizontal layout: left screen
138 xminFactor
= (float)area
.width()/(float)fullRect
.width();
139 xmaxFactor
= ((float)fullRect
.width()-(float)area
.width()*0.5f
)/((float)fullRect
.width()*0.5f
);
140 xTranslate
= (float)fullRect
.width()*0.5f
-(float)area
.width()*0.5f
;
142 if( area
.x() != 0 && area
.width() != fullRect
.width() )
144 // horizontal layout: right screen
145 xminFactor
= ((float)fullRect
.width()-(float)area
.width()*0.5f
)/((float)fullRect
.width()*0.5f
);
146 xmaxFactor
= (float)area
.width()/(float)fullRect
.width();
147 xTranslate
= (float)fullRect
.width()*0.5f
-(float)area
.width()*0.5f
;
149 if( area
.y() == 0 && area
.height() != fullRect
.height() )
151 // vertical layout: top screen
152 yminFactor
= ((float)fullRect
.height()-(float)area
.height()*0.5f
)/((float)fullRect
.height()*0.5f
);
153 ymaxFactor
= (float)area
.height()/(float)fullRect
.height();
154 yTranslate
= (float)fullRect
.height()*0.5f
-(float)area
.height()*0.5f
;
156 if( area
.y() != 0 && area
.height() != fullRect
.height() )
158 // vertical layout: bottom screen
159 yminFactor
= (float)area
.height()/(float)fullRect
.height();
160 ymaxFactor
= ((float)fullRect
.height()-(float)area
.height()*0.5f
)/((float)fullRect
.height()*0.5f
);
161 yTranslate
= (float)fullRect
.height()*0.5f
-(float)area
.height()*0.5f
;
163 glFrustum( xmin
*xminFactor
, xmax
*xmaxFactor
, ymin
*yminFactor
, ymax
*ymaxFactor
, zNear
, zFar
);
164 glMatrixMode( GL_MODELVIEW
);
166 glTranslatef( xTranslate
, yTranslate
, 0.0 );
169 QList
< EffectWindow
* > tempList
= effects
->currentTabBoxWindowList();
170 int index
= tempList
.indexOf( effects
->currentTabBoxWindow() );
171 if( animation
|| start
|| stop
)
173 if( !start
&& !stop
)
175 if( direction
== Right
)
180 index
= tempList
.count() + index
;
181 if( index
>= tempList
.count() )
182 index
= index
% tempList
.count();
184 foreach( Direction direction
, scheduled_directions
)
186 if( direction
== Right
)
191 index
= tempList
.count() + index
;
192 if( index
>= tempList
.count() )
193 index
= index
% tempList
.count();
196 int leftIndex
= index
-1;
198 leftIndex
= tempList
.count() -1;
199 int rightIndex
= index
+1;
200 if( rightIndex
== tempList
.count() )
203 EffectWindow
* frontWindow
= tempList
[ index
];
205 rightWindows
.clear();
207 bool evenWindows
= ( tempList
.count() % 2 == 0 ) ? true : false;
208 int leftWindowCount
= 0;
210 leftWindowCount
= tempList
.count()/2 - 1;
212 leftWindowCount
= ( tempList
.count() - 1 )/2;
213 for( int i
=0; i
< leftWindowCount
; i
++ )
215 int tempIndex
= ( leftIndex
- i
);
217 tempIndex
= tempList
.count() + tempIndex
;
218 leftWindows
.prepend( tempList
[ tempIndex
] );
220 int rightWindowCount
= 0;
222 rightWindowCount
= tempList
.count()/2;
224 rightWindowCount
= ( tempList
.count() - 1 )/2;
225 for( int i
=0; i
< rightWindowCount
; i
++ )
227 int tempIndex
= ( rightIndex
+ i
) % tempList
.count();
228 rightWindows
.prepend( tempList
[ tempIndex
] );
233 // restrict painting the reflections to the current screen
234 QRegion clip
= QRegion( area
);
235 PaintClipper::push( clip
);
236 // no reflections during start and stop animation
237 if( !start
&& !stop
)
238 paintScene( frontWindow
, &leftWindows
, &rightWindows
, true );
239 PaintClipper::pop( clip
);
240 glEnable( GL_BLEND
);
241 glBlendFunc( GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
242 glPolygonMode( GL_FRONT
, GL_FILL
);
244 QRect fullRect
= effects
->clientArea( FullArea
, activeScreen
, effects
->currentDesktop() );
245 // we can use a huge scale factor (needed to calculate the rearground vertices)
246 // as we restrict with a PaintClipper painting on the current screen
247 float reflectionScaleFactor
= 100000 * tan( 60.0 * M_PI
/ 360.0f
)/area
.width();
248 if( effects
->numScreens() > 1 && area
.x() != fullRect
.x() )
250 // have to change the reflection area in horizontal layout and right screen
251 glTranslatef( -area
.x(), 0.0, 0.0 );
253 glTranslatef( area
.x() + area
.width()*0.5f
, 0.0, 0.0 );
255 -area
.width()*0.5f
, area
.height(), 0.0,
256 area
.width()*0.5f
, area
.height(), 0.0,
257 (float)area
.width()*reflectionScaleFactor
, area
.height(), -5000,
258 -(float)area
.width()*reflectionScaleFactor
, area
.height(), -5000 };
262 alpha
= timeLine
.value();
264 alpha
= 1.0 - timeLine
.value();
265 glColor4f( 0.0, 0.0, 0.0, alpha
);
268 // have to adjust the y values to fit OpenGL
269 // in OpenGL y==0 is at bottom, in Qt at top
270 if( effects
->numScreens() > 1 )
272 QRect fullArea
= effects
->clientArea( FullArea
, 0, 1 );
273 if( fullArea
.height() != area
.height() )
276 y
= fullArea
.height() - area
.height();
278 y
= fullArea
.height() - area
.y() - area
.height();
281 // use scissor to restrict painting of the reflection plane to current screen
282 glScissor( area
.x(), y
, area
.width(), area
.height() );
283 glEnable( GL_SCISSOR_TEST
);
284 glBegin( GL_POLYGON
);
285 glVertex3f( vertices
[0], vertices
[1], vertices
[2] );
286 glVertex3f( vertices
[3], vertices
[4], vertices
[5] );
289 glColor4f( 0.0, 0.0, 0.0, alpha
);
290 glVertex3f( vertices
[6], vertices
[7], vertices
[8] );
291 glVertex3f( vertices
[9], vertices
[10], vertices
[11] );
293 glDisable( GL_SCISSOR_TEST
);
296 glDisable( GL_BLEND
);
298 paintScene( frontWindow
, &leftWindows
, &rightWindows
);
300 if( effects
->numScreens() > 1 )
303 // revert change of projection matrix
304 glMatrixMode( GL_PROJECTION
);
306 glMatrixMode( GL_MODELVIEW
);
309 // caption of selected window
312 color_frame
= KColorScheme( QPalette::Active
, KColorScheme::Window
).background().color();
313 color_frame
.setAlphaF( 0.9 );
314 color_text
= KColorScheme( QPalette::Active
, KColorScheme::Window
).foreground().color();
317 color_frame
.setAlphaF( 0.9 * timeLine
.value() );
318 color_text
.setAlphaF( timeLine
.value() );
322 color_frame
.setAlphaF( 0.9 - 0.9 * timeLine
.value() );
323 color_text
.setAlphaF( 1.0 - timeLine
.value() );
326 text_font
.setBold( true );
327 text_font
.setPointSize( 20 );
328 glPushAttrib( GL_CURRENT_BIT
);
329 glColor4f( color_frame
.redF(), color_frame
.greenF(), color_frame
.blueF(), color_frame
.alphaF());
330 QRect frameRect
= QRect( area
.width()*0.25f
+ area
.x(),
331 area
.height()*0.9f
+ area
.y(),
333 QFontMetrics( text_font
).height() * 1.2f
);
334 renderRoundBoxWithEdge( frameRect
);
335 effects
->paintText( effects
->currentTabBoxWindow()->caption(),
337 frameRect
.width() - 100,
341 // icon of selected window
342 QPixmap iconPixmap
= effects
->currentTabBoxWindow()->icon();
345 int alpha
= 255.0f
* timeLine
.value();
348 alpha
= 255.0f
- alpha
;
350 QPixmap transparency
= iconPixmap
.copy( iconPixmap
.rect() );
351 transparency
.fill( QColor( 255, 255, 255, alpha
) );
352 iconPixmap
.setAlphaChannel( transparency
.alphaChannel() );
354 GLTexture
* icon
= new GLTexture( iconPixmap
);
356 glPushAttrib( GL_CURRENT_BIT
| GL_ENABLE_BIT
);
358 glEnable( GL_BLEND
);
359 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
360 // icon takes 80 % of the height of the frame. So each 10 % space left on the top and bottom
361 QRect iconRect
= QRect( frameRect
.x() + frameRect
.height()*0.1f
,
362 frameRect
.y() + frameRect
.height()*0.1f
,
363 frameRect
.height()*0.8f
,
364 frameRect
.height()*0.8f
);
365 icon
->render( region
, iconRect
);
368 glDisable( GL_BLEND
);
371 if( ( thumbnails
&& (!dynamicThumbnails
||
372 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
)) )
373 && !( start
|| stop
) )
376 // HACK: PaintClipper is used because window split is somehow wrong if the height is greater than width
377 PaintClipper::push( frame_area
.adjusted( frame_margin
, frame_margin
, -frame_margin
, -frame_margin
));
378 paintHighlight( highlight_area
);
379 foreach( EffectWindow
* w
, windows
.keys())
381 paintWindowThumbnail( w
);
382 paintWindowIcon( w
);
384 PaintClipper::pop( frame_area
.adjusted( frame_margin
, frame_margin
, -frame_margin
, -frame_margin
) );
389 void CoverSwitchEffect::postPaintScreen()
391 if( ( mActivated
&& ( animation
|| start
) ) || stop
|| stopRequested
)
393 if( timeLine
.value() == 1.0 )
395 timeLine
.setProgress(0.0);
399 effects
->setActiveFullScreenEffect( 0 );
402 startRequested
= false;
404 effects
->refTabBox();
411 else if( !scheduled_directions
.isEmpty() )
413 direction
= scheduled_directions
.dequeue();
426 stopRequested
= false;
431 effects
->addRepaintFull();
433 effects
->postPaintScreen();
436 void CoverSwitchEffect::paintScene( EffectWindow
* frontWindow
, QList
< EffectWindow
* >* leftWindows
,
437 QList
< EffectWindow
* >* rightWindows
, bool reflectedWindows
)
440 // one window in the front. Other windows left and right rotated
441 // for odd number of windows: left: (n-1)/2; front: 1; right: (n-1)/2
442 // for even number of windows: left: n/2; front: 1; right: n/2 -1
446 // all left windows are moved to next position
447 // top most left window is rotated and moved to front window position
448 // front window is rotated and moved to next right window position
449 // right windows are moved to next position
450 // last right window becomes totally transparent in half the time
451 // appears transparent on left side and becomes totally opaque again
452 // backward (alt+shift+tab) same as forward but opposite direction
453 int width
= area
.width();
454 int leftWindowCount
= leftWindows
->count();
455 int rightWindowCount
= rightWindows
->count();
457 rot
.axis
= RotationData::YAxis
;
460 // Problem during animation: a window which is painted after another window
461 // appears in front of the other
462 // so during animation the painting order has to be rearreanged
463 // paint sequence no animation: left, right, front
464 // paint sequence forward animation: right, front, left
468 paintWindows( leftWindows
, true, reflectedWindows
);
469 paintWindows( rightWindows
, false, reflectedWindows
);
470 paintFrontWindow( frontWindow
, width
, leftWindowCount
, rightWindowCount
, reflectedWindows
);
474 if( direction
== Right
)
476 if( timeLine
.value() < 0.5 )
478 // paint in normal way
479 paintWindows( leftWindows
, true, reflectedWindows
);
480 paintWindows( rightWindows
, false, reflectedWindows
);
481 paintFrontWindow( frontWindow
, width
, leftWindowCount
, rightWindowCount
, reflectedWindows
);
485 paintWindows( rightWindows
, false, reflectedWindows
);
486 paintFrontWindow( frontWindow
, width
, leftWindowCount
, rightWindowCount
, reflectedWindows
);
487 paintWindows( leftWindows
, true, reflectedWindows
, rightWindows
->at( 0 ) );
492 paintWindows( leftWindows
, true, reflectedWindows
);
493 if( timeLine
.value() < 0.5 )
495 paintWindows( rightWindows
, false, reflectedWindows
);
496 paintFrontWindow( frontWindow
, width
, leftWindowCount
, rightWindowCount
, reflectedWindows
);
500 EffectWindow
* leftWindow
;
501 if( leftWindowCount
> 0)
503 leftWindow
= leftWindows
->at( 0 );
504 paintFrontWindow( frontWindow
, width
, leftWindowCount
, rightWindowCount
, reflectedWindows
);
507 leftWindow
= frontWindow
;
508 paintWindows( rightWindows
, false, reflectedWindows
, leftWindow
);
514 void CoverSwitchEffect::paintWindow( EffectWindow
* w
, int mask
, QRegion region
, WindowPaintData
& data
)
516 if( mActivated
|| stop
|| stopRequested
)
518 if( !( mask
& PAINT_WINDOW_TRANSFORMED
) && !w
->isDesktop() )
520 if( ( start
|| stop
) && w
->isDock() )
522 data
.opacity
= 1.0 - timeLine
.value();
524 data
.opacity
= timeLine
.value();
530 if ( ( start
|| stop
) && (!w
->isOnCurrentDesktop() || w
->isMinimized() ) )
532 if (stop
) // Fade out windows not on the current desktop
533 data
.opacity
= (1.0 - timeLine
.value());
534 else // Fade in Windows from other desktops when animation is started
535 data
.opacity
= timeLine
.value();
537 effects
->paintWindow( w
, mask
, region
, data
);
540 void CoverSwitchEffect::tabBoxAdded( int mode
)
542 if( effects
->activeFullScreenEffect() && effects
->activeFullScreenEffect() != this )
546 // only for windows mode
547 if( mode
== TabBoxWindowsMode
&& effects
->currentTabBoxWindowList().count() > 0 )
549 input
= effects
->createFullScreenInputWindow( this, Qt::ArrowCursor
);
550 activeScreen
= effects
->activeScreen();
551 if( !stop
&& !stopRequested
)
553 effects
->refTabBox();
554 effects
->setActiveFullScreenEffect( this );
555 scheduled_directions
.clear();
556 selected_window
= effects
->currentTabBoxWindow();
564 // Calculation of correct area
565 area
= effects
->clientArea( FullScreenArea
, activeScreen
, effects
->currentDesktop());
566 scaleFactor
= (zPosition
+1100) * 2.0 * tan( 60.0 * M_PI
/ 360.0f
)/displayWidth();
567 if( displayWidth()-area
.width() != 0 )
569 // one of the screens is smaller than the other (horizontal)
570 if( area
.width() < displayWidth() - area
.width() )
571 scaleFactor
*= (float)area
.width()/(float)(displayWidth()-area
.width());
572 else if( area
.width() != displayWidth() - area
.width() )
574 // vertical layout with different width
575 // but we don't want to catch screens with same width and different height
576 if( displayHeight() != area
.height() )
577 scaleFactor
*= (float)area
.width()/(float)(displayWidth());
581 effects
->addRepaintFull();
585 startRequested
= true;
587 if( thumbnails
&& (!dynamicThumbnails
||
588 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
)) )
590 highlight_is_set
= false;
591 calculateFrameSize();
592 calculateItemSizes();
598 void CoverSwitchEffect::tabBoxClosed()
604 if( !animation
&& !start
)
608 else if( start
&& scheduled_directions
.isEmpty() )
612 timeLine
.setProgress( 1.0 - timeLine
.value() );
616 stopRequested
= true;
620 effects
->setActiveFullScreenEffect( 0 );
622 effects
->unrefTabBox();
623 effects
->destroyInputWindow( input
);
624 effects
->addRepaintFull();
625 if( thumbnails
&& (!dynamicThumbnails
||
626 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
)) )
628 qDeleteAll( windows
);
634 void CoverSwitchEffect::tabBoxUpdated()
638 if( animateSwitch
&& effects
->currentTabBoxWindowList().count() > 1)
640 // determine the switch direction
641 if( selected_window
!= effects
->currentTabBoxWindow() )
643 if( selected_window
!= NULL
)
645 int old_index
= effects
->currentTabBoxWindowList().indexOf( selected_window
);
646 int new_index
= effects
->currentTabBoxWindowList().indexOf( effects
->currentTabBoxWindow() );
647 Direction new_direction
;
648 int distance
= new_index
- old_index
;
650 new_direction
= Left
;
652 new_direction
= Right
;
653 if( effects
->currentTabBoxWindowList().count() == 2 )
655 new_direction
= Left
;
660 distance
= abs( distance
);
661 int tempDistance
= effects
->currentTabBoxWindowList().count() - distance
;
662 if( tempDistance
< abs( distance
) )
664 distance
= tempDistance
;
665 if( new_direction
== Left
)
666 new_direction
= Right
;
668 new_direction
= Left
;
670 if( !animation
&& !start
)
673 direction
= new_direction
;
676 for( int i
=0; i
<distance
; i
++ )
678 if( !scheduled_directions
.isEmpty() && scheduled_directions
.last() != new_direction
)
679 scheduled_directions
.pop_back();
681 scheduled_directions
.enqueue( new_direction
);
682 if( scheduled_directions
.count() == effects
->currentTabBoxWindowList().count() )
683 scheduled_directions
.clear();
687 selected_window
= effects
->currentTabBoxWindow();
690 if( thumbnails
&& (!dynamicThumbnails
||
691 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
)) )
693 calculateFrameSize();
694 calculateItemSizes();
696 effects
->addRepaintFull();
700 void CoverSwitchEffect::paintWindowCover( EffectWindow
* w
, bool reflectedWindow
, WindowPaintData
& data
)
702 QRect windowRect
= w
->geometry();
703 data
.yTranslate
= area
.height() - windowRect
.y() - windowRect
.height();
704 data
.zTranslate
= -zPosition
;
707 if( w
->isMinimized() )
709 data
.opacity
*= timeLine
.value();
713 data
.xTranslate
*= timeLine
.value();
714 data
.yTranslate
*= timeLine
.value();
715 if( effects
->numScreens() > 1)
717 QRect clientRect
= effects
->clientArea( FullScreenArea
, w
->screen(), effects
->currentDesktop() );
718 QRect fullRect
= effects
->clientArea( FullArea
, activeScreen
, effects
->currentDesktop() );
719 if( w
->screen() == activeScreen
)
721 if( clientRect
.width() != fullRect
.width() && clientRect
.x() != fullRect
.x() )
723 data
.xTranslate
-= clientRect
.x()*(1.0f
-timeLine
.value());
725 if( clientRect
.height() != fullRect
.height() && clientRect
.y() != fullRect
.y() )
727 data
.yTranslate
-= clientRect
.y()*(1.0f
-timeLine
.value());
732 if( clientRect
.width() != fullRect
.width() && clientRect
.x() < area
.x())
734 data
.xTranslate
-= clientRect
.width()*(1.0f
-timeLine
.value());
736 if( clientRect
.height() != fullRect
.height() && clientRect
.y() < area
.y() )
738 data
.yTranslate
-= clientRect
.height()*(1.0f
-timeLine
.value());
742 data
.zTranslate
*= timeLine
.value();
744 data
.rotation
->angle
*= timeLine
.value();
749 if( w
->isMinimized() && w
!= effects
->activeWindow() )
751 data
.opacity
*= (1.0 - timeLine
.value());
755 data
.xTranslate
*= (1.0 - timeLine
.value());
756 data
.yTranslate
*= (1.0 - timeLine
.value());
757 if( effects
->numScreens() > 1)
759 QRect clientRect
= effects
->clientArea( FullScreenArea
, w
->screen(), effects
->currentDesktop() );
760 QRect rect
= effects
->clientArea( FullScreenArea
, activeScreen
, effects
->currentDesktop() );
761 QRect fullRect
= effects
->clientArea( FullArea
, activeScreen
, effects
->currentDesktop() );
762 if( w
->screen() == activeScreen
)
764 if( clientRect
.width() != fullRect
.width() && clientRect
.x() != fullRect
.x() )
766 data
.xTranslate
-= clientRect
.x()*timeLine
.value();
768 if( clientRect
.height() != fullRect
.height() && clientRect
.y() != fullRect
.y() )
770 data
.yTranslate
-= clientRect
.y()*timeLine
.value();
775 if( clientRect
.width() != fullRect
.width() && clientRect
.x() < rect
.x())
777 data
.xTranslate
-= clientRect
.width()*timeLine
.value();
779 if( clientRect
.height() != fullRect
.height() && clientRect
.y() < area
.y() )
781 data
.yTranslate
-= clientRect
.height()*timeLine
.value();
785 data
.zTranslate
*= (1.0 - timeLine
.value());
787 data
.rotation
->angle
*= (1.0 - timeLine
.value());
791 QRect thumbnail
= infiniteRegion();
793 if( reflectedWindow
)
796 glScalef( 1.0, -1.0, 1.0 );
797 data
.yTranslate
= - area
.height() - windowRect
.y() - windowRect
.height();
798 effects
->paintWindow( w
,
799 PAINT_WINDOW_TRANSFORMED
,
800 infiniteRegion(), data
);
805 effects
->paintWindow( w
,
806 PAINT_WINDOW_TRANSFORMED
,
807 infiniteRegion(), data
);
811 void CoverSwitchEffect::paintFrontWindow( EffectWindow
* frontWindow
, int width
, int leftWindows
, int rightWindows
, bool reflectedWindow
)
813 if( frontWindow
== NULL
)
815 float distance
= 0.0;
816 bool specialHandlingForward
= false;
817 WindowPaintData
data( frontWindow
);
818 data
.xTranslate
= area
.width()*0.5 - frontWindow
->geometry().x() - frontWindow
->geometry().width()*0.5;
819 if( leftWindows
== 0 )
822 if( !start
&& !stop
)
823 specialHandlingForward
= true;
825 if( rightWindows
== 0 )
831 if( direction
== Right
)
834 distance
= -frontWindow
->geometry().width()*0.5f
+ area
.width()*0.5f
+
835 (((float)displayWidth()*0.5*scaleFactor
)-(float)area
.width()*0.5f
)/rightWindows
;
836 data
.xTranslate
+= distance
* timeLine
.value();
838 rot
.axis
= RotationData::YAxis
;
839 rot
.angle
= -angle
*timeLine
.value();
840 rot
.xRotationPoint
= frontWindow
->geometry().width();
841 data
.rotation
= &rot
;
846 distance
= frontWindow
->geometry().width()*0.5f
- area
.width()*0.5f
+
847 ((float)width
*0.5f
-((float)displayWidth()*0.5*scaleFactor
))/leftWindows
;
849 if( specialHandlingForward
)
851 data
.xTranslate
+= distance
* timeLine
.value() * factor
;
853 rot
.axis
= RotationData::YAxis
;
854 rot
.angle
= angle
*timeLine
.value();
855 data
.rotation
= &rot
;
858 if( specialHandlingForward
)
860 data
.opacity
*= (1.0 - timeLine
.value() * 2.0);
861 paintWindowCover( frontWindow
, reflectedWindow
, data
);
864 paintWindowCover( frontWindow
, reflectedWindow
, data
);
867 void CoverSwitchEffect::paintWindows( QList
< EffectWindow
* >* windows
, bool left
, bool reflectedWindows
, EffectWindow
* additionalWindow
)
869 int width
= area
.width();
870 int windowCount
= windows
->count();
871 EffectWindow
* window
;
873 int rotateFactor
= 1;
879 float xTranslate
= -((float)(width
)*0.5f
-((float)displayWidth()*0.5*scaleFactor
));
881 xTranslate
= ((float)displayWidth()*0.5*scaleFactor
)-(float)width
*0.5f
;
882 // handling for additional window from other side
883 // has to appear on this side after half of the time
884 if( animation
&& timeLine
.value() >= 0.5 && additionalWindow
!= NULL
)
887 rot
.axis
= RotationData::YAxis
;
889 rot
.angle
= angle
*rotateFactor
;
890 WindowPaintData
data( additionalWindow
);
892 data
.xTranslate
+= -xTranslate
- additionalWindow
->geometry().x();
895 data
.xTranslate
+= xTranslate
+ area
.width() -
896 additionalWindow
->geometry().x() - additionalWindow
->geometry().width();
897 rot
.xRotationPoint
= additionalWindow
->geometry().width();
899 data
.rotation
= &rot
;
900 data
.opacity
*= ( timeLine
.value() - 0.5 ) * 2.0;
901 paintWindowCover( additionalWindow
, reflectedWindows
, data
);
904 rot
.axis
= RotationData::YAxis
;
906 for( int i
=0; i
< windowCount
; i
++ )
908 window
= windows
->at( i
);
911 WindowPaintData
data( window
);
914 data
.xTranslate
+= -xTranslate
+ xTranslate
*i
/windowCount
- window
->geometry().x();
916 data
.xTranslate
+= xTranslate
+ width
- xTranslate
*i
/windowCount
- window
->geometry().x() - window
->geometry().width();
919 if( direction
== Right
)
921 if( ( i
== windowCount
- 1 ) && left
)
923 // right most window on left side -> move to front
924 // have to move one window distance plus half the difference between the window and the desktop size
925 data
.xTranslate
+= (xTranslate
/windowCount
+ (width
- window
->geometry().width())*0.5f
)*timeLine
.value();
926 rot
.angle
= ( angle
- angle
* timeLine
.value() );
928 // right most window does not have to be moved
929 else if( !left
&& ( i
== 0 ) ); // do nothing
932 // all other windows - move to next position
933 data
.xTranslate
+= xTranslate
/windowCount
* timeLine
.value();
938 if( ( i
== windowCount
- 1 ) && !left
)
940 // left most window on right side -> move to front
941 data
.xTranslate
-= (xTranslate
/windowCount
+ (width
- window
->geometry().width())*0.5f
)*timeLine
.value();
942 rot
.angle
= ( angle
- angle
* timeLine
.value() );
944 // left most window does not have to be moved
945 else if( i
==0 && left
); // do nothing
948 // all other windows - move to next position
949 data
.xTranslate
-= xTranslate
/windowCount
* timeLine
.value();
954 rot
.xRotationPoint
= 0.0;
956 rot
.xRotationPoint
= window
->geometry().width();
957 rot
.angle
*= rotateFactor
;
958 data
.rotation
= &rot
;
959 // make window most to edge transparent if animation
960 if( animation
&& i
== 0 && ( ( direction
== Left
&& left
) || ( direction
== Right
&& !left
) ) )
962 // only for the first half of the animation
963 if( timeLine
.value() < 0.5 )
965 data
.opacity
*= (1.0 - timeLine
.value() * 2.0);
966 paintWindowCover( window
, reflectedWindows
, data
);
971 paintWindowCover( window
, reflectedWindows
, data
);
976 // thumbnail bar - taken from boxswitch effect
977 void CoverSwitchEffect::calculateFrameSize()
981 QRect screenr
= effects
->clientArea( PlacementArea
, activeScreen
, effects
->currentDesktop());
982 itemcount
= effects
->currentTabBoxWindowList().count();
983 item_max_size
.setWidth( (screenr
.width()*0.95f
- frame_margin
* 2)/itemcount
);
984 if( item_max_size
.width() > 250 )
985 item_max_size
.setWidth( 250 );
986 item_max_size
.setHeight( item_max_size
.width() * ((float)screenr
.height()/(float)screenr
.width()) );
987 // Shrink the size until all windows/desktops can fit onscreen
988 frame_area
.setWidth( frame_margin
* 2 + itemcount
* item_max_size
.width());
989 frame_area
.setHeight( frame_margin
* 2 + item_max_size
.height() );
991 frame_area
.moveTo( screenr
.x() + ( screenr
.width() - frame_area
.width()) / 2,
992 screenr
.y() + screenr
.height()*0.05f
);
995 void CoverSwitchEffect::calculateItemSizes()
998 EffectWindowList original_windows
= effects
->currentTabBoxWindowList();
999 int index
= original_windows
.indexOf( effects
->currentTabBoxWindow() );
1000 int leftIndex
= index
;
1001 int rightIndex
= index
+ 1;
1002 if( rightIndex
== original_windows
.count() )
1004 EffectWindowList ordered_windows
;
1006 int leftWindowCount
= original_windows
.count()/2;
1007 int rightWindowCount
= leftWindowCount
;
1008 if( original_windows
.count()%2 == 1 )
1010 for( int i
=0; i
< leftWindowCount
; i
++ )
1012 int tempIndex
= ( leftIndex
- i
);
1014 tempIndex
= original_windows
.count() + tempIndex
;
1015 ordered_windows
.prepend( original_windows
[ tempIndex
] );
1017 for( int i
=0; i
< rightWindowCount
; i
++ )
1019 int tempIndex
= ( rightIndex
+ i
) % original_windows
.count();
1020 ordered_windows
.append( original_windows
[ tempIndex
] );
1022 // move items cause of schedule
1023 for( int i
=0; i
< scheduled_directions
.count(); i
++ )
1025 Direction actual
= scheduled_directions
[ i
];
1026 if( actual
== Left
)
1028 EffectWindow
* w
= ordered_windows
.takeLast();
1029 ordered_windows
.prepend( w
);
1033 EffectWindow
* w
= ordered_windows
.takeFirst();
1034 ordered_windows
.append( w
);
1037 if( animation
&& timeLine
.value() < 0.5 )
1039 if( direction
== Left
)
1041 EffectWindow
* w
= ordered_windows
.takeLast();
1043 ordered_windows
.prepend( w
);
1047 EffectWindow
* w
= ordered_windows
.takeFirst();
1049 ordered_windows
.append( w
);
1052 else if( animation
&& timeLine
.value() >= 0.5 )
1054 if( animation
&& direction
== Left
)
1055 edge_window
= ordered_windows
.last();
1056 if( animation
&& direction
== Right
)
1057 edge_window
= ordered_windows
.first();
1062 if( direction
== Left
)
1063 offset
= (float)item_max_size
.width()*(1.0-timeLine
.value());
1065 offset
= -(float)item_max_size
.width()*(1.0-timeLine
.value());
1067 for( int i
= 0; i
< ordered_windows
.count(); i
++ )
1069 EffectWindow
* w
= ordered_windows
.at( i
);
1070 windows
[ w
] = new ItemInfo();
1072 float moveIndex
= i
;
1073 if( animation
&& timeLine
.value() < 0.5 )
1075 if( direction
== Left
)
1080 if( ordered_windows
.count()%2 == 0 )
1082 windows
[ w
]->area
= QRect( frame_area
.x() + frame_margin
1083 + moveIndex
* item_max_size
.width() + offset
,
1084 frame_area
.y() + frame_margin
,
1085 item_max_size
.width(), item_max_size
.height());
1086 windows
[ w
]->clickable
= windows
[ w
]->area
;
1088 if( ordered_windows
.count()%2 == 0 )
1090 right_window
= ordered_windows
.last();
1092 if( !highlight_is_set
)
1094 highlight_area
= windows
[ effects
->currentTabBoxWindow() ]->area
;
1095 highlight_is_set
= true;
1099 void CoverSwitchEffect::paintFrame()
1101 glPushAttrib( GL_CURRENT_BIT
);
1102 glColor4f( color_frame
.redF(), color_frame
.greenF(), color_frame
.blueF(), color_frame
.alphaF());
1103 renderRoundBoxWithEdge( frame_area
);
1107 void CoverSwitchEffect::paintHighlight( QRect area
)
1109 glPushAttrib( GL_CURRENT_BIT
);
1110 glColor4f( color_highlight
.redF(), color_highlight
.greenF(), color_highlight
.blueF(), color_highlight
.alphaF());
1111 renderRoundBox( area
, 6 );
1115 void CoverSwitchEffect::paintWindowThumbnail( EffectWindow
* w
)
1117 if( !windows
.contains( w
))
1119 WindowPaintData
data( w
);
1121 setPositionTransformations( data
,
1122 windows
[ w
]->thumbnail
, w
,
1123 windows
[ w
]->area
.adjusted( highlight_margin
, highlight_margin
, -highlight_margin
, -highlight_margin
),
1124 Qt::KeepAspectRatio
);
1126 if( animation
&& ( w
== edge_window
) && ( windows
.size() % 2 == 1 ) )
1128 // in case of animation:
1129 // the window which has to change the side will be split and painted on both sides of the edge
1130 double splitPoint
= 0.0;
1131 if( direction
== Left
)
1133 splitPoint
= w
->geometry().width()*timeLine
.value();
1137 splitPoint
= w
->geometry().width() - w
->geometry().width()*timeLine
.value();
1139 data
.quads
= data
.quads
.splitAtX( splitPoint
);
1140 WindowQuadList left_quads
;
1141 WindowQuadList right_quads
;
1142 foreach( const WindowQuad
&quad
, data
.quads
)
1144 if( quad
.left() >= splitPoint
)
1146 if( quad
.right() <= splitPoint
)
1147 right_quads
<< quad
;
1149 // the base position of the window is changed after half of the animation
1150 if( timeLine
.value() < 0.5 )
1152 if( direction
== Left
)
1153 data
.quads
= left_quads
;
1155 data
.quads
= right_quads
;
1159 if( direction
== Left
)
1160 data
.quads
= right_quads
;
1162 data
.quads
= left_quads
;
1165 // paint one part of the thumbnail
1166 effects
->drawWindow( w
,
1167 PAINT_WINDOW_OPAQUE
| PAINT_WINDOW_TRANSFORMED
,
1168 windows
[ w
]->thumbnail
, data
);
1170 QRect secondThumbnail
;
1172 // paint the second part of the thumbnail:
1173 // the other window quads are needed and a new rect for transformation has to be calculated
1174 if( direction
== Left
)
1176 if( timeLine
.value() < 0.5 )
1178 data
.quads
= right_quads
;
1179 secondThumbnail
= QRect( frame_area
.x() + frame_area
.width() - frame_margin
1180 - (float)item_max_size
.width()*timeLine
.value(),
1181 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1185 data
.quads
= left_quads
;
1186 secondThumbnail
= QRect( frame_area
.x() + frame_margin
- (float)item_max_size
.width()*timeLine
.value(),
1187 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1189 secondThumbnail
= QRect( frame_area
.x() + frame_margin
-
1190 (float)item_max_size
.width()*(timeLine
.value()-0.5),
1191 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1196 if( timeLine
.value() < 0.5 )
1198 data
.quads
= left_quads
;
1199 secondThumbnail
= QRect( frame_area
.x() + frame_margin
-
1200 (float)item_max_size
.width()*(1.0 - timeLine
.value()),
1201 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1205 data
.quads
= right_quads
;
1206 secondThumbnail
= QRect( frame_area
.x() + frame_area
.width() - frame_margin
1207 - (float)item_max_size
.width()*(1.0 - timeLine
.value()),
1208 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1211 setPositionTransformations( data
,
1212 windows
[ w
]->thumbnail
, w
,
1213 secondThumbnail
.adjusted( highlight_margin
, highlight_margin
, -highlight_margin
, -highlight_margin
),
1214 Qt::KeepAspectRatio
);
1215 effects
->drawWindow( w
,
1216 PAINT_WINDOW_OPAQUE
| PAINT_WINDOW_TRANSFORMED
,
1217 windows
[ w
]->thumbnail
, data
);
1219 else if( ( windows
.size() % 2 == 0 ) && ( w
== right_window
) )
1221 // in case of even number of thumbnails:
1222 // the window on the right is painted one half on left and on half on the right side
1223 float animationOffset
= 0.0f
;
1224 double splitPoint
= w
->geometry().width()*0.5;
1225 if( animation
&& timeLine
.value() <= 0.5 )
1227 // in case of animation the right window has only to be split during first half of animation
1228 if( direction
== Left
)
1230 splitPoint
+= w
->geometry().width()*timeLine
.value();
1231 animationOffset
= -(float)item_max_size
.width()*timeLine
.value();
1235 splitPoint
-= w
->geometry().width()*timeLine
.value();
1236 animationOffset
= (float)item_max_size
.width()*timeLine
.value();
1239 if( animation
&& timeLine
.value() > 0.5 )
1241 // at half of animation a different window has become the right window
1242 // we have to adjust the splitting again
1243 if( direction
== Left
)
1245 splitPoint
-= w
->geometry().width()*(1.0-timeLine
.value());
1246 animationOffset
= (float)item_max_size
.width()*(1.0-timeLine
.value());
1250 splitPoint
+= w
->geometry().width()*(1.0-timeLine
.value());
1251 animationOffset
= -(float)item_max_size
.width()*(1.0-timeLine
.value());
1254 data
.quads
= data
.quads
.splitAtX( splitPoint
);
1255 WindowQuadList rightQuads
;
1256 WindowQuadList leftQuads
;
1257 foreach( const WindowQuad
&quad
, data
.quads
)
1259 if( quad
.right() <= splitPoint
)
1265 // left quads are painted on right side of frame
1266 data
.quads
= leftQuads
;
1267 effects
->drawWindow( w
,
1268 PAINT_WINDOW_OPAQUE
| PAINT_WINDOW_TRANSFORMED
,
1269 windows
[ w
]->thumbnail
, data
);
1271 // right quads are painted on left side of frame
1272 data
.quads
= rightQuads
;
1273 QRect secondThumbnail
;
1274 secondThumbnail
= QRect( frame_area
.x() + frame_margin
-
1275 (float)item_max_size
.width()*0.5 + animationOffset
,
1276 frame_area
.y() + frame_margin
, item_max_size
.width(), item_max_size
.height());
1277 setPositionTransformations( data
,
1278 windows
[ w
]->thumbnail
, w
,
1279 secondThumbnail
.adjusted( highlight_margin
, highlight_margin
, -highlight_margin
, -highlight_margin
),
1280 Qt::KeepAspectRatio
);
1281 effects
->drawWindow( w
,
1282 PAINT_WINDOW_OPAQUE
| PAINT_WINDOW_TRANSFORMED
,
1283 windows
[ w
]->thumbnail
, data
);
1287 effects
->drawWindow( w
,
1288 PAINT_WINDOW_OPAQUE
| PAINT_WINDOW_TRANSFORMED
,
1289 windows
[ w
]->thumbnail
, data
);
1293 void CoverSwitchEffect::paintWindowIcon( EffectWindow
* w
)
1295 if( !windows
.contains( w
))
1297 // Don't render null icons
1298 if( w
->icon().isNull() )
1303 if( windows
[ w
]->icon
.cacheKey() != w
->icon().cacheKey())
1304 { // make sure windows[ w ]->icon is the right QPixmap, and rebind
1305 windows
[ w
]->icon
= w
->icon();
1306 if( ( windows
.size() % 2 == 1 ) && animation
&& w
== edge_window
)
1309 if( timeLine
.value() < 0.5 )
1310 alpha
= 255.0f
* (1.0 - timeLine
.value()*2.0);
1312 alpha
= 255.0f
* (timeLine
.value()*2.0 - 1.0);
1313 QPixmap transparency
= windows
[ w
]->icon
.copy( windows
[ w
]->icon
.rect() );
1314 transparency
.fill( QColor( 255, 255, 255, alpha
) );
1315 windows
[ w
]->icon
.setAlphaChannel( transparency
.alphaChannel() );
1317 windows
[ w
]->iconTexture
.load( windows
[ w
]->icon
);
1318 windows
[ w
]->iconTexture
.setFilter( GL_LINEAR
);
1320 int width
= windows
[ w
]->icon
.width();
1321 int height
= windows
[ w
]->icon
.height();
1322 int x
= windows
[ w
]->area
.x() + windows
[ w
]->area
.width() - width
- highlight_margin
;
1323 int y
= windows
[ w
]->area
.y() + windows
[ w
]->area
.height() - height
- highlight_margin
;
1324 if( ( windows
.size() % 2 == 0 ) )
1326 if( w
== right_window
)
1328 // in case of right window the icon has to be painted on the left side of the frame
1329 x
= frame_area
.x() + windows
[ w
]->area
.width()*0.5 - width
- highlight_margin
;
1332 if( timeLine
.value() <= 0.5 )
1334 if( direction
== Left
)
1336 x
-= windows
[ w
]->area
.width()*timeLine
.value();
1337 x
= qMax( x
, frame_area
.x() + frame_margin
);
1340 x
+= windows
[ w
]->area
.width()*timeLine
.value();
1344 if( direction
== Left
)
1345 x
+= windows
[ w
]->area
.width()*(1.0-timeLine
.value());
1348 x
-= windows
[ w
]->area
.width()*(1.0-timeLine
.value());
1349 x
= qMax( x
, frame_area
.x() + frame_margin
);
1357 // during animation the icon of the edge window has to change position
1358 if( animation
&& w
== edge_window
)
1360 if( timeLine
.value() < 0.5 )
1362 if( direction
== Left
)
1363 x
+= windows
[ w
]->area
.width()*timeLine
.value();
1365 x
-= windows
[ w
]->area
.width()*timeLine
.value();
1369 if( direction
== Left
)
1370 x
-= windows
[ w
]->area
.width()*(1.0 - timeLine
.value());
1372 x
+= windows
[ w
]->area
.width()*(1.0 - timeLine
.value());
1376 glPushAttrib( GL_CURRENT_BIT
| GL_ENABLE_BIT
);
1377 glEnable( GL_BLEND
);
1378 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
1379 // Render some background
1381 if( ( windows
.size() % 2 == 1 ) && animation
&& w
== edge_window
)
1383 if( timeLine
.value() < 0.5 )
1384 alpha
*= (1.0 - timeLine
.value()*2.0);
1386 alpha
*= (timeLine
.value()*2.0 - 1.0);
1388 glColor4f( 0, 0, 0, alpha
);
1389 renderRoundBox( QRect( x
-3, y
-3, width
+6, height
+6 ), 3 );
1391 glColor4f( 1, 1, 1, 1 );
1392 windows
[ w
]->iconTexture
.bind();
1393 windows
[ w
]->iconTexture
.render( infiniteRegion(), QRect( x
, y
, width
, height
));
1394 windows
[ w
]->iconTexture
.unbind();
1398 void CoverSwitchEffect::windowInputMouseEvent( Window w
, QEvent
* e
)
1400 assert( w
== input
);
1401 if( e
->type() != QEvent::MouseButtonPress
)
1403 // we don't want click events during animations
1406 QPoint pos
= static_cast< QMouseEvent
* >( e
)->pos();
1408 // has one of the thumbnails been clicked?
1409 if( (thumbnails
&& (!dynamicThumbnails
||
1410 (dynamicThumbnails
&& effects
->currentTabBoxWindowList().size() >= thumbnailWindows
))))
1412 // determine which item was clicked
1413 foreach( EffectWindow
* w
, windows
.keys())
1415 if( windows
[ w
]->clickable
.contains( pos
))
1417 effects
->setTabBoxWindow( w
);
1421 // special handling for second half of window in case of animation and even number of windows
1422 if( windows
.size() % 2 == 0 )
1424 QRect additionalRect
= QRect( frame_area
.x() + frame_margin
,
1425 frame_area
.y() + frame_margin
,
1426 item_max_size
.width()*0.5, item_max_size
.height());
1427 if( additionalRect
.contains( pos
))
1429 effects
->setTabBoxWindow( right_window
);
1435 // determine if a window has been clicked
1436 // not interested in events above a fullscreen window (ignoring panel size)
1437 if( pos
.y() < (area
.height()*scaleFactor
- area
.height())*0.5f
*(1.0f
/scaleFactor
) )
1440 if( pos
.x() < (area
.width()*scaleFactor
- selected_window
->width())*0.5f
*(1.0f
/scaleFactor
) )
1442 float availableSize
= (area
.width()*scaleFactor
- area
.width())*0.5f
*(1.0f
/scaleFactor
);
1443 for( int i
=0;i
<leftWindows
.count();i
++ )
1445 int windowPos
= availableSize
/leftWindows
.count()*i
;
1446 if( pos
.x() < windowPos
)
1448 if( i
+1 < leftWindows
.count() )
1450 if( pos
.x() > availableSize
/leftWindows
.count()*(i
+1) )
1454 effects
->setTabBoxWindow( leftWindows
[i
] );
1459 if( pos
.x() > area
.width() - (area
.width()*scaleFactor
- selected_window
->width())*0.5f
*(1.0f
/scaleFactor
) )
1461 float availableSize
= (area
.width()*scaleFactor
- area
.width())*0.5f
*(1.0f
/scaleFactor
);
1462 for( int i
=0;i
<rightWindows
.count();i
++ )
1464 int windowPos
= area
.width() - availableSize
/rightWindows
.count()*i
;
1465 if( pos
.x() > windowPos
)
1467 if( i
+1 < rightWindows
.count() )
1469 if( pos
.x() < area
.width() - availableSize
/rightWindows
.count()*(i
+1) )
1473 effects
->setTabBoxWindow( rightWindows
[i
] );