From f9e011539f74d3f396ed12c15a737a59f8a79fb6 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:09:33 +0100 Subject: [PATCH 01/17] cmake: add cpack support --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b86759d43..88e39f817 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,13 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CPACK_PACKAGE_NAME "kwin-better-blur") +set(CPACK_PACKAGING_INSTALL_PREFIX "/usr") +set(CPACK_PACKAGE_FILE_NAME "kwin-better-blur") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fork of the KWin Blur effect for KDE Plasma 6 with additional features (including force blur) and bug fixes") +include(CPack) + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE) endif() From 2f54614e6f423d0a77679987a61eaf288e994d28 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:19:47 +0100 Subject: [PATCH 02/17] readme: add build instructions for fedora kinoite --- README.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bad8506d6..8f8b69c08 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ Fixes for blur-related Plasma bugs that haven't been patched yet. # Building from source +> [!NOTE] +> On Fedora Kinoite and other distributions based on it, the effect must be built in a container. + ### Dependencies - CMake - Extra CMake Modules @@ -74,7 +77,7 @@ Fixes for blur-related Plasma bugs that haven't been patched yet.
- Fedora + Fedora 40, 41
``` @@ -98,10 +101,29 @@ cd kwin-effects-forceblur mkdir build cd build cmake ../ -DCMAKE_INSTALL_PREFIX=/usr -make -sudo make install +make -j ``` +### Installation +
+ Fedora Kinoite +
+ + ```sh + cpack -V -G RPM + exit # exit the container + sudo rpm-ostree install kwin-effects-forceblur/build/kwin-better-blur.rpm + ``` +
+
+ Other distributions +
+ + ```sh + sudo make install + ``` +
+ Remove the *build* directory when rebuilding the effect. # Usage From c75e6b560292a2812eb35560be5873eaf578949f Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:21:51 +0100 Subject: [PATCH 03/17] workflows/fedora-41: create --- .github/workflows/fedora-41.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/fedora-41.yml diff --git a/.github/workflows/fedora-41.yml b/.github/workflows/fedora-41.yml new file mode 100644 index 000000000..05b9b49cc --- /dev/null +++ b/.github/workflows/fedora-41.yml @@ -0,0 +1,31 @@ +name: Fedora 41 + +on: + push: + branches: [ main ] + paths-ignore: [ "**.md" ] + pull_request: + branches: [ main ] + paths-ignore: [ "**.md" ] + schedule: + - cron: "0 0 * * *" + +jobs: + build: + runs-on: ubuntu-latest + container: + image: fedora:41 + options: --user root + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Dependencies + run: dnf -y install git cmake extra-cmake-modules gcc-g++ kf6-kwindowsystem-devel plasma-workspace-devel libplasma-devel qt6-qtbase-private-devel qt6-qtbase-devel cmake kwin-devel extra-cmake-modules kwin-devel kf6-knotifications-devel kf6-kio-devel kf6-kcrash-devel kf6-ki18n-devel kf6-kguiaddons-devel libepoxy-devel kf6-kglobalaccel-devel kf6-kcmutils-devel kf6-kconfigwidgets-devel kf6-kdeclarative-devel kdecoration-devel kf6-kglobalaccel kf6-kdeclarative libplasma kf6-kio qt6-qtbase kf6-kguiaddons kf6-ki18n wayland-devel + + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build + + - name: Build + run: cmake --build ${{github.workspace}}/build -j From 84a01bc791cbb06489899f319638c8fbe7b01537 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:03:20 +0100 Subject: [PATCH 04/17] add support for KDecoration3 --- CMakeLists.txt | 10 +++++++++- src/CMakeLists.txt | 7 +++++-- src/blur.cpp | 20 ++++++++++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b86759d43..e28a387db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,15 @@ if(${KWin_VERSION} VERSION_GREATER_EQUAL 6.1.90) add_compile_definitions(KWIN_6_2_OR_GREATER) endif() -find_package(KDecoration2 REQUIRED) +find_package(KDecoration2) +find_package(KDecoration3) +if (${KDecoration3_FOUND}) + add_compile_definitions(KDECORATION3) +endif() +if(NOT ${KDecoration3_FOUND} AND NOT ${KDecoration2_FOUND}) + message(FATAL_ERROR "Could not find KDecoration2 or KDecoration3.") +endif() + find_package(KWinDBusInterface CONFIG REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2ce5f865c..e659aa2a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,8 +28,11 @@ target_link_libraries(forceblur PRIVATE KWin::kwin KF6::ConfigGui - - KDecoration2::KDecoration ) +if (${KDecoration3_FOUND}) + target_link_libraries(forceblur PRIVATE KDecoration3::KDecoration) +else() + target_link_libraries(forceblur PRIVATE KDecoration2::KDecoration) +endif() install(TARGETS forceblur DESTINATION ${KDE_INSTALL_PLUGINDIR}/kwin/effects/plugins) diff --git a/src/blur.cpp b/src/blur.cpp index 72f435167..6bf17335e 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -41,7 +41,12 @@ #include #include +#ifdef KDECORATION3 +#include +#else #include +#endif + #include Q_LOGGING_CATEGORY(KWIN_BLUR, "kwin_better_blur", QtWarningMsg) @@ -420,7 +425,13 @@ void BlurEffect::setupDecorationConnections(EffectWindow *w) return; } - connect(w->decoration(), &KDecoration2::Decoration::blurRegionChanged, this, [this, w]() { + connect(w->decoration(), +#ifdef KDECORATION3 + &KDecoration3::Decoration::blurRegionChanged +#else + &KDecoration2::Decoration::blurRegionChanged +#endif + , this, [this, w]() { updateBlurRegion(w); }); } @@ -464,7 +475,12 @@ QRegion BlurEffect::decorationBlurRegion(const EffectWindow *w) const return QRegion(); } - QRegion decorationRegion = QRegion(w->decoration()->rect()) - w->contentsRect().toRect(); + QRect decorationRect = w->decoration()->rect() +#ifdef KDECORATION3 + .toAlignedRect() +#endif + ; + QRegion decorationRegion = QRegion(decorationRect) - w->contentsRect().toRect(); //! we return only blurred regions that belong to decoration region return decorationRegion.intersected(w->decoration()->blurRegion()); } From b3dd6c9e3707a540fef0a59b1ec933932fc41a62 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:41:37 +0100 Subject: [PATCH 05/17] workflows/neon-unstable: create --- .github/workflows/neon-unstable.yml | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/neon-unstable.yml diff --git a/.github/workflows/neon-unstable.yml b/.github/workflows/neon-unstable.yml new file mode 100644 index 000000000..a26cf18eb --- /dev/null +++ b/.github/workflows/neon-unstable.yml @@ -0,0 +1,34 @@ +name: KDE Neon (unstable) + +on: + push: + branches: [ main ] + paths-ignore: [ "**.md" ] + pull_request: + branches: [ main ] + paths-ignore: [ "**.md" ] + schedule: + - cron: "0 0 * * *" + +jobs: + build: + runs-on: ubuntu-latest + container: + image: invent-registry.kde.org/neon/docker-images/plasma:unstable + options: --user root + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Refresh Packages + run: apt update + + - name: Install Dependencies + run: apt install -y git cmake g++ extra-cmake-modules qt6-tools-dev kwin-dev libkf6configwidgets-dev gettext libkf6crash-dev libkf6globalaccel-dev libkf6kio-dev libkf6service-dev libkf6notifications-dev libkf6kcmutils-dev libkdecorations3-dev + + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build + + - name: Build + run: cmake --build ${{github.workspace}}/build -j From 4e0191a9feda51b3fe700b9aeaa4677e2ba9eeff Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:36:35 +0100 Subject: [PATCH 06/17] workflows/opensuse-tumbleweed: create --- .github/workflows/opensuse-tumbleweed.yml | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/opensuse-tumbleweed.yml diff --git a/.github/workflows/opensuse-tumbleweed.yml b/.github/workflows/opensuse-tumbleweed.yml new file mode 100644 index 000000000..e9fd58afb --- /dev/null +++ b/.github/workflows/opensuse-tumbleweed.yml @@ -0,0 +1,34 @@ +name: openSUSE Tumbleweed + +on: + push: + branches: [ main ] + paths-ignore: [ "**.md" ] + pull_request: + branches: [ main ] + paths-ignore: [ "**.md" ] + schedule: + - cron: "0 0 * * *" + +jobs: + build: + runs-on: ubuntu-latest + container: + image: opensuse/tumbleweed + options: --user root + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Refresh Packages + run: zypper ref + + - name: Install Dependencies + run: zypper in -y git cmake-full gcc-c++ kf6-extra-cmake-modules kcoreaddons-devel kguiaddons-devel kconfigwidgets-devel kwindowsystem-devel ki18n-devel kiconthemes-devel kpackage-devel frameworkintegration-devel kcmutils-devel kirigami2-devel "cmake(KF6Config)" "cmake(KF6CoreAddons)" "cmake(KF6FrameworkIntegration)" "cmake(KF6GuiAddons)" "cmake(KF6I18n)" "cmake(KF6KCMUtils)" "cmake(KF6KirigamiPlatform)" "cmake(KF6WindowSystem)" "cmake(Qt6Core)" "cmake(Qt6DBus)" "cmake(Qt6Quick)" "cmake(Qt6Svg)" "cmake(Qt6Widgets)" "cmake(Qt6Xml)" "cmake(Qt6UiTools)" "cmake(KF6Crash)" "cmake(KF6GlobalAccel)" "cmake(KF6KIO)" "cmake(KF6Service)" "cmake(KF6Notifications)" libepoxy-devel kwin6-devel + + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build + + - name: Build + run: cmake --build ${{github.workspace}}/build -j From 84ebeeda8b8137a051d3efbf01ab4d98971fa454 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:57:28 +0100 Subject: [PATCH 07/17] blur: free the window's blur textures if it has fake blur If a window had real blur but then switched to fake blur, the textures used for real blur would still be kept in memory, even though they may never be used again. --- src/blur.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/blur.cpp b/src/blur.cpp index 6bf17335e..e73510040 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -820,6 +820,10 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg GLTexture *fakeBlurTexture = nullptr; if (w && hasFakeBlur(w)) { fakeBlurTexture = ensureFakeBlurTexture(m_currentScreen, renderTarget); + if (fakeBlurTexture) { + renderInfo.textures.clear(); + renderInfo.framebuffers.clear(); + } } if (!fakeBlurTexture From d0e61cbe90dda67d5c0e824c3ad383a2de9d69d1 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:27:42 +0100 Subject: [PATCH 08/17] blur: add ability to set brightness, saturation and contrast --- src/blur.cpp | 41 +++++++++++++++++ src/blur.h | 7 ++- src/blur.kcfg | 9 ++++ src/kcm/blur_config.ui | 78 +++++++++++++++++++++++++++++++- src/settings.cpp | 3 ++ src/settings.h | 3 ++ src/shaders/downsample.frag | 10 +++- src/shaders/downsample_core.frag | 10 +++- 8 files changed, 156 insertions(+), 5 deletions(-) diff --git a/src/blur.cpp b/src/blur.cpp index e73510040..42bf302d5 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -80,6 +80,8 @@ BlurEffect::BlurEffect() m_downsamplePass.mvpMatrixLocation = m_downsamplePass.shader->uniformLocation("modelViewProjectionMatrix"); m_downsamplePass.offsetLocation = m_downsamplePass.shader->uniformLocation("offset"); m_downsamplePass.halfpixelLocation = m_downsamplePass.shader->uniformLocation("halfpixel"); + m_downsamplePass.transformColorsLocation = m_downsamplePass.shader->uniformLocation("transformColors"); + m_downsamplePass.colorMatrixLocation = m_downsamplePass.shader->uniformLocation("colorMatrix"); } m_upsamplePass.shader = ShaderManager::instance()->generateShaderFromFile(ShaderTrait::MapTexture, @@ -238,6 +240,7 @@ void BlurEffect::reconfigure(ReconfigureFlags flags) m_offset = blurStrengthValues[m_settings.general.blurStrength].offset; m_expandSize = blurOffsets[m_iterationCount - 1].expandSize; m_fakeBlurTextures.clear(); + m_colorMatrix = colorMatrix(m_settings.general.brightness, m_settings.general.saturation, m_settings.general.contrast); for (EffectWindow *w : effects->stackingOrder()) { updateBlurRegion(w); @@ -1005,6 +1008,8 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg m_downsamplePass.shader->setUniform(m_downsamplePass.mvpMatrixLocation, projectionMatrix); m_downsamplePass.shader->setUniform(m_downsamplePass.offsetLocation, float(m_offset)); + m_downsamplePass.shader->setUniform(m_downsamplePass.colorMatrixLocation, m_colorMatrix); + m_downsamplePass.shader->setUniform(m_downsamplePass.transformColorsLocation, true); for (size_t i = 1; i < renderInfo.framebuffers.size(); ++i) { const auto &read = renderInfo.framebuffers[i - 1]; @@ -1018,6 +1023,10 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg GLFramebuffer::pushFramebuffer(draw.get()); vbo->draw(GL_TRIANGLES, 0, 6); + + if (i == 1) { + m_downsamplePass.shader->setUniform(m_downsamplePass.transformColorsLocation, false); + } } ShaderManager::instance()->popShader(); @@ -1252,6 +1261,38 @@ GLTexture *BlurEffect::createFakeBlurTextureX11(const GLenum &textureFormat) return compositeTexture.release(); } +QMatrix4x4 BlurEffect::colorMatrix(const float &brightness, const float &saturation, const float &contrast) const +{ + QMatrix4x4 saturationMatrix; + if (saturation != 1.0) { + const qreal r = (1.0 - saturation) * .2126; + const qreal g = (1.0 - saturation) * .7152; + const qreal b = (1.0 - saturation) * .0722; + + saturationMatrix = QMatrix4x4(r + saturation, r, r, 0.0, + g, g + saturation, g, 0.0, + b, b, b + saturation, 0.0, + 0, 0, 0, 1.0); + } + + QMatrix4x4 brightnessMatrix; + if (brightness != 1.0) { + brightnessMatrix.scale(brightness, brightness, brightness); + } + + QMatrix4x4 contrastMatrix; + if (contrast != 1.0) { + const float transl = (1.0 - contrast) / 2.0; + + contrastMatrix = QMatrix4x4(contrast, 0, 0, 0.0, + 0, contrast, 0, 0.0, + 0, 0, contrast, 0.0, + transl, transl, transl, 1.0); + } + + return contrastMatrix * saturationMatrix * brightnessMatrix; +} + bool BlurEffect::isActive() const { return m_valid && !effects->isScreenLocked(); diff --git a/src/blur.h b/src/blur.h index d783edf85..3906caaf2 100644 --- a/src/blur.h +++ b/src/blur.h @@ -97,6 +97,7 @@ public Q_SLOTS: bool shouldForceBlur(const EffectWindow *w) const; void updateBlurRegion(EffectWindow *w, bool geometryChanged = false); bool hasFakeBlur(EffectWindow *w); + QMatrix4x4 colorMatrix(const float &brightness, const float &saturation, const float &contrast) const; /* * @param w The pointer to the window being blurred, nullptr if an image is being blurred. @@ -139,6 +140,8 @@ public Q_SLOTS: int mvpMatrixLocation; int offsetLocation; int halfpixelLocation; + int transformColorsLocation; + int colorMatrixLocation; } m_downsamplePass; struct @@ -158,8 +161,6 @@ public Q_SLOTS: int antialiasingLocation; int blurSizeLocation; int opacityLocation; - - } m_upsamplePass; struct @@ -215,6 +216,8 @@ public Q_SLOTS: // Windows to blur even when transformed. QList m_blurWhenTransformed; + QMatrix4x4 m_colorMatrix; + QMap windowBlurChangedConnections; QMap windowExpandedGeometryChangedConnections; QMap screenChangedConnections; diff --git a/src/blur.kcfg b/src/blur.kcfg index 32512e873..9d62fa9d4 100644 --- a/src/blur.kcfg +++ b/src/blur.kcfg @@ -73,5 +73,14 @@ class3 true + + 1.0 + + + 1.0 + + + 1.0 + diff --git a/src/kcm/blur_config.ui b/src/kcm/blur_config.ui index cfd50e11a..00a1e1859 100644 --- a/src/kcm/blur_config.ui +++ b/src/kcm/blur_config.ui @@ -7,7 +7,7 @@ 0 0 480 - 200 + 240 @@ -179,6 +179,82 @@ + + + + Qt::Vertical + + + + 0 + 10 + + + + + + + + + + Brightness + + + + + + + 0.0 + + + 0.1 + + + + + + + + + + + Saturation + + + + + + + 0.0 + + + 0.1 + + + + + + + + + + + Contrast + + + + + + + 0.0 + + + 0.1 + + + + + diff --git a/src/settings.cpp b/src/settings.cpp index 88eb0db6d..a38307e44 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -11,6 +11,9 @@ void BlurSettings::read() general.blurStrength = BlurConfig::blurStrength() - 1; general.noiseStrength = BlurConfig::noiseStrength(); general.windowOpacityAffectsBlur = BlurConfig::transparentBlur(); + general.brightness = BlurConfig::brightness(); + general.saturation = BlurConfig::saturation(); + general.contrast = BlurConfig::contrast(); forceBlur.windowClasses = BlurConfig::windowClasses().split("\n"); forceBlur.windowClassMatchingMode = BlurConfig::blurMatching() ? WindowClassMatchingMode::Whitelist : WindowClassMatchingMode::Blacklist; diff --git a/src/settings.h b/src/settings.h index aa72cba94..7d97fd39e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -24,6 +24,9 @@ struct GeneralSettings int blurStrength; int noiseStrength; bool windowOpacityAffectsBlur; + float brightness; + float saturation; + float contrast; }; struct ForceBlurSettings diff --git a/src/shaders/downsample.frag b/src/shaders/downsample.frag index d83b7133b..2e0c81028 100644 --- a/src/shaders/downsample.frag +++ b/src/shaders/downsample.frag @@ -2,6 +2,9 @@ uniform sampler2D texUnit; uniform float offset; uniform vec2 halfpixel; +uniform bool transformColors; +uniform mat4 colorMatrix; + varying vec2 uv; void main(void) @@ -11,6 +14,11 @@ void main(void) sum += texture2D(texUnit, uv + halfpixel.xy * offset); sum += texture2D(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset); sum += texture2D(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset); + sum /= 8.0; + + if (transformColors) { + sum *= colorMatrix; + } - gl_FragColor = sum / 8.0; + gl_FragColor = sum; } diff --git a/src/shaders/downsample_core.frag b/src/shaders/downsample_core.frag index 8f16f232a..32f1fa462 100644 --- a/src/shaders/downsample_core.frag +++ b/src/shaders/downsample_core.frag @@ -4,6 +4,9 @@ uniform sampler2D texUnit; uniform float offset; uniform vec2 halfpixel; +uniform bool transformColors; +uniform mat4 colorMatrix; + in vec2 uv; out vec4 fragColor; @@ -15,6 +18,11 @@ void main(void) sum += texture(texUnit, uv + halfpixel.xy * offset); sum += texture(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset); sum += texture(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset); + sum /= 8.0; + + if (transformColors) { + sum *= colorMatrix; + } - fragColor = sum / 8.0; + fragColor = sum; } From f838534ba6354fe95dfbc8f179a5af03e54095f5 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:50:17 +0100 Subject: [PATCH 09/17] force-blur: fix blur region for x11 windows with csd --- src/blur.cpp | 18 ++++++++++++------ src/blur.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/blur.cpp b/src/blur.cpp index d156dc4e0..b2afd92ef 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -278,9 +278,15 @@ void BlurEffect::updateBlurRegion(EffectWindow *w, bool geometryChanged) // Don't override blur region for menus that already have one. The window geometry could include shadows. if (shouldForceBlur(w) && !((isMenu(w) || w->isTooltip()) && (content.has_value() || geometryChanged))) { - content = w->expandedGeometry().translated(-w->x(), -w->y()).toRect(); - if (m_settings.forceBlur.blurDecorations && w->decoration()) { - frame = w->frameGeometry().translated(-w->x(), -w->y()).toRect(); + // On X11, EffectWindow::contentsRect() includes GTK's client-side shadows, while on Wayland, it doesn't. + // The content region is translated by EffectWindow::contentsRect() in BlurEffect::blurRegion, causing the + // blur region to be off on X11. The frame region is not translated, so it is used instead. + const auto isX11WithCSD = !effects->waylandDisplay() && (w->frameGeometry() != w->bufferGeometry()); + if (!isX11WithCSD) { + content = w->contentsRect().translated(-w->contentsRect().topLeft()).toRect(); + } + if (isX11WithCSD || (m_settings.forceBlur.blurDecorations && w->decoration())) { + frame = w->frameGeometry().translated(-w->x(), -w->y()).toRect();; } } @@ -323,7 +329,7 @@ void BlurEffect::slotWindowAdded(EffectWindow *w) }); } - windowExpandedGeometryChangedConnections[w] = connect(w, &EffectWindow::windowExpandedGeometryChanged, this, [this,w]() { + windowFrameGeometryChangedConnections[w] = connect(w, &EffectWindow::windowFrameGeometryChanged, this, [this,w]() { if (!w) { return; } @@ -358,9 +364,9 @@ void BlurEffect::slotWindowDeleted(EffectWindow *w) disconnect(*it); windowBlurChangedConnections.erase(it); } - if (auto it = windowExpandedGeometryChangedConnections.find(w); it != windowExpandedGeometryChangedConnections.end()) { + if (auto it = windowFrameGeometryChangedConnections.find(w); it != windowFrameGeometryChangedConnections.end()) { disconnect(*it); - windowExpandedGeometryChangedConnections.erase(it); + windowFrameGeometryChangedConnections.erase(it); } if (auto it = std::find(m_allWindows.begin(), m_allWindows.end(), w); it != m_allWindows.end()) { m_allWindows.erase(it); diff --git a/src/blur.h b/src/blur.h index bb06547f2..d84ed42a8 100644 --- a/src/blur.h +++ b/src/blur.h @@ -207,7 +207,7 @@ public Q_SLOTS: QList m_blurWhenTransformed; QMap windowBlurChangedConnections; - QMap windowExpandedGeometryChangedConnections; + QMap windowFrameGeometryChangedConnections; QMap screenChangedConnections; std::unordered_map m_windows; From b2854140e2614b765be248528e97a4596d11e070 Mon Sep 17 00:00:00 2001 From: taj_ny <79316397+taj-ny@users.noreply.github.com> Date: Fri, 20 Dec 2024 19:03:10 +0100 Subject: [PATCH 10/17] remove double semicolon --- src/blur.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blur.cpp b/src/blur.cpp index b921c74b9..b0a93b588 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -300,7 +300,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w, bool geometryChanged) content = w->contentsRect().translated(-w->contentsRect().topLeft()).toRect(); } if (isX11WithCSD || (m_settings.forceBlur.blurDecorations && w->decoration())) { - frame = w->frameGeometry().translated(-w->x(), -w->y()).toRect();; + frame = w->frameGeometry().translated(-w->x(), -w->y()).toRect(); } } From 02c5c93d86de12fb344f8abd7778b75862cff437 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:42:23 +0100 Subject: [PATCH 11/17] force-blur: fix blur region for x11 windows with csd on wayland f0814dad41ea92234418d3947b91348933f4f696 fixed it on X11 and broke it on Wayland. --- src/blur.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blur.cpp b/src/blur.cpp index b0a93b588..76ce6902d 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -295,7 +295,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w, bool geometryChanged) // On X11, EffectWindow::contentsRect() includes GTK's client-side shadows, while on Wayland, it doesn't. // The content region is translated by EffectWindow::contentsRect() in BlurEffect::blurRegion, causing the // blur region to be off on X11. The frame region is not translated, so it is used instead. - const auto isX11WithCSD = !effects->waylandDisplay() && (w->frameGeometry() != w->bufferGeometry()); + const auto isX11WithCSD = w->isX11Client() && w->frameGeometry() != w->bufferGeometry(); if (!isX11WithCSD) { content = w->contentsRect().translated(-w->contentsRect().topLeft()).toRect(); } From 73c34a8fde8229e23e24c1d358ea30d979f135e8 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Sat, 28 Dec 2024 22:40:12 +0100 Subject: [PATCH 12/17] kcm: add about page --- src/kcm/CMakeLists.txt | 2 ++ src/kcm/blur_config.cpp | 2 ++ src/kcm/blur_config.ui | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/kcm/CMakeLists.txt b/src/kcm/CMakeLists.txt index 7072ba56b..20da9a805 100644 --- a/src/kcm/CMakeLists.txt +++ b/src/kcm/CMakeLists.txt @@ -14,3 +14,5 @@ target_link_libraries(kwin_better_blur_config ) install(TARGETS kwin_better_blur_config DESTINATION ${KDE_INSTALL_PLUGINDIR}/kwin/effects/configs) + +add_compile_definitions(ABOUT_VERSION_STRING="v${PROJECT_VERSION}") \ No newline at end of file diff --git a/src/kcm/blur_config.cpp b/src/kcm/blur_config.cpp index 0f5fab180..82e26b535 100644 --- a/src/kcm/blur_config.cpp +++ b/src/kcm/blur_config.cpp @@ -24,6 +24,8 @@ BlurEffectConfig::BlurEffectConfig(QObject *parent, const KPluginMetaData &data) ui.setupUi(widget()); BlurConfig::instance("kwinrc"); addConfig(BlurConfig::self(), widget()); + + ui.versionString->setText(QStringLiteral("Version: ") + ABOUT_VERSION_STRING); } BlurEffectConfig::~BlurEffectConfig() diff --git a/src/kcm/blur_config.ui b/src/kcm/blur_config.ui index 00a1e1859..7cee9e727 100644 --- a/src/kcm/blur_config.ui +++ b/src/kcm/blur_config.ui @@ -637,6 +637,31 @@ Works best with tiling. + + + About + + + + + + + + + + + + + + + 0 + 1 + + + + + + From 197b543b0d1737d119e0659a94272db62fe5dd5f Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Sun, 29 Dec 2024 12:07:14 +0100 Subject: [PATCH 13/17] kcm/about: add project name --- src/kcm/CMakeLists.txt | 2 +- src/kcm/blur_config.cpp | 2 +- src/kcm/blur_config.ui | 20 ++++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/kcm/CMakeLists.txt b/src/kcm/CMakeLists.txt index 20da9a805..6883de22c 100644 --- a/src/kcm/CMakeLists.txt +++ b/src/kcm/CMakeLists.txt @@ -15,4 +15,4 @@ target_link_libraries(kwin_better_blur_config install(TARGETS kwin_better_blur_config DESTINATION ${KDE_INSTALL_PLUGINDIR}/kwin/effects/configs) -add_compile_definitions(ABOUT_VERSION_STRING="v${PROJECT_VERSION}") \ No newline at end of file +add_compile_definitions(ABOUT_VERSION_STRING="${PROJECT_VERSION}") \ No newline at end of file diff --git a/src/kcm/blur_config.cpp b/src/kcm/blur_config.cpp index 82e26b535..7f73e12d8 100644 --- a/src/kcm/blur_config.cpp +++ b/src/kcm/blur_config.cpp @@ -25,7 +25,7 @@ BlurEffectConfig::BlurEffectConfig(QObject *parent, const KPluginMetaData &data) BlurConfig::instance("kwinrc"); addConfig(BlurConfig::self(), widget()); - ui.versionString->setText(QStringLiteral("Version: ") + ABOUT_VERSION_STRING); + ui.versionString->setText(QStringLiteral("Version ") + ABOUT_VERSION_STRING); } BlurEffectConfig::~BlurEffectConfig() diff --git a/src/kcm/blur_config.ui b/src/kcm/blur_config.ui index 7cee9e727..30b02e9d8 100644 --- a/src/kcm/blur_config.ui +++ b/src/kcm/blur_config.ui @@ -644,12 +644,24 @@ Works best with tiling. - - - + + + + + true + 15 + + + + Better Blur + + + - + + + From 387b9d6ddb2f51cb43123dbd7cc9bb50bbc45953 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Sun, 29 Dec 2024 18:57:15 +0100 Subject: [PATCH 14/17] kcm/about: add authors and links --- src/kcm/CMakeLists.txt | 6 +++++- src/kcm/about.html | 12 +++++++++++ src/kcm/blur_config.cpp | 8 +++++++- src/kcm/blur_config.qrc | 5 +++++ src/kcm/blur_config.ui | 45 +++++++++-------------------------------- 5 files changed, 38 insertions(+), 38 deletions(-) create mode 100644 src/kcm/about.html create mode 100644 src/kcm/blur_config.qrc diff --git a/src/kcm/CMakeLists.txt b/src/kcm/CMakeLists.txt index 6883de22c..26ff09517 100644 --- a/src/kcm/CMakeLists.txt +++ b/src/kcm/CMakeLists.txt @@ -1,4 +1,8 @@ -set(kwin_better_blur_config_SRCS blur_config.cpp blur_config.h) +set(kwin_better_blur_config_SRCS + blur_config.cpp + blur_config.h + blur_config.qrc +) ki18n_wrap_ui(kwin_better_blur_config_SRCS blur_config.ui) kconfig_add_kcfg_files(kwin_better_blur_config_SRCS ../blurconfig.kcfgc) diff --git a/src/kcm/about.html b/src/kcm/about.html new file mode 100644 index 000000000..944b093a0 --- /dev/null +++ b/src/kcm/about.html @@ -0,0 +1,12 @@ +

Better Blur

+

Version ${version}

+ +

+ Authors:
+ KWin development team
+ taj_ny +

+

+ GitHub
+ Configuration documentation +

\ No newline at end of file diff --git a/src/kcm/blur_config.cpp b/src/kcm/blur_config.cpp index 7f73e12d8..c4c00a634 100644 --- a/src/kcm/blur_config.cpp +++ b/src/kcm/blur_config.cpp @@ -25,7 +25,13 @@ BlurEffectConfig::BlurEffectConfig(QObject *parent, const KPluginMetaData &data) BlurConfig::instance("kwinrc"); addConfig(BlurConfig::self(), widget()); - ui.versionString->setText(QStringLiteral("Version ") + ABOUT_VERSION_STRING); + QFile about(":/effects/forceblur/kcm/about.html"); + if (about.open(QIODevice::ReadOnly)) { + const auto html = about.readAll() + .replace("${version}", ABOUT_VERSION_STRING) + .replace("${repo}", "https://github.com/taj-ny/kwin-effects-forceblur"); + ui.aboutText->setHtml(html); + } } BlurEffectConfig::~BlurEffectConfig() diff --git a/src/kcm/blur_config.qrc b/src/kcm/blur_config.qrc new file mode 100644 index 000000000..a953ab2c8 --- /dev/null +++ b/src/kcm/blur_config.qrc @@ -0,0 +1,5 @@ + + + about.html + + diff --git a/src/kcm/blur_config.ui b/src/kcm/blur_config.ui index 30b02e9d8..5cd765f34 100644 --- a/src/kcm/blur_config.ui +++ b/src/kcm/blur_config.ui @@ -643,32 +643,15 @@ Works best with tiling. - - - - - - true - 15 - - - - Better Blur - - - - - - - - - - - - - 0 - 1 - + + + true + + + true + + + Failed to load about.html @@ -676,16 +659,6 @@ Works best with tiling.
- - - - <a href="https://github.com/taj-ny/kwin-effects-forceblur/blob/main/docs/configuration.md">Configuration documentation</a> - - - true - - -
From ba201ce8131511505528624bba5ede7772a521cd Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:42:39 +0100 Subject: [PATCH 15/17] rename fake blur to static blur --- README.md | 2 +- docs/configuration.md | 8 ++--- src/blur.cpp | 80 +++++++++++++++++++++--------------------- src/blur.h | 16 ++++----- src/kcm/blur_config.ui | 8 ++--- src/settings.cpp | 12 +++---- src/settings.h | 8 ++--- 7 files changed, 67 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 8f8b69c08..f5deb21e3 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Better Blur (formerly kwin-effects-forceblur) is a fork the KWin Blur effect for - X11 and Wayland support - Force blur - Rounded corners with optional anti-aliasing -- Optional blur texture caching for much lower GPU usage, works best with tiling +- Static blur for much lower GPU usage ### Bug fixes Fixes for blur-related Plasma bugs that haven't been patched yet. diff --git a/docs/configuration.md b/docs/configuration.md index 98126a8ee..ef265d2de 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -17,11 +17,11 @@ This option will override the blur region specified by the decoration. ### Paint windows as non-opaque Fixes transparency for some applications by marking their windows as transparent. This will only be done for force-blurred windows. -# Fake blur +# Static blur When enabled, the blur texture will be cached and reused. The blurred areas of the window will be marked as opaque, resulting in KWin not painting anything behind them. Only one image per screen is cached at a time. -Fake blur is mainly intended for laptop users who want longer battery life while still having blur everywhere. +Static blur is mainly intended for laptop users who want longer battery life while still having blur everywhere. ### Use real blur for windows that are in front of other windows By default, when two windows overlap, you won't be able to see the window behind. @@ -32,11 +32,11 @@ If this option is enabled, the effect will automatically switch to real blur whe https://github.com/taj-ny/kwin-effects-forceblur/assets/79316397/7bae6a16-6c78-4889-8df1-feb24005dabc ### Image source -The image to use for fake blur. +The image to use for static blur. - Desktop wallpaper - A screenshot of the desktop is taken for every screen. Icons and widgets will be included. The cached texture is invalidated when the entire desktop is repainted, which can happen when the wallpaper changes, icons are interacted with or when widgets update. - Custom - The specified image is scaled for every screen without respecting the aspect ratio. Supported formats are JPEG and PNG. ### Blur image -Whether to blur the image used for fake blur. This is only done once. +Whether to blur the image used for static blur. This is only done once. diff --git a/src/blur.cpp b/src/blur.cpp index 76ce6902d..02a2f5874 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -239,7 +239,7 @@ void BlurEffect::reconfigure(ReconfigureFlags flags) m_iterationCount = blurStrengthValues[m_settings.general.blurStrength].iteration; m_offset = blurStrengthValues[m_settings.general.blurStrength].offset; m_expandSize = blurOffsets[m_iterationCount - 1].expandSize; - m_fakeBlurTextures.clear(); + m_staticBlurTextures.clear(); m_colorMatrix = colorMatrix(m_settings.general.brightness, m_settings.general.saturation, m_settings.general.contrast); for (EffectWindow *w : effects->stackingOrder()) { @@ -319,13 +319,13 @@ void BlurEffect::updateBlurRegion(EffectWindow *w, bool geometryChanged) } } -bool BlurEffect::hasFakeBlur(EffectWindow *w) +bool BlurEffect::hasStaticBlur(EffectWindow *w) { - if (!m_settings.fakeBlur.enable) { + if (!m_settings.staticBlur.enable) { return false; } - if (m_settings.fakeBlur.disableWhenWindowBehind) { + if (m_settings.staticBlur.disableWhenWindowBehind) { if (auto it = m_windows.find(w); it != m_windows.end()) { return !it->second.hasWindowBehind; } @@ -352,7 +352,7 @@ void BlurEffect::slotWindowAdded(EffectWindow *w) } if (w->isDesktop() && !effects->waylandDisplay()) { - m_fakeBlurTextures.erase(nullptr); + m_staticBlurTextures.erase(nullptr); return; } @@ -397,11 +397,11 @@ void BlurEffect::slotWindowDeleted(EffectWindow *w) void BlurEffect::slotScreenAdded(KWin::Output *screen) { screenChangedConnections[screen] = connect(screen, &Output::changed, this, [this, screen]() { - if (!m_settings.fakeBlur.enable) { + if (!m_settings.staticBlur.enable) { return; } - m_fakeBlurTextures.erase(screen); + m_staticBlurTextures.erase(screen); effects->addRepaintFull(); }); } @@ -536,8 +536,8 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:: // in case this window has regions to be blurred const QRegion blurArea = blurRegion(w).translated(w->pos().toPoint()); - bool fakeBlur = hasFakeBlur(w) && m_fakeBlurTextures.contains(m_currentScreen) && !blurArea.isEmpty(); - if (fakeBlur) { + bool staticBlur = hasStaticBlur(w) && m_staticBlurTextures.contains(m_currentScreen) && !blurArea.isEmpty(); + if (staticBlur) { data.opaque += blurArea; int topCornerRadius; @@ -560,8 +560,8 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:: } } - if (m_settings.fakeBlur.enable) { - if (m_settings.fakeBlur.disableWhenWindowBehind) { + if (m_settings.staticBlur.enable) { + if (m_settings.staticBlur.disableWhenWindowBehind) { if (auto it = m_windows.find(w); it != m_windows.end()) { const bool hadWindowBehind = it->second.hasWindowBehind; it->second.hasWindowBehind = false; @@ -588,18 +588,18 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:: } } - if (m_settings.fakeBlur.imageSource == FakeBlurImageSource::DesktopWallpaper && w->isDesktop() && w->frameGeometry() == data.paint.boundingRect()) { - m_fakeBlurTextures.erase(m_currentScreen); + if (m_settings.staticBlur.imageSource == StaticBlurImageSource::DesktopWallpaper && w->isDesktop() && w->frameGeometry() == data.paint.boundingRect()) { + m_staticBlurTextures.erase(m_currentScreen); } } - if (m_settings.forceBlur.markWindowAsTranslucent && !fakeBlur && shouldForceBlur(w)) { + if (m_settings.forceBlur.markWindowAsTranslucent && !staticBlur && shouldForceBlur(w)) { data.setTranslucent(); } effects->prePaintWindow(w, data, presentTime); - if (!fakeBlur) { + if (!staticBlur) { const QRegion oldOpaque = data.opaque; if (data.opaque.intersects(m_currentBlur)) { // to blur an area partially we have to shrink the opaque area of a window @@ -692,10 +692,10 @@ void BlurEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewpo effects->drawWindow(renderTarget, viewport, w, mask, region, data); } -GLTexture *BlurEffect::ensureFakeBlurTexture(const Output *output, const RenderTarget &renderTarget) +GLTexture *BlurEffect::ensureStaticBlurTexture(const Output *output, const RenderTarget &renderTarget) { - if (m_fakeBlurTextures.contains(output)) { - return m_fakeBlurTextures[output].get(); + if (m_staticBlurTextures.contains(output)) { + return m_staticBlurTextures[output].get(); } if (effects->waylandDisplay() && !output) { @@ -707,13 +707,13 @@ GLTexture *BlurEffect::ensureFakeBlurTexture(const Output *output, const RenderT textureFormat = renderTarget.texture()->internalFormat(); } GLTexture *texture = effects->waylandDisplay() - ? createFakeBlurTextureWayland(output, renderTarget, textureFormat) - : createFakeBlurTextureX11(textureFormat); + ? createStaticBlurTextureWayland(output, renderTarget, textureFormat) + : createStaticBlurTextureX11(textureFormat); if (!texture) { return nullptr; } - return (m_fakeBlurTextures[output] = std::unique_ptr(texture)).get(); + return (m_staticBlurTextures[output] = std::unique_ptr(texture)).get(); } GLTexture *BlurEffect::ensureNoiseTexture() @@ -826,16 +826,16 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg // Since the VBO is shared, the texture needs to be blurred before the geometry is uploaded, otherwise it will be // reset. - GLTexture *fakeBlurTexture = nullptr; - if (w && hasFakeBlur(w)) { - fakeBlurTexture = ensureFakeBlurTexture(m_currentScreen, renderTarget); - if (fakeBlurTexture) { + GLTexture *staticBlurTexture = nullptr; + if (w && hasStaticBlur(w)) { + staticBlurTexture = ensureStaticBlurTexture(m_currentScreen, renderTarget); + if (staticBlurTexture) { renderInfo.textures.clear(); renderInfo.framebuffers.clear(); } } - if (!fakeBlurTexture + if (!staticBlurTexture && (renderInfo.framebuffers.size() != (m_iterationCount + 1) || renderInfo.textures[0]->size() != backgroundRect.size() || renderInfo.textures[0]->internalFormat() != textureFormat)) { @@ -862,7 +862,7 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg } // Fetch the pixels behind the shape that is going to be blurred. - if (!fakeBlurTexture) { + if (!staticBlurTexture) { const QRegion dirtyRegion = region & backgroundRect; for (const QRect &dirtyRect: dirtyRegion) { renderInfo.framebuffers[0]->blitFromRenderTarget(renderTarget, viewport, dirtyRect, dirtyRect.translated(-backgroundRect.topLeft())); @@ -973,7 +973,7 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg vbo->bindArrays(); - if (fakeBlurTexture) { + if (staticBlurTexture) { ShaderManager::instance()->pushShader(m_texture.shader.get()); QMatrix4x4 projectionMatrix; @@ -986,7 +986,7 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg } m_texture.shader->setUniform(m_texture.mvpMatrixLocation, projectionMatrix); - m_texture.shader->setUniform(m_texture.textureSizeLocation, QVector2D(fakeBlurTexture->size().width(), fakeBlurTexture->size().height())); + m_texture.shader->setUniform(m_texture.textureSizeLocation, QVector2D(staticBlurTexture->size().width(), staticBlurTexture->size().height())); m_texture.shader->setUniform(m_texture.texStartPosLocation, QVector2D(backgroundRect.x() - screenGeometry.x(), backgroundRect.y() - screenGeometry.y())); m_texture.shader->setUniform(m_texture.blurSizeLocation, QVector2D(backgroundRect.width(), backgroundRect.height())); m_texture.shader->setUniform(m_texture.scaleLocation, (float)viewport.scale()); @@ -995,7 +995,7 @@ void BlurEffect::blur(BlurRenderData &renderInfo, const RenderTarget &renderTarg m_texture.shader->setUniform(m_texture.antialiasingLocation, m_settings.roundedCorners.antialiasing); m_texture.shader->setUniform(m_texture.opacityLocation, static_cast(opacity)); - fakeBlurTexture->bind(); + staticBlurTexture->bind(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1155,7 +1155,7 @@ GLTexture *BlurEffect::wallpaper(EffectWindow *desktop, const qreal &scale, cons return texture.release(); } -GLTexture *BlurEffect::createFakeBlurTextureWayland(const Output *output, const RenderTarget &renderTarget, const GLenum &textureFormat) +GLTexture *BlurEffect::createStaticBlurTextureWayland(const Output *output, const RenderTarget &renderTarget, const GLenum &textureFormat) { EffectWindow *desktop = nullptr; for (EffectWindow *w : effects->stackingOrder()) { @@ -1169,10 +1169,10 @@ GLTexture *BlurEffect::createFakeBlurTextureWayland(const Output *output, const } std::unique_ptr texture; - if (m_settings.fakeBlur.imageSource == FakeBlurImageSource::DesktopWallpaper) { + if (m_settings.staticBlur.imageSource == StaticBlurImageSource::DesktopWallpaper) { texture.reset(wallpaper(desktop, output->scale(), textureFormat)); - } else if (m_settings.fakeBlur.imageSource == FakeBlurImageSource::Custom) { - texture = GLTexture::upload(m_settings.fakeBlur.customImage.scaled(output->pixelSize(), Qt::AspectRatioMode::IgnoreAspectRatio, Qt::TransformationMode::SmoothTransformation)); + } else if (m_settings.staticBlur.imageSource == StaticBlurImageSource::Custom) { + texture = GLTexture::upload(m_settings.staticBlur.customImage.scaled(output->pixelSize(), Qt::AspectRatioMode::IgnoreAspectRatio, Qt::TransformationMode::SmoothTransformation)); } if (!texture) { return nullptr; @@ -1207,14 +1207,14 @@ GLTexture *BlurEffect::createFakeBlurTextureWayland(const Output *output, const GLFramebuffer::popFramebuffer(); ShaderManager::instance()->popShader(); - if (m_settings.fakeBlur.blurCustomImage) { + if (m_settings.staticBlur.blurCustomImage) { blur(texture.get()); } return texture.release(); } -GLTexture *BlurEffect::createFakeBlurTextureX11(const GLenum &textureFormat) +GLTexture *BlurEffect::createStaticBlurTextureX11(const GLenum &textureFormat) { std::vector desktops; QRegion desktopGeometries; @@ -1241,16 +1241,16 @@ GLTexture *BlurEffect::createFakeBlurTextureX11(const GLenum &textureFormat) const auto geometry = desktop->frameGeometry(); std::unique_ptr texture; - if (m_settings.fakeBlur.imageSource == FakeBlurImageSource::DesktopWallpaper) { + if (m_settings.staticBlur.imageSource == StaticBlurImageSource::DesktopWallpaper) { texture.reset(wallpaper(desktop, 1, textureFormat)); - } else if (m_settings.fakeBlur.imageSource == FakeBlurImageSource::Custom) { - texture = GLTexture::upload(m_settings.fakeBlur.customImage.scaled(geometry.width(), geometry.height(), Qt::AspectRatioMode::IgnoreAspectRatio, Qt::TransformationMode::SmoothTransformation)); + } else if (m_settings.staticBlur.imageSource == StaticBlurImageSource::Custom) { + texture = GLTexture::upload(m_settings.staticBlur.customImage.scaled(geometry.width(), geometry.height(), Qt::AspectRatioMode::IgnoreAspectRatio, Qt::TransformationMode::SmoothTransformation)); } if (!texture) { return nullptr; } - if (m_settings.fakeBlur.blurCustomImage) { + if (m_settings.staticBlur.blurCustomImage) { blur(texture.get()); } diff --git a/src/blur.h b/src/blur.h index 6f426b5cb..bc3251179 100644 --- a/src/blur.h +++ b/src/blur.h @@ -96,7 +96,7 @@ public Q_SLOTS: bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data); bool shouldForceBlur(const EffectWindow *w) const; void updateBlurRegion(EffectWindow *w, bool geometryChanged = false); - bool hasFakeBlur(EffectWindow *w); + bool hasStaticBlur(EffectWindow *w); QMatrix4x4 colorMatrix(const float &brightness, const float &saturation, const float &contrast) const; /* @@ -108,9 +108,9 @@ public Q_SLOTS: /** * @param output Can be nullptr. * @remark This method shall not be called outside of BlurEffect::blur. - * @return The cached fake blur texture. The texture will be created if it doesn't exist. + * @return The cached static blur texture. The texture will be created if it doesn't exist. */ - GLTexture *ensureFakeBlurTexture(const Output *output, const RenderTarget &renderTarget); + GLTexture *ensureStaticBlurTexture(const Output *output, const RenderTarget &renderTarget); GLTexture *ensureNoiseTexture(); /** @@ -121,17 +121,17 @@ public Q_SLOTS: GLTexture *wallpaper(EffectWindow *desktop, const qreal &scale, const GLenum &textureFormat); /** - * Creates a fake blur texture for the specified screen. + * Creates a static blur texture for the specified screen. * @remark This method shall not be called outside of BlurEffect::blur. * @return A pointer to the texture, or nullptr if an error occurred. */ - GLTexture *createFakeBlurTextureWayland(const Output *output, const RenderTarget &renderTarget, const GLenum &textureFormat); + GLTexture *createStaticBlurTextureWayland(const Output *output, const RenderTarget &renderTarget, const GLenum &textureFormat); /** - * Creates a composite fake blur texture containing images for all screens. + * Creates a composite static blur texture containing images for all screens. * @return A pointer to the texture, or nullptr if an error occurred. */ - GLTexture *createFakeBlurTextureX11(const GLenum &textureFormat); + GLTexture *createStaticBlurTextureX11(const GLenum &textureFormat); private: struct @@ -211,7 +211,7 @@ public Q_SLOTS: QList blurStrengthValues; - std::unordered_map> m_fakeBlurTextures; + std::unordered_map> m_staticBlurTextures; // Windows to blur even when transformed. QList m_blurWhenTransformed; diff --git a/src/kcm/blur_config.ui b/src/kcm/blur_config.ui index 5cd765f34..502e0294f 100644 --- a/src/kcm/blur_config.ui +++ b/src/kcm/blur_config.ui @@ -467,14 +467,14 @@ - Fake Blur + Static blur - When enabled, the blur texture will be cached and reused, resulting in much lower GPU usage. -Works best with tiling. + When enabled, a cached texture will be painted behind windows instead of actually blurring +the background, resulting in much lower GPU usage. @@ -501,7 +501,7 @@ Works best with tiling. - Use real blur for windows that are in front of other windows + Use dynamic blur for windows with other windows behind diff --git a/src/settings.cpp b/src/settings.cpp index a38307e44..5cbfda97d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -29,15 +29,15 @@ void BlurSettings::read() roundedCorners.antialiasing = BlurConfig::roundedCornersAntialiasing(); roundedCorners.roundMaximized = BlurConfig::roundCornersOfMaximizedWindows(); - fakeBlur.enable = BlurConfig::fakeBlur(); - fakeBlur.disableWhenWindowBehind = BlurConfig::fakeBlurDisableWhenWindowBehind(); - fakeBlur.customImage = QImage(BlurConfig::fakeBlurImage()); + staticBlur.enable = BlurConfig::fakeBlur(); + staticBlur.disableWhenWindowBehind = BlurConfig::fakeBlurDisableWhenWindowBehind(); + staticBlur.customImage = QImage(BlurConfig::fakeBlurImage()); if (BlurConfig::fakeBlurImageSourceDesktopWallpaper()) { - fakeBlur.imageSource = FakeBlurImageSource::DesktopWallpaper; + staticBlur.imageSource = StaticBlurImageSource::DesktopWallpaper; } else { - fakeBlur.imageSource = FakeBlurImageSource::Custom; + staticBlur.imageSource = StaticBlurImageSource::Custom; } - fakeBlur.blurCustomImage = BlurConfig::fakeBlurCustomImageBlur(); + staticBlur.blurCustomImage = BlurConfig::fakeBlurCustomImageBlur(); } } \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index 7d97fd39e..fa047780e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -6,7 +6,7 @@ namespace KWin { -enum class FakeBlurImageSource +enum class StaticBlurImageSource { Custom, DesktopWallpaper @@ -49,11 +49,11 @@ struct RoundedCornersSettings bool roundMaximized; }; -struct FakeBlurSettings +struct StaticBlurSettings { bool enable; bool disableWhenWindowBehind; - FakeBlurImageSource imageSource; + StaticBlurImageSource imageSource; QImage customImage; bool blurCustomImage; }; @@ -64,7 +64,7 @@ class BlurSettings GeneralSettings general{}; ForceBlurSettings forceBlur{}; RoundedCornersSettings roundedCorners{}; - FakeBlurSettings fakeBlur{}; + StaticBlurSettings staticBlur{}; void read(); }; From c7c71b46c194956bce8b044d5e3d11245d52f5e4 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:46:51 +0100 Subject: [PATCH 16/17] metadata: remove '(formerly Force Blur') from effect title --- README.md | 2 +- src/metadata.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8f8b69c08..ecfa6d77a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # KWin Better Blur [![AUR Version](https://img.shields.io/aur/version/kwin-effects-forceblur)](https://aur.archlinux.org/packages/kwin-effects-forceblur) -Better Blur (formerly kwin-effects-forceblur) is a fork the KWin Blur effect for KDE Plasma 6 with additional features and bug fixes. +Better Blur is a fork the KWin Blur effect for KDE Plasma 6 with additional features and bug fixes. ![image](https://github.com/taj-ny/kwin-effects-forceblur/assets/79316397/1078cf12-e6da-43c7-80b4-d90a8b0f3404) Window opacity has been set to 85% for System Settings, Dolphin and VSCodium, Firefox uses a transparent theme | [NixOS configuration](https://github.com/taj-ny/nix-config) diff --git a/src/metadata.json b/src/metadata.json index e85268a7b..e209ac721 100644 --- a/src/metadata.json +++ b/src/metadata.json @@ -12,7 +12,7 @@ "Description": "Fork of the KWin Blur effect for KDE Plasma 6 with force blur and more", "EnabledByDefault": false, "License": "GPL", - "Name": "Better Blur (formerly Force Blur)" + "Name": "Better Blur" }, "X-KDE-ConfigModule": "kwin_better_blur_config" } From 0736f9aef3715a7e76a8f9edd96adcfaed22e5b0 Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:54:58 +0100 Subject: [PATCH 17/17] static-blur: don't make window opaque when opacity affects blur --- src/blur.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/blur.cpp b/src/blur.cpp index 02a2f5874..8771028e9 100644 --- a/src/blur.cpp +++ b/src/blur.cpp @@ -538,7 +538,9 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:: bool staticBlur = hasStaticBlur(w) && m_staticBlurTextures.contains(m_currentScreen) && !blurArea.isEmpty(); if (staticBlur) { - data.opaque += blurArea; + if (!m_settings.general.windowOpacityAffectsBlur) { + data.opaque += blurArea; + } int topCornerRadius; int bottomCornerRadius;