support kdecoration2 blurregion
--use kdecoration2 blurred regions to adjust blur effect appropriately when needed CCBUG:395725 Requires: https://invent.kde.org/plasma/kdecoration/-/merge_requests/17
This commit is contained in:
parent
c0d0fab049
commit
bc145b614c
7 changed files with 73 additions and 2 deletions
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue