New way to determine in which direction to animate the magic lamp. Based on the assumption that icon geometry is part of a panel. Using the panel to find the position is more safe as a the height of a vertical panel is greater than the width. This might not be true for the icon geometry. If the panel is autohidden we still have to use the icon geometry using the assumption that it will border one screen edge. For the unlikely case of bordering two screen edges the wrong animation might be used but it won't be distorted.

There's still the possiblity of distortion if someone places the panel between two screens. But that's hardly possible to catch as it would require to animate parts of the window in one direction and the rest in another direction.
BUG: 183059
BUG: 183099

svn path=/trunk/KDE/kdebase/workspace/; revision=936880
This commit is contained in:
Martin Gräßlin 2009-03-08 15:12:55 +00:00
parent 9d33d771dc
commit 3c449d81cc

View file

@ -92,31 +92,74 @@ void MagicLampEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi
QRect geo = w->geometry();
QRect icon = w->iconGeometry();
QRect area = effects->clientArea( ScreenArea, w );
// If there's no icon geometry, minimize to the center of the screen
if( !icon.isValid() )
icon = QRect( displayWidth() / 2, displayHeight(), 0, 0 );
icon = QRect( area.x() + area.width() / 2, area.y() + area.height(), 0, 0 );
QRect area = effects->clientArea( PlacementArea, w );
IconPosition position = Bottom;
// top
if( icon.y() + icon.height() <= area.y() )
IconPosition position;
// Assumption: there is a panel containing the icon position
EffectWindow* panel = NULL;
foreach( EffectWindow* window, effects->stackingOrder() )
{
position = Top;
if( !window->isDock() )
continue;
// we have to use intersects as there seems to be a Plasma bug
// the published icon geometry might be bigger than the panel
if( window->geometry().intersects( icon ) )
{
panel = window;
break;
}
}
// bottom
if( icon.y() >= area.y()+area.height() )
if( panel )
{
position = Bottom;
// Assumption: width of horizonal panel is greater than its height and vice versa
// The panel has to border one screen edge, so get it's screen area
QRect panelScreen = effects->clientArea( ScreenArea, panel );
if( panel->width() >= panel->height() )
{
// horizontal panel
if( panel->y() == panelScreen.y() )
position = Top;
else
position = Bottom;
}
else
{
// vertical panel
if( panel->x() == panelScreen.x() )
position = Left;
else
position = Right;
}
}
// left
if( icon.x() + icon.width() <= area.x() )
else
{
position = Left;
}
// right
if( icon.x() >= area.x()+ area.width() )
{
position = Right;
// we did not find a panel, so it might be autohidden
QRect iconScreen = effects->clientArea( ScreenArea, icon.topLeft(), effects->currentDesktop() );
// as the icon geometry could be overlap a screen edge we use an intersection
QRect rect = iconScreen.intersected( icon );
// here we need a different assumption: icon geometry borders one screen edge
// this assumption might be wrong for e.g. task applet being the only applet in panel
// in this case the icon borders two screen edges
// there might be a wrong animation, but not distorted
if( rect.x() == iconScreen.x() )
{
position = Left;
}
else if( rect.x() + rect.width() == iconScreen.x() + iconScreen.width() )
{
position = Right;
}
else if( rect.y() == iconScreen.y() )
{
position = Top;
}
else
{
position = Bottom;
}
}
WindowQuadList newQuads;