effects/blur: Schedule blur manager removal with a delay

This prevents flickering behind plasma panels after changing compositing
settings.

If the blur effect is disabled, the destructor of the BlurEffect will
start the blur manager remove timer. When it expires, the blur manager
global will be removed and it will be finally destroyed after 5s (to work
around the wl_global race condition).

If compositing is toggled, the destructor of the BlurEffect will start
the remove timer and the constructor of the BlurEffect will stop the
timer, the blur manager object will be unaffected.

The blur effect options don't affect the generated shader code, so the
shader status check was removed in reconfigure().
master
Vlad Zahorodnii 3 years ago
parent 190a92bc3f
commit 76db5d76e7

@ -15,6 +15,7 @@
#include <QMatrix4x4>
#include <QScreen> // for QGuiApplication
#include <QTime>
#include <QTimer>
#include <QWindow>
#include <cmath> // for ceil()
@ -29,6 +30,9 @@ namespace KWin
static const QByteArray s_blurAtomName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION");
KWaylandServer::BlurManagerInterface *BlurEffect::s_blurManager = nullptr;
QTimer *BlurEffect::s_blurManagerRemoveTimer = nullptr;
BlurEffect::BlurEffect()
{
initConfig<BlurConfig>();
@ -40,13 +44,23 @@ BlurEffect::BlurEffect()
// ### Hackish way to announce support.
// Should be included in _NET_SUPPORTED instead.
if (m_shader && m_shader->isValid() && m_renderTargetsValid) {
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
KWaylandServer::Display *display = effects->waylandDisplay();
if (display) {
m_blurManager.reset(new KWaylandServer::BlurManagerInterface(display));
if (effects->xcbConnection()) {
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
}
if (effects->waylandDisplay()) {
if (!s_blurManagerRemoveTimer) {
s_blurManagerRemoveTimer = new QTimer(qApp);
s_blurManagerRemoveTimer->setSingleShot(true);
s_blurManagerRemoveTimer->callOnTimeout([]() {
s_blurManager->remove();
s_blurManager = nullptr;
});
}
s_blurManagerRemoveTimer->stop();
if (!s_blurManager) {
s_blurManager = new KWaylandServer::BlurManagerInterface(effects->waylandDisplay(), s_blurManagerRemoveTimer);
}
}
} else {
net_wm_blur_region = 0;
}
connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded);
@ -70,6 +84,10 @@ BlurEffect::BlurEffect()
BlurEffect::~BlurEffect()
{
// When compositing is restarted, avoid removing the manager immediately.
if (s_blurManager) {
s_blurManagerRemoveTimer->start(1000);
}
deleteFBOs();
}
@ -251,11 +269,6 @@ void BlurEffect::reconfigure(ReconfigureFlags flags)
updateTexture();
if (!m_shader || !m_shader->isValid()) {
effects->removeSupportProperty(s_blurAtomName, this);
m_blurManager.reset();
}
// Update all windows for the blur to take effect
effects->addRepaintFull();
}

@ -17,7 +17,6 @@
#include <QStack>
#include <KWaylandServer/blur_interface.h>
#include <KWaylandServer/utils.h>
namespace KWin
{
@ -90,7 +89,7 @@ private:
QScopedPointer<GLTexture> m_noiseTexture;
bool m_renderTargetsValid;
long net_wm_blur_region;
long net_wm_blur_region = 0;
QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top)
QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top)
@ -116,7 +115,9 @@ private:
QVector <BlurValuesStruct> blurStrengthValues;
QMap <EffectWindow*, QMetaObject::Connection> windowBlurChangedConnections;
KWaylandServer::ScopedGlobalPointer<KWaylandServer::BlurManagerInterface> m_blurManager;
static KWaylandServer::BlurManagerInterface *s_blurManager;
static QTimer *s_blurManagerRemoveTimer;
};
inline

Loading…
Cancel
Save