Force-enable blur for Plasma's windows during desktop slide

Without setting the property, Plasma's panel and dialogs lose the
backgroundcontrast effect during slides, which makes them flicker.

As the panel is shown on screen all the time, this is quite a visible
bug. To fix this, when the slide effect is started, we check for window
types and properties of each window, and force the blur flag on if it's
unset.

If the background contrast flag is set to false, we leave the window
alone assuming that there's a reason to force it off. Windows that
are newly added during the slide get the same treatment, so something
popping up while sliding (such as the desktop switch OSD) also gets
the background effect applied.When the effect stops or is interupted, we
unset what we've set, and clean up our internal bookkeeping.

Thanks Martin and Thomas for the thorough review!

REVIEW:115857
icc-effect-5.14.5
Sebastian Kügler 2014-02-19 14:02:09 +01:00
parent a8ec2b8bf3
commit 57a0667e9d
2 changed files with 38 additions and 2 deletions

View File

@ -30,6 +30,10 @@ SlideEffect::SlideEffect()
: slide(false)
{
connect(effects, SIGNAL(desktopChanged(int,int)), this, SLOT(slotDesktopChanged(int,int)));
connect(effects, &EffectsHandler::windowAdded, this, &SlideEffect::windowAdded);
connect(effects, &EffectsHandler::windowDeleted, [this](EffectWindow *w) {
m_backgroundContrastForcedBefore.removeAll(w);
});
mTimeLine.setCurveShape(QTimeLine::EaseInOutCurve);
reconfigure(ReconfigureAll);
}
@ -49,11 +53,15 @@ void SlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
if (mTimeLine.currentValue() != 1)
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
else {
slide = false;
mTimeLine.setCurrentTime(0);
foreach (EffectWindow * w, effects->stackingOrder()) {
w->setData(WindowForceBlurRole, QVariant(false));
if (m_backgroundContrastForcedBefore.contains(w)) {
w->setData(WindowForceBackgroundContrastRole, QVariant());
}
}
m_backgroundContrastForcedBefore.clear();
slide = false;
mTimeLine.setCurrentTime(0);
effects->setActiveFullScreenEffect(NULL);
}
}
@ -231,6 +239,10 @@ void SlideEffect::slotDesktopChanged(int old, int current)
slide_start_pos = rect.topLeft() - diffPos * 1 / (1 - mTimeLine.currentValue());
} else {
// at the end, stop
foreach (EffectWindow * w, m_backgroundContrastForcedBefore) {
w->setData(WindowForceBackgroundContrastRole, QVariant());
}
m_backgroundContrastForcedBefore.clear();
slide = false;
mTimeLine.setCurrentTime(0);
effects->setActiveFullScreenEffect(NULL);
@ -243,12 +255,33 @@ void SlideEffect::slotDesktopChanged(int old, int current)
slide = true;
foreach (EffectWindow * w, effects->stackingOrder()) {
w->setData(WindowForceBlurRole, QVariant(true));
if (shouldForceBackgroundContrast(w)) {
m_backgroundContrastForcedBefore.append(w);
w->setData(WindowForceBackgroundContrastRole, QVariant(true));
}
}
effects->setActiveFullScreenEffect(this);
}
effects->addRepaintFull();
}
void SlideEffect::windowAdded(EffectWindow *w)
{
if (slide && shouldForceBackgroundContrast(w)) {
m_backgroundContrastForcedBefore.append(w);
w->setData(WindowForceBackgroundContrastRole, QVariant(true));
}
}
bool SlideEffect::shouldForceBackgroundContrast(const EffectWindow *w) const
{
// Windows that are docks, kept above (such as panel popups), and do not
// have the background contrast explicitely disabled should be forced on
// during the slide animation
const bool bgWindow = (w->hasAlpha() && w->isOnAllDesktops() && (w->isDock() || w->keepAbove()));
return bgWindow && (!w->data(WindowForceBackgroundContrastRole).isValid());
}
bool SlideEffect::isActive() const
{
return slide;

View File

@ -47,6 +47,9 @@ private Q_SLOTS:
void slotDesktopChanged(int old, int current);
private:
void windowAdded(EffectWindow* w);
bool shouldForceBackgroundContrast(const EffectWindow* w) const;
QList< EffectWindow* > m_backgroundContrastForcedBefore;
QRect desktopRect(int desktop) const;
QTimeLine mTimeLine;
int painting_desktop;