Commit bc145b61 authored by Michail Vourlakos's avatar Michail Vourlakos
Browse files

support kdecoration2 blurregion

--use kdecoration2 blurred regions to adjust blur effect appropriately when
needed

CCBUG:395725

Requires: kdecoration!17
parent c0d0fab0
Pipeline #135519 passed with stage
in 15 minutes and 24 seconds
......@@ -189,6 +189,9 @@ public:
bool decorationHasAlpha() const override {
return false;
}
KDecoration2::Decoration *decoration() const override {
return nullptr;
}
QString caption() const override {
return QString();
}
......
......@@ -52,6 +52,7 @@
#include "wayland_server.h"
#include "decorations/decorationbridge.h"
#include <KDecoration2/Decoration>
#include <KDecoration2/DecorationSettings>
namespace KWin
......@@ -355,6 +356,10 @@ void EffectsHandlerImpl::setupClientConnections(AbstractClient* c)
connect(c, &AbstractClient::visibleGeometryChanged, this, [this, c]() {
Q_EMIT windowExpandedGeometryChanged(c->effectWindow());
});
connect(c, &AbstractClient::decorationChanged, this, [this, c]() {
Q_EMIT windowDecorationChanged(c->effectWindow());
});
}
void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
......@@ -2078,6 +2083,16 @@ QRect EffectWindowImpl::decorationInnerRect() const
return toplevel->rect() - toplevel->frameMargins();
}
KDecoration2::Decoration *EffectWindowImpl::decoration() const
{
auto client = qobject_cast<AbstractClient *>(toplevel);
if (!client) {
return nullptr;
}
return client->decoration();
}
QByteArray EffectWindowImpl::readProperty(long atom, long type, int format) const
{
if (!kwinApp()->x11Connection()) {
......
......@@ -490,6 +490,7 @@ public:
qlonglong windowId() const override;
QRect decorationInnerRect() const override;
KDecoration2::Decoration *decoration() const override;
QByteArray readProperty(long atom, long type, int format) const override;
void deleteProperty(long atom) const override;
......
......@@ -55,6 +55,7 @@ set(kwin_effect_KDE_LIBS
KF5::Plasma # screenedge effect
KF5::WindowSystem
KF5::Service # utils / screenshot effect
KDecoration2::KDecoration # blur effect
Plasma::KWaylandServer
)
......
......@@ -25,6 +25,8 @@
#include <KSharedConfig>
#include <KConfigGroup>
#include <KDecoration2/Decoration>
namespace KWin
{
......@@ -65,6 +67,7 @@ BlurEffect::BlurEffect()
connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &BlurEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::windowDecorationChanged, this, &BlurEffect::setupDecorationConnections);
connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::virtualScreenGeometryChanged, this, &BlurEffect::slotScreenGeometryChanged);
connect(effects, &EffectsHandler::xcbConnectionChanged, this,
......@@ -334,6 +337,7 @@ void BlurEffect::slotWindowAdded(EffectWindow *w)
internal->installEventFilter(this);
}
setupDecorationConnections(w);
updateBlurRegion(w);
}
......@@ -354,6 +358,17 @@ void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom)
}
}
void BlurEffect::setupDecorationConnections(EffectWindow *w)
{
if (!w->decoration()) {
return;
}
connect(w->decoration(), &KDecoration2::Decoration::blurRegionChanged, this, [this, w] () {
updateBlurRegion(w);
});
}
bool BlurEffect::eventFilter(QObject *watched, QEvent *event)
{
auto internal = qobject_cast<QWindow*>(watched);
......@@ -399,6 +414,23 @@ bool BlurEffect::supported()
return supported;
}
QRegion BlurEffect::decorationBlurRegion(const EffectWindow *w) const
{
if (!w || !effects->decorationSupportsBlurBehind() || !w->decoration()) {
return QRegion();
}
QRegion decorationRegion = QRegion(w->decoration()->rect()) - w->decorationInnerRect();
if (!w->decoration()->blurRegion().isNull()) {
//! we return only blurred regions that belong to decoration region
return decorationRegion.intersected(w->decoration()->blurRegion());
}
//! when decoration requests blur but does not provide any blur region we can assume it prefers entire decoration region
return decorationRegion;
}
QRect BlurEffect::expand(const QRect &rect) const
{
return rect.adjusted(-m_expandSize, -m_expandSize, m_expandSize, m_expandSize);
......@@ -424,7 +456,7 @@ QRegion BlurEffect::blurRegion(const EffectWindow *w) const
const QRegion appRegion = qvariant_cast<QRegion>(value);
if (!appRegion.isEmpty()) {
if (w->decorationHasAlpha() && effects->decorationSupportsBlurBehind()) {
region = QRegion(w->rect()) - w->decorationInnerRect();
region = decorationBlurRegion(w);
}
region |= appRegion.translated(w->contentsRect().topLeft()) &
w->decorationInnerRect();
......@@ -436,7 +468,7 @@ QRegion BlurEffect::blurRegion(const EffectWindow *w) const
} else if (w->decorationHasAlpha() && effects->decorationSupportsBlurBehind()) {
// If the client hasn't specified a blur region, we'll only enable
// the effect behind the decoration.
region = QRegion(w->rect()) - w->decorationInnerRect();
region = decorationBlurRegion(w);
}
return region;
......
......@@ -58,6 +58,7 @@ public Q_SLOTS:
void slotWindowDeleted(KWin::EffectWindow *w);
void slotPropertyNotify(KWin::EffectWindow *w, long atom);
void slotScreenGeometryChanged();
void setupDecorationConnections(EffectWindow *w);
private:
QRect expand(const QRect &rect) const;
......@@ -67,6 +68,7 @@ private:
void initBlurStrengthValues();
void updateTexture();
QRegion blurRegion(const EffectWindow *w) const;
QRegion decorationBlurRegion(const EffectWindow *w) const;
bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const;
void updateBlurRegion(EffectWindow *w) const;
void doBlur(const QRegion &shape, const QRect &screen, const float opacity, const QMatrix4x4 &screenProjection, bool isDock, QRect windowRect);
......
......@@ -54,6 +54,10 @@ class QTabletEvent;
*/
Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
namespace KDecoration2 {
class Decoration;
}
namespace KWaylandServer {
class SurfaceInterface;
class Display;
......@@ -1865,6 +1869,14 @@ Q_SIGNALS:
*/
void sessionStateChanged();
/**
* This signal is emitted when decoration of @p was changed.
*
* @param w The window for which decoration changed
* @since 5.25
*/
void windowDecorationChanged(KWin::EffectWindow *window);
/**
* This signal is emitted when the visible geometry of a window changed.
*/
......@@ -2377,6 +2389,11 @@ public:
virtual QRect decorationInnerRect() const = 0;
bool hasDecoration() const;
virtual bool decorationHasAlpha() const = 0;
/**
* Returns the decoration
* @since 5.25
*/
virtual KDecoration2::Decoration *decoration() const = 0;
virtual QByteArray readProperty(long atom, long type, int format) const = 0;
virtual void deleteProperty(long atom) const = 0;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment