From 3c449d81cc8d11f25ebbb1d542849319563da600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 8 Mar 2009 15:12:55 +0000 Subject: [PATCH] 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 --- effects/magiclamp/magiclamp.cpp | 77 +++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/effects/magiclamp/magiclamp.cpp b/effects/magiclamp/magiclamp.cpp index 04e3ac0b2e..f53a1eb720 100644 --- a/effects/magiclamp/magiclamp.cpp +++ b/effects/magiclamp/magiclamp.cpp @@ -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;