effects/slide: Make the slide effect not depend on nested prePaintWindow()
This is needed to allow the Compositor get the surface damage before calling Scene::paint().
This commit is contained in:
parent
b6ec6f8216
commit
0db64527f0
2 changed files with 58 additions and 57 deletions
|
@ -62,6 +62,25 @@ void SlideEffect::reconfigure(ReconfigureFlags)
|
|||
m_slideBackground = SlideConfig::slideBackground();
|
||||
}
|
||||
|
||||
inline QRegion buildClipRegion(const QPoint &pos, int w, int h)
|
||||
{
|
||||
const QSize screenSize = effects->virtualScreenSize();
|
||||
QRegion r = QRect(pos, screenSize);
|
||||
if (effects->optionRollOverDesktops()) {
|
||||
r |= (r & QRect(-w, 0, w, h)).translated(w, 0); // W
|
||||
r |= (r & QRect(w, 0, w, h)).translated(-w, 0); // E
|
||||
|
||||
r |= (r & QRect(0, -h, w, h)).translated(0, h); // N
|
||||
r |= (r & QRect(0, h, w, h)).translated(0, -h); // S
|
||||
|
||||
r |= (r & QRect(-w, -h, w, h)).translated(w, h); // NW
|
||||
r |= (r & QRect(w, -h, w, h)).translated(-w, h); // NE
|
||||
r |= (r & QRect(w, h, w, h)).translated(-w, -h); // SE
|
||||
r |= (r & QRect(-w, h, w, h)).translated(w, -h); // SW
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void SlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||
{
|
||||
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||
|
@ -69,11 +88,31 @@ void SlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::millisec
|
|||
delta = presentTime - m_lastPresentTime;
|
||||
}
|
||||
m_lastPresentTime = presentTime;
|
||||
|
||||
m_timeLine.update(delta);
|
||||
|
||||
data.mask |= PAINT_SCREEN_TRANSFORMED
|
||||
| PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
const int w = workspaceWidth();
|
||||
const int h = workspaceHeight();
|
||||
|
||||
// When "Desktop navigation wraps around" checkbox is checked, currentPos
|
||||
// can be outside the rectangle Rect{x:-w, y:-h, width:2*w, height: 2*h},
|
||||
// so we map currentPos back to the rect.
|
||||
m_paintCtx.currentPos = m_startPos + m_diff * m_timeLine.value();
|
||||
if (effects->optionRollOverDesktops()) {
|
||||
m_paintCtx.currentPos.setX(m_paintCtx.currentPos.x() % w);
|
||||
m_paintCtx.currentPos.setY(m_paintCtx.currentPos.y() % h);
|
||||
}
|
||||
|
||||
m_paintCtx.visibleDesktops.clear();
|
||||
const QRegion clipRegion = buildClipRegion(m_paintCtx.currentPos, w, h);
|
||||
for (int i = 1; i <= effects->numberOfDesktops(); i++) {
|
||||
const QRect desktopGeo = desktopGeometry(i);
|
||||
if (!clipRegion.contains(desktopGeo)) {
|
||||
continue;
|
||||
}
|
||||
m_paintCtx.visibleDesktops << i;
|
||||
}
|
||||
|
||||
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
|
||||
effects->prePaintScreen(data, presentTime);
|
||||
}
|
||||
|
@ -104,52 +143,12 @@ inline void wrapDiff(QPoint &diff, int w, int h)
|
|||
}
|
||||
}
|
||||
|
||||
inline QRegion buildClipRegion(const QPoint &pos, int w, int h)
|
||||
{
|
||||
const QSize screenSize = effects->virtualScreenSize();
|
||||
QRegion r = QRect(pos, screenSize);
|
||||
if (effects->optionRollOverDesktops()) {
|
||||
r |= (r & QRect(-w, 0, w, h)).translated(w, 0); // W
|
||||
r |= (r & QRect(w, 0, w, h)).translated(-w, 0); // E
|
||||
|
||||
r |= (r & QRect(0, -h, w, h)).translated(0, h); // N
|
||||
r |= (r & QRect(0, h, w, h)).translated(0, -h); // S
|
||||
|
||||
r |= (r & QRect(-w, -h, w, h)).translated(w, h); // NW
|
||||
r |= (r & QRect(w, -h, w, h)).translated(-w, h); // NE
|
||||
r |= (r & QRect(w, h, w, h)).translated(-w, -h); // SE
|
||||
r |= (r & QRect(-w, h, w, h)).translated(w, -h); // SW
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void SlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||
{
|
||||
const bool wrap = effects->optionRollOverDesktops();
|
||||
const int w = workspaceWidth();
|
||||
const int h = workspaceHeight();
|
||||
|
||||
QPoint currentPos = m_startPos + m_diff * m_timeLine.value();
|
||||
|
||||
// When "Desktop navigation wraps around" checkbox is checked, currentPos
|
||||
// can be outside the rectangle Rect{x:-w, y:-h, width:2*w, height: 2*h},
|
||||
// so we map currentPos back to the rect.
|
||||
if (wrap) {
|
||||
currentPos.setX(currentPos.x() % w);
|
||||
currentPos.setY(currentPos.y() % h);
|
||||
}
|
||||
|
||||
QVector<int> visibleDesktops;
|
||||
visibleDesktops.reserve(4); // 4 - maximum number of visible desktops
|
||||
const QRegion clipRegion = buildClipRegion(currentPos, w, h);
|
||||
for (int i = 1; i <= effects->numberOfDesktops(); i++) {
|
||||
const QRect desktopGeo = desktopGeometry(i);
|
||||
if (!clipRegion.contains(desktopGeo)) {
|
||||
continue;
|
||||
}
|
||||
visibleDesktops << i;
|
||||
}
|
||||
|
||||
// When we enter a virtual desktop that has a window in fullscreen mode,
|
||||
// stacking order is fine. When we leave a virtual desktop that has
|
||||
// a window in fullscreen mode, stacking order is no longer valid
|
||||
|
@ -173,11 +172,11 @@ void SlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &
|
|||
// Windows, such as docks or keep-above windows, are painted in
|
||||
// the last pass so they are above other windows.
|
||||
m_paintCtx.firstPass = true;
|
||||
const int lastDesktop = visibleDesktops.last();
|
||||
for (int desktop : qAsConst(visibleDesktops)) {
|
||||
const int lastDesktop = m_paintCtx.visibleDesktops.last();
|
||||
for (int desktop : qAsConst(m_paintCtx.visibleDesktops)) {
|
||||
m_paintCtx.desktop = desktop;
|
||||
m_paintCtx.lastPass = (lastDesktop == desktop);
|
||||
m_paintCtx.translation = desktopCoords(desktop) - currentPos;
|
||||
m_paintCtx.translation = desktopCoords(desktop) - m_paintCtx.currentPos;
|
||||
if (wrap) {
|
||||
wrapDiff(m_paintCtx.translation, w, h);
|
||||
}
|
||||
|
@ -202,10 +201,8 @@ bool SlideEffect::isTranslated(const EffectWindow *w) const
|
|||
return false;
|
||||
} else if (w == m_movingWindow) {
|
||||
return false;
|
||||
} else if (w->isOnDesktop(m_paintCtx.desktop)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,20 +248,22 @@ bool SlideEffect::isPainted(const EffectWindow *w) const
|
|||
|
||||
void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||
{
|
||||
const bool painted = isPainted(w);
|
||||
if (painted) {
|
||||
for (const auto &desktop : std::as_const(m_paintCtx.visibleDesktops)) {
|
||||
if (w->isOnDesktop(desktop)) {
|
||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||
} else {
|
||||
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||
}
|
||||
if (painted && isTranslated(w)) {
|
||||
data.setTransformed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
effects->prePaintWindow(w, data, presentTime);
|
||||
}
|
||||
|
||||
void SlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||
{
|
||||
if (!isPainted(w)) {
|
||||
return;
|
||||
}
|
||||
if (isTranslated(w)) {
|
||||
data += m_paintCtx.translation;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
bool lastPass;
|
||||
QPoint translation;
|
||||
|
||||
QPoint currentPos;
|
||||
QVector<int> visibleDesktops;
|
||||
EffectWindowList fullscreenWindows;
|
||||
} m_paintCtx;
|
||||
|
||||
|
|
Loading…
Reference in a new issue