Fixing incorrect clipping of sliding popups
Make use of new extension of protocol for magic number -1. If offset is -1 KWin has to decide the offset. This fixes all the incorrect animations and allows us to perform clipping again by filtering out the window quads which should not be visible. Additionally the effect now sanitizes the offset. That is for e.g. Yakuake setting an offset of 0, but there is a strut on the top corner causing Yakuake not to appear on 0, but with an offset of the strut. Such cases are now considered as well and the animation is fixed. REVIEW: 103367 BUG: 287602 CCBUG: 261159 CCBUG: 278760 FIXED-IN: 4.8.0
This commit is contained in:
parent
fbae9f9972
commit
de8b9f546f
1 changed files with 115 additions and 37 deletions
|
@ -82,17 +82,86 @@ void SlidingPopupsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
|||
|
||||
void SlidingPopupsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
||||
{
|
||||
qreal progress = 1.0;
|
||||
bool appearing = false;
|
||||
if (mAppearingWindows.contains(w)) {
|
||||
mAppearingWindows[ w ]->setCurrentTime(mAppearingWindows[ w ]->currentTime() + time);
|
||||
if (mAppearingWindows[ w ]->currentValue() < 1)
|
||||
if (mAppearingWindows[ w ]->currentValue() < 1) {
|
||||
data.setTransformed();
|
||||
else
|
||||
progress = mAppearingWindows[ w ]->currentValue();
|
||||
appearing = true;
|
||||
} else
|
||||
delete mAppearingWindows.take(w);
|
||||
} else if (mDisappearingWindows.contains(w)) {
|
||||
data.setTransformed();
|
||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||
|
||||
mDisappearingWindows[ w ]->setCurrentTime(mDisappearingWindows[ w ]->currentTime() + time);
|
||||
progress = mDisappearingWindows[ w ]->currentValue();
|
||||
|
||||
if (progress != 1.0) {
|
||||
data.setTransformed();
|
||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||
} else {
|
||||
delete mDisappearingWindows.take(w);
|
||||
w->unrefWindow();
|
||||
}
|
||||
}
|
||||
if (progress != 1.0) {
|
||||
const int start = mWindowsData[ w ].start;
|
||||
if (start != 0) {
|
||||
const QRect screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
||||
// filter out window quads, but only if the window does not start from the edge
|
||||
switch(mWindowsData[ w ].from) {
|
||||
case West: {
|
||||
const double splitPoint = w->width() - (w->x() + w->width() - screenRect.x() - start) + w->width() * (appearing ? 1.0 - progress : progress);
|
||||
data.quads = data.quads.splitAtX(splitPoint);
|
||||
WindowQuadList filtered;
|
||||
foreach (const WindowQuad &quad, data.quads) {
|
||||
if (quad.left() >= splitPoint) {
|
||||
filtered << quad;
|
||||
}
|
||||
}
|
||||
data.quads = filtered;
|
||||
break;
|
||||
}
|
||||
case North: {
|
||||
const double splitPoint = w->height() - (w->y() + w->height() - screenRect.y() - start) + w->height() * (appearing ? 1.0 - progress : progress);
|
||||
data.quads = data.quads.splitAtY(splitPoint);
|
||||
WindowQuadList filtered;
|
||||
foreach (const WindowQuad &quad, data.quads) {
|
||||
if (quad.top() >= splitPoint) {
|
||||
filtered << quad;
|
||||
}
|
||||
}
|
||||
data.quads = filtered;
|
||||
break;
|
||||
}
|
||||
case East: {
|
||||
const double splitPoint = screenRect.x() + screenRect.width() - w->x() - start - w->width() * (appearing ? 1.0 - progress : progress);
|
||||
data.quads = data.quads.splitAtX(splitPoint);
|
||||
WindowQuadList filtered;
|
||||
foreach (const WindowQuad &quad, data.quads) {
|
||||
if (quad.right() <= splitPoint) {
|
||||
filtered << quad;
|
||||
}
|
||||
}
|
||||
data.quads = filtered;
|
||||
break;
|
||||
}
|
||||
case South:
|
||||
default: {
|
||||
const double splitPoint = screenRect.y() + screenRect.height() - w->y() - start - w->height() * (appearing ? 1.0 - progress : progress);
|
||||
data.quads = data.quads.splitAtY(splitPoint);
|
||||
WindowQuadList filtered;
|
||||
foreach (const WindowQuad &quad, data.quads) {
|
||||
if (quad.bottom() <= splitPoint) {
|
||||
filtered << quad;
|
||||
}
|
||||
}
|
||||
data.quads = filtered;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow(w, data, time);
|
||||
}
|
||||
|
@ -101,7 +170,6 @@ void SlidingPopupsEffect::paintWindow(EffectWindow* w, int mask, QRegion region,
|
|||
{
|
||||
bool animating = false;
|
||||
bool appearing = false;
|
||||
QRegion clippedRegion = region;
|
||||
|
||||
if (mAppearingWindows.contains(w)) {
|
||||
appearing = true;
|
||||
|
@ -122,59 +190,33 @@ void SlidingPopupsEffect::paintWindow(EffectWindow* w, int mask, QRegion region,
|
|||
progress = 1.0;
|
||||
}
|
||||
const int start = mWindowsData[ w ].start;
|
||||
QRect r;
|
||||
|
||||
const QRect screenRect = effects->clientArea(FullScreenArea, w->screen(), w->desktop());
|
||||
switch(mWindowsData[ w ].from) {
|
||||
case West:
|
||||
data.xTranslate += (start - w->width()) * progress;
|
||||
r = QRect(start - w->width(), w->y(), w->width(), w->height());
|
||||
data.xTranslate -= w->width() * progress;
|
||||
break;
|
||||
case North:
|
||||
data.yTranslate += (start - w->height()) * progress;
|
||||
r = QRect(w->x(), start - w->height(), w->width(), w->height());
|
||||
data.yTranslate -= w->height() * progress;
|
||||
break;
|
||||
case East:
|
||||
data.xTranslate += (start - w->x()) * progress;
|
||||
r = QRect(w->x() + w->width(), w->y(), w->width(), w->height());
|
||||
data.xTranslate += w->width() * progress;
|
||||
break;
|
||||
case South:
|
||||
default:
|
||||
data.yTranslate += (start - w->y()) * progress;
|
||||
r = QRect(w->x(), start, w->width(), w->height());
|
||||
data.yTranslate += w->height() * progress;
|
||||
}
|
||||
clippedRegion = clippedRegion.subtracted(r);
|
||||
effects->addRepaint(r);
|
||||
}
|
||||
|
||||
effects->paintWindow(w, mask, clippedRegion, data);
|
||||
effects->paintWindow(w, mask, region, data);
|
||||
}
|
||||
|
||||
void SlidingPopupsEffect::postPaintWindow(EffectWindow* w)
|
||||
{
|
||||
if (mAppearingWindows.contains(w) || mDisappearingWindows.contains(w)) {
|
||||
w->addRepaintFull(); // trigger next animation repaint
|
||||
const int start = mWindowsData[ w ].start;
|
||||
switch(mWindowsData[ w ].from) {
|
||||
case West:
|
||||
effects->addRepaint(QRect(start, w->y(), w->x(), w->height()));
|
||||
break;
|
||||
case North:
|
||||
effects->addRepaint(QRect(w->x(), start, w->width(), w->y()));
|
||||
break;
|
||||
case East:
|
||||
effects->addRepaint(QRect(w->x() + w->width(), w->y(), displayWidth() - w->x() - w->width() - start, w->height()));
|
||||
break;
|
||||
case South:
|
||||
default:
|
||||
effects->addRepaint(QRect(w->x(), w->y()+w->height(), w->width(), displayHeight() - w->y() - w->height() - start));
|
||||
}
|
||||
}
|
||||
effects->postPaintWindow(w);
|
||||
if (mDisappearingWindows.contains(w) && mDisappearingWindows[ w ]->currentValue() >= 1) {
|
||||
delete mDisappearingWindows.take(w);
|
||||
w->unrefWindow();
|
||||
effects->addRepaint(w->geometry());
|
||||
}
|
||||
}
|
||||
|
||||
void SlidingPopupsEffect::slotWindowAdded(EffectWindow *w)
|
||||
|
@ -244,6 +286,42 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow* w, long a)
|
|||
animData.fadeInDuration = animationTime(mFadeInTime);
|
||||
animData.fadeOutDuration = animationTime(mFadeOutTime);
|
||||
}
|
||||
const QRect screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
||||
if (animData.start == -1) {
|
||||
switch (animData.from) {
|
||||
case West:
|
||||
animData.start = qMax(w->x() - screenRect.x(), 0);
|
||||
break;
|
||||
case North:
|
||||
animData.start = qMax(w->y() - screenRect.y(), 0);
|
||||
break;
|
||||
case East:
|
||||
animData.start = qMax(screenRect.x() + screenRect.width() - (w->x() + w->width()), 0);
|
||||
break;
|
||||
case South:
|
||||
default:
|
||||
animData.start = qMax(screenRect.y() + screenRect.height() - (w->y() + w->height()), 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// sanitize
|
||||
int difference = 0;
|
||||
switch (animData.from) {
|
||||
case West:
|
||||
difference = w->x() - screenRect.x();
|
||||
break;
|
||||
case North:
|
||||
difference = w->y() - screenRect.y();
|
||||
break;
|
||||
case East:
|
||||
difference = w->x() + w->width() - (screenRect.x() + screenRect.width());
|
||||
break;
|
||||
case South:
|
||||
default:
|
||||
difference = w->y() + w->height() - (screenRect.y() + screenRect.height());
|
||||
break;
|
||||
}
|
||||
animData.start = qMax<int>(animData.start, difference);
|
||||
mWindowsData[ w ] = animData;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue