From 69151896615ec272d78860b2ef42e61657f435f1 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Thu, 22 Jun 2023 11:35:27 +0200 Subject: [PATCH] plugins/backgroundcontrast,blur: ensure the effect is only applied behind the window When a window is translated and/or scaled, the effect must be strictly behind the window and never beyond it, as that is very noticeable. BUG: 469625 (cherry picked from commit cd94cdaf3a04227073c3f99833139a712d195d3a) --- src/effects/backgroundcontrast/contrast.cpp | 22 +++++++++++++-------- src/effects/blur/blur.cpp | 19 ++++++++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/effects/backgroundcontrast/contrast.cpp b/src/effects/backgroundcontrast/contrast.cpp index 8921a481e3f..66dffd99a94 100644 --- a/src/effects/backgroundcontrast/contrast.cpp +++ b/src/effects/backgroundcontrast/contrast.cpp @@ -382,25 +382,31 @@ void ContrastEffect::drawWindow(EffectWindow *w, int mask, const QRegion ®ion const QRect screen = effects->renderTargetRect(); QRegion shape = region & contrastRegion(w).translated(w->pos().toPoint()) & screen; - // let's do the evil parts - someone wants to blur behind a transformed window + // let's do the evil parts - someone wants to contrast behind a transformed window const bool translated = data.xTranslation() || data.yTranslation(); const bool scaled = data.xScale() != 1 || data.yScale() != 1; if (scaled) { QPoint pt = shape.boundingRect().topLeft(); QRegion scaledShape; for (QRect r : shape) { - r.moveTo(pt.x() + (r.x() - pt.x()) * data.xScale() + data.xTranslation(), - pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation()); - r.setWidth(std::ceil(r.width() * data.xScale())); - r.setHeight(std::ceil(r.height() * data.yScale())); - scaledShape |= r; + const QPointF topLeft(pt.x() + (r.x() - pt.x()) * data.xScale() + data.xTranslation(), + pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation()); + const QPoint bottomRight(std::floor(topLeft.x() + r.width() * data.xScale()) - 1, + std::floor(topLeft.y() + r.height() * data.yScale()) - 1); + scaledShape |= QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight); } shape = scaledShape & region; // Only translated, not scaled } else if (translated) { - shape = shape.translated(data.xTranslation(), data.yTranslation()); - shape = shape & region; + QRegion translated; + for (QRect r : shape) { + const QRectF t = QRectF(r).translated(data.xTranslation(), data.yTranslation()); + const QPoint topLeft(std::ceil(t.x()), std::ceil(t.y())); + const QPoint bottomRight(std::floor(t.x() + t.width() - 1), std::floor(t.y() + t.height() - 1)); + translated |= QRect(topLeft, bottomRight); + } + shape = translated & region; } if (!shape.isEmpty()) { diff --git a/src/effects/blur/blur.cpp b/src/effects/blur/blur.cpp index ec08e6cc968..1b6d9997c98 100644 --- a/src/effects/blur/blur.cpp +++ b/src/effects/blur/blur.cpp @@ -625,17 +625,24 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, const QRegion ®ion, Wi QPoint pt = shape.boundingRect().topLeft(); QRegion scaledShape; for (QRect r : shape) { - r.moveTo(pt.x() + (r.x() - pt.x()) * data.xScale() + data.xTranslation(), - pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation()); - r.setWidth(std::ceil(r.width() * data.xScale())); - r.setHeight(std::ceil(r.height() * data.yScale())); - scaledShape |= r; + const QPointF topLeft(pt.x() + (r.x() - pt.x()) * data.xScale() + data.xTranslation(), + pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation()); + const QPoint bottomRight(std::floor(topLeft.x() + r.width() * data.xScale()) - 1, + std::floor(topLeft.y() + r.height() * data.yScale()) - 1); + scaledShape |= QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight); } shape = scaledShape; // Only translated, not scaled } else if (translated) { - shape = shape.translated(data.xTranslation(), data.yTranslation()); + QRegion translated; + for (QRect r : shape) { + const QRectF t = QRectF(r).translated(data.xTranslation(), data.yTranslation()); + const QPoint topLeft(std::ceil(t.x()), std::ceil(t.y())); + const QPoint bottomRight(std::floor(t.x() + t.width() - 1), std::floor(t.y() + t.height() - 1)); + translated |= QRect(topLeft, bottomRight); + } + shape = translated; } EffectWindow *modal = w->transientFor(); -- GitLab