We have to keep track of the currentTabBoxWindowList in tabbox effects:
when a client closes, windowClosed is called before it is removed from the list. So we have to remove it from our list and make sure it isn't used any more. And just to be sure we reference the window and unref after the effect closes. The windowList is only changed in tabBoxAdded and tabBoxUpdated. BUG: 184602 svn path=/trunk/KDE/kdebase/workspace/; revision=1016998
This commit is contained in:
parent
8b19de13f0
commit
465fd0fbca
2 changed files with 59 additions and 31 deletions
|
@ -106,7 +106,7 @@ void CoverSwitchEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
|||
{
|
||||
timeLine.addTime( (double)time );
|
||||
if( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
calculateItemSizes();
|
||||
}
|
||||
if( effects->currentTabBoxWindow() == NULL )
|
||||
|
@ -176,8 +176,8 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
glTranslatef( xTranslate, yTranslate, 0.0 );
|
||||
}
|
||||
|
||||
QList< EffectWindow* > tempList = effects->currentTabBoxWindowList();
|
||||
int index = tempList.indexOf( effects->currentTabBoxWindow() );
|
||||
QList< EffectWindow* > tempList = currentWindowList;
|
||||
int index = tempList.indexOf( selected_window );
|
||||
if( animation || start || stop )
|
||||
{
|
||||
if( !start && !stop )
|
||||
|
@ -245,7 +245,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
PaintClipper::push( clip );
|
||||
// no reflections during start and stop animation
|
||||
if( !start && !stop )
|
||||
paintScene( frontWindow, &leftWindows, &rightWindows, true );
|
||||
paintScene( frontWindow, leftWindows, rightWindows, true );
|
||||
PaintClipper::pop( clip );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
@ -305,7 +305,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
glPopMatrix();
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
paintScene( frontWindow, &leftWindows, &rightWindows );
|
||||
paintScene( frontWindow, leftWindows, rightWindows );
|
||||
|
||||
if( effects->numScreens() > 1 )
|
||||
{
|
||||
|
@ -328,7 +328,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
|||
}
|
||||
|
||||
if( ( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
&& !( start || stop ) )
|
||||
{
|
||||
thumbnailFrame.render( region );
|
||||
|
@ -356,11 +356,18 @@ void CoverSwitchEffect::postPaintScreen()
|
|||
{
|
||||
stop = false;
|
||||
effects->setActiveFullScreenEffect( 0 );
|
||||
foreach( EffectWindow* window, referrencedWindows )
|
||||
{
|
||||
window->unrefWindow();
|
||||
}
|
||||
referrencedWindows.clear();
|
||||
currentWindowList.clear();
|
||||
if( startRequested )
|
||||
{
|
||||
startRequested = false;
|
||||
mActivated = true;
|
||||
effects->refTabBox();
|
||||
currentWindowList = effects->currentTabBoxWindowList();
|
||||
if( animateStart )
|
||||
{
|
||||
start = true;
|
||||
|
@ -392,8 +399,8 @@ void CoverSwitchEffect::postPaintScreen()
|
|||
effects->postPaintScreen();
|
||||
}
|
||||
|
||||
void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, QList< EffectWindow* >* leftWindows,
|
||||
QList< EffectWindow* >* rightWindows, bool reflectedWindows )
|
||||
void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, const EffectWindowList& leftWindows,
|
||||
const EffectWindowList& rightWindows, bool reflectedWindows )
|
||||
{
|
||||
// LAYOUT
|
||||
// one window in the front. Other windows left and right rotated
|
||||
|
@ -410,8 +417,8 @@ 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 leftWindowCount = leftWindows->count();
|
||||
int rightWindowCount = rightWindows->count();
|
||||
int leftWindowCount = leftWindows.count();
|
||||
int rightWindowCount = rightWindows.count();
|
||||
RotationData rot;
|
||||
rot.axis = RotationData::YAxis;
|
||||
|
||||
|
@ -443,7 +450,7 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, QList< EffectWind
|
|||
{
|
||||
paintWindows( rightWindows, false, reflectedWindows );
|
||||
paintFrontWindow( frontWindow, width, leftWindowCount, rightWindowCount, reflectedWindows );
|
||||
paintWindows( leftWindows, true, reflectedWindows, rightWindows->at( 0 ) );
|
||||
paintWindows( leftWindows, true, reflectedWindows, rightWindows.at( 0 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -459,7 +466,7 @@ void CoverSwitchEffect::paintScene( EffectWindow* frontWindow, QList< EffectWind
|
|||
EffectWindow* leftWindow;
|
||||
if( leftWindowCount > 0)
|
||||
{
|
||||
leftWindow = leftWindows->at( 0 );
|
||||
leftWindow = leftWindows.at( 0 );
|
||||
paintFrontWindow( frontWindow, width, leftWindowCount, rightWindowCount, reflectedWindows );
|
||||
}
|
||||
else
|
||||
|
@ -513,6 +520,7 @@ void CoverSwitchEffect::tabBoxAdded( int mode )
|
|||
effects->setActiveFullScreenEffect( this );
|
||||
scheduled_directions.clear();
|
||||
selected_window = effects->currentTabBoxWindow();
|
||||
currentWindowList = effects->currentTabBoxWindowList();
|
||||
direction = Left;
|
||||
mActivated = true;
|
||||
if( animateStart )
|
||||
|
@ -558,7 +566,7 @@ void CoverSwitchEffect::tabBoxAdded( int mode )
|
|||
startRequested = true;
|
||||
}
|
||||
if( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
{
|
||||
highlight_is_set = false;
|
||||
calculateFrameSize();
|
||||
|
@ -596,7 +604,7 @@ void CoverSwitchEffect::tabBoxClosed()
|
|||
effects->destroyInputWindow( input );
|
||||
effects->addRepaintFull();
|
||||
if( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
{
|
||||
qDeleteAll( windows );
|
||||
windows.clear();
|
||||
|
@ -608,14 +616,14 @@ void CoverSwitchEffect::tabBoxUpdated()
|
|||
{
|
||||
if( mActivated )
|
||||
{
|
||||
if( animateSwitch && effects->currentTabBoxWindowList().count() > 1)
|
||||
if( animateSwitch && currentWindowList.count() > 1)
|
||||
{
|
||||
// determine the switch direction
|
||||
if( selected_window != effects->currentTabBoxWindow() )
|
||||
{
|
||||
if( selected_window != NULL )
|
||||
{
|
||||
int old_index = effects->currentTabBoxWindowList().indexOf( selected_window );
|
||||
int old_index = currentWindowList.indexOf( selected_window );
|
||||
int new_index = effects->currentTabBoxWindowList().indexOf( effects->currentTabBoxWindow() );
|
||||
Direction new_direction;
|
||||
int distance = new_index - old_index;
|
||||
|
@ -658,12 +666,13 @@ void CoverSwitchEffect::tabBoxUpdated()
|
|||
}
|
||||
}
|
||||
selected_window = effects->currentTabBoxWindow();
|
||||
currentWindowList = effects->currentTabBoxWindowList();
|
||||
captionFrame.setText( selected_window->caption() );
|
||||
captionFrame.setIcon( selected_window->icon() );
|
||||
}
|
||||
}
|
||||
if( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
{
|
||||
calculateFrameSize();
|
||||
calculateItemSizes();
|
||||
|
@ -839,10 +848,10 @@ void CoverSwitchEffect::paintFrontWindow( EffectWindow* frontWindow, int width,
|
|||
paintWindowCover( frontWindow, reflectedWindow, data );
|
||||
}
|
||||
|
||||
void CoverSwitchEffect::paintWindows( QList< EffectWindow* >* windows, bool left, bool reflectedWindows, EffectWindow* additionalWindow )
|
||||
void CoverSwitchEffect::paintWindows( const EffectWindowList& windows, bool left, bool reflectedWindows, EffectWindow* additionalWindow )
|
||||
{
|
||||
int width = area.width();
|
||||
int windowCount = windows->count();
|
||||
int windowCount = windows.count();
|
||||
EffectWindow* window;
|
||||
|
||||
int rotateFactor = 1;
|
||||
|
@ -861,7 +870,7 @@ void CoverSwitchEffect::paintWindows( QList< EffectWindow* >* windows, bool left
|
|||
RotationData rot;
|
||||
rot.axis = RotationData::YAxis;
|
||||
rot.angle = angle;
|
||||
rot.angle = angle*rotateFactor;
|
||||
rot.angle = angle*rotateFactor;
|
||||
WindowPaintData data( additionalWindow );
|
||||
if( left )
|
||||
data.xTranslate += -xTranslate - additionalWindow->geometry().x();
|
||||
|
@ -878,11 +887,13 @@ void CoverSwitchEffect::paintWindows( QList< EffectWindow* >* windows, bool left
|
|||
RotationData rot;
|
||||
rot.axis = RotationData::YAxis;
|
||||
// normal behaviour
|
||||
for( int i=0; i < windowCount; i++ )
|
||||
for( int i=0; i < windows.count(); i++)
|
||||
{
|
||||
window = windows->at( i );
|
||||
if( window == NULL )
|
||||
window = windows.at( i );
|
||||
if( window == NULL || window->isDeleted() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WindowPaintData data( window );
|
||||
rot.angle = angle;
|
||||
if( left )
|
||||
|
@ -954,7 +965,7 @@ void CoverSwitchEffect::calculateFrameSize()
|
|||
int itemcount;
|
||||
|
||||
QRect screenr = effects->clientArea( PlacementArea, activeScreen, effects->currentDesktop());
|
||||
itemcount = effects->currentTabBoxWindowList().count();
|
||||
itemcount = currentWindowList.count();
|
||||
item_max_size.setWidth( (screenr.width()*0.95f * 2)/itemcount );
|
||||
if( item_max_size.width() > 250 )
|
||||
item_max_size.setWidth( 250 );
|
||||
|
@ -973,8 +984,8 @@ void CoverSwitchEffect::calculateItemSizes()
|
|||
{
|
||||
qDeleteAll( windows );
|
||||
windows.clear();
|
||||
EffectWindowList original_windows = effects->currentTabBoxWindowList();
|
||||
int index = original_windows.indexOf( effects->currentTabBoxWindow() );
|
||||
EffectWindowList original_windows = currentWindowList;
|
||||
int index = original_windows.indexOf( selected_window );
|
||||
int leftIndex = index;
|
||||
int rightIndex = index + 1;
|
||||
if( rightIndex == original_windows.count() )
|
||||
|
@ -1072,7 +1083,7 @@ void CoverSwitchEffect::calculateItemSizes()
|
|||
}
|
||||
if( !highlight_is_set )
|
||||
{
|
||||
highlight_area = windows[ effects->currentTabBoxWindow() ]->area;
|
||||
highlight_area = windows[ selected_window ]->area;
|
||||
highlight_is_set = true;
|
||||
}
|
||||
}
|
||||
|
@ -1346,7 +1357,7 @@ void CoverSwitchEffect::windowInputMouseEvent( Window w, QEvent* e )
|
|||
|
||||
// has one of the thumbnails been clicked?
|
||||
if( (thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows))))
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows))))
|
||||
{
|
||||
// determine which item was clicked
|
||||
foreach( EffectWindow* w, windows.keys())
|
||||
|
@ -1424,7 +1435,7 @@ void CoverSwitchEffect::abort()
|
|||
stopRequested = false;
|
||||
effects->addRepaintFull();
|
||||
if( thumbnails && (!dynamicThumbnails ||
|
||||
(dynamicThumbnails && effects->currentTabBoxWindowList().size() >= thumbnailWindows)) )
|
||||
(dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)) )
|
||||
{
|
||||
qDeleteAll( windows );
|
||||
windows.clear();
|
||||
|
@ -1433,6 +1444,20 @@ void CoverSwitchEffect::abort()
|
|||
thumbnailFrame.free();
|
||||
}
|
||||
|
||||
void CoverSwitchEffect::windowClosed( EffectWindow* c )
|
||||
{
|
||||
// if the list is not empty, the effect is active
|
||||
if( !currentWindowList.isEmpty() )
|
||||
{
|
||||
c->refWindow();
|
||||
referrencedWindows.append( c );
|
||||
currentWindowList.removeAll( c );
|
||||
leftWindows.removeAll( c );
|
||||
rightWindows.removeAll( c );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CoverSwitchEffect::ItemInfo::ItemInfo()
|
||||
: iconFrame( NULL )
|
||||
{
|
||||
|
|
|
@ -50,14 +50,15 @@ class CoverSwitchEffect
|
|||
virtual void tabBoxClosed();
|
||||
virtual void tabBoxUpdated();
|
||||
virtual void windowInputMouseEvent( Window w, QEvent* e );
|
||||
virtual void windowClosed( EffectWindow* c );
|
||||
|
||||
static bool supported();
|
||||
private:
|
||||
void paintScene( EffectWindow* frontWindow, QList< EffectWindow* >* leftWindows, QList< EffectWindow* >* rightWindows,
|
||||
void paintScene( EffectWindow* frontWindow, const EffectWindowList& leftWindows, const EffectWindowList& rightWindows,
|
||||
bool reflectedWindows = false );
|
||||
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 );
|
||||
void paintWindows( const EffectWindowList& windows, bool left, bool reflectedWindows, EffectWindow* additionalWindow = NULL );
|
||||
void abort();
|
||||
// thumbnail bar
|
||||
class ItemInfo;
|
||||
|
@ -97,6 +98,8 @@ class CoverSwitchEffect
|
|||
int activeScreen;
|
||||
QList< EffectWindow* > leftWindows;
|
||||
QList< EffectWindow* > rightWindows;
|
||||
EffectWindowList currentWindowList;
|
||||
EffectWindowList referrencedWindows;
|
||||
|
||||
EffectFrame captionFrame;
|
||||
QFont captionFont;
|
||||
|
|
Loading…
Reference in a new issue