Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Commit b9dd76a

Browse files
authored
Merge pull request #81 from taj-ny/develop
v1.3.0
2 parents b1a27bf + af0693d commit b9dd76a

14 files changed

Lines changed: 675 additions & 139 deletions

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.16.0)
22

33
project(forceblur)
4-
set(PROJECT_VERSION "1.2.1")
4+
set(PROJECT_VERSION "1.3.0")
55
set(PROJECT_VERSION_MAJOR 0)
66

77
set(KF_MIN_VERSION "5.240.0")

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
# kwin-effects-forceblur [![AUR Version](https://img.shields.io/aur/version/kwin-effects-forceblur)](https://aur.archlinux.org/packages/kwin-effects-forceblur)
2-
A fork of the KWin Blur effect for KDE Plasma 6 with the ability to blur any window on Wayland and X11.
2+
Kwin-effects-forceblur (name subject to change) is a fork of the KWin Blur effect for KDE Plasma 6 with several improvements and bug fixes.
33

44
Latest features are available on the ``develop`` branch.
55

6-
![image](https://github.com/taj-ny/kwin-effects-forceblur/assets/79316397/9d2f337e-badd-4d95-ba55-96c80202e196)
7-
<sup>Window opacity has been set to 85% for System Settings and Dolphin, Firefox uses a transparent theme | [NixOS configuration](https://github.com/taj-ny/nix-config)</sup>
6+
![image](https://github.com/taj-ny/kwin-effects-forceblur/assets/79316397/1078cf12-e6da-43c7-80b4-d90a8b0f3404)
7+
<sup>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)</sup>
88

99
# Features
1010
- Wayland support
11+
- Force blur
12+
- Rounded corners with optional anti-aliasing
1113
- Draw image behind windows instead of blurring (can be used with a blurred image of the wallpaper in order to achieve a very similar effect to blur but with **much** lower GPU usage)
12-
- Rounded corners
13-
- Fix for [artifacts](https://github.com/taj-ny/kwin-effects-forceblur/pull/38) when using a transparent color scheme
14+
15+
### Bug fixes
16+
Fixes for blur-related Plasma bugs that haven't been patched yet.
17+
18+
- Blur may sometimes disappear during animations
19+
- [Transparent color schemes don't work properly with the Breeze application style](https://github.com/taj-ny/kwin-effects-forceblur/pull/38)
1420

1521
# Installation
1622
<details>

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
stdenv.mkDerivation rec {
1111
pname = "kwin-effects-forceblur";
12-
version = "1.2.1";
12+
version = "1.3.0";
1313

1414
src = ./.;
1515

src/blur.cpp

Lines changed: 394 additions & 111 deletions
Large diffs are not rendered by default.

src/blur.h

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,27 @@ public Q_SLOTS:
7777

7878
private:
7979
void initBlurStrengthValues();
80-
QRegion blurRegion(EffectWindow *w, bool noRoundedCorners = false) const;
80+
QRegion blurRegion(EffectWindow *w) const;
8181
QRegion decorationBlurRegion(const EffectWindow *w) const;
82+
QRegion transformedBlurRegion(QRegion blurRegion, const WindowPaintData &data) const;
8283
bool decorationSupportsBlurBehind(const EffectWindow *w) const;
83-
bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const;
84+
bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data);
8485
bool shouldForceBlur(const EffectWindow *w) const;
8586
void updateBlurRegion(EffectWindow *w);
86-
void updateCornerRegions();
8787
void blur(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data);
8888
GLTexture *ensureNoiseTexture();
89-
bool hasFakeBlur(EffectWindow *w) const;
89+
90+
/*
91+
* @returns An array containing rounded corner masks for the given screen scale and radii. If no masks exist, they
92+
* will be generated.
93+
*/
94+
std::array<QRegion, 4> roundedCorners(int topCornerRadius, int bottomCornerRadius, qreal scale);
95+
96+
/*
97+
* Generates rounded corner masks for the left and right corner of the given radius.
98+
* @param top Whether the corners belong to the top part of the window.
99+
*/
100+
void generateRoundedCornerMasks(int radius, QRegion &left, QRegion &right, bool top) const;
90101

91102
private:
92103
struct
@@ -123,10 +134,33 @@ public Q_SLOTS:
123134
int mvpMatrixLocation;
124135
int textureSizeLocation;
125136
int texStartPosLocation;
137+
int regionSizeLocation;
126138

127139
std::unique_ptr<GLTexture> texture;
128140
} m_texturePass;
129141

142+
struct
143+
{
144+
std::unique_ptr<GLShader> shader;
145+
146+
int roundTopLeftCornerLocation;
147+
int roundTopRightCornerLocation;
148+
int roundBottomLeftCornerLocation;
149+
int roundBottomRightCornerLocation;
150+
151+
int topCornerRadiusLocation;
152+
int bottomCornerRadiusLocation;
153+
154+
int antialiasingLocation;
155+
156+
int regionSizeLocation;
157+
158+
int beforeBlurTextureLocation;
159+
int afterBlurTextureLocation;
160+
161+
int mvpMatrixLocation;
162+
} m_roundedCorners;
163+
130164
bool m_valid = false;
131165
long net_wm_blur_region = 0;
132166
QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top)
@@ -142,9 +176,6 @@ public Q_SLOTS:
142176
bool m_blurNonMatching;
143177
bool m_blurDecorations;
144178
bool m_transparentBlur;
145-
int m_topCornerRadius;
146-
int m_bottomCornerRadius;
147-
bool m_roundCornersOfMaximizedWindows;
148179
bool m_blurMenus;
149180
bool m_blurDocks;
150181
bool m_paintAsTranslucent;
@@ -153,11 +184,17 @@ public Q_SLOTS:
153184

154185
bool m_hasValidFakeBlurTexture;
155186

156-
// Regions to subtract from the blurred region
157-
QRegion m_topLeftCorner;
158-
QRegion m_topRightCorner;
159-
QRegion m_bottomLeftCorner;
160-
QRegion m_bottomRightCorner;
187+
int m_windowTopCornerRadius;
188+
int m_windowBottomCornerRadius;
189+
int m_menuCornerRadius;
190+
int m_dockCornerRadius;
191+
float m_roundedCornersAntialiasing;
192+
bool m_roundCornersOfMaximizedWindows;
193+
int m_cornerRadiusOffset;
194+
195+
// Corner masks where the key is the screen scale and the value is an array of the masks
196+
// (top left, top right, bottom left, bottom right). Used for rounding the blur region.
197+
std::map<const std::tuple<int, int, qreal>, std::array<QRegion, 4>> m_corners;
161198

162199
struct OffsetStruct
163200
{
@@ -176,6 +213,9 @@ public Q_SLOTS:
176213

177214
QList<BlurValuesStruct> blurStrengthValues;
178215

216+
// Windows to blur even when transformed.
217+
QList<const EffectWindow*> m_blurWhenTransformed;
218+
179219
QMap<EffectWindow *, QMetaObject::Connection> windowBlurChangedConnections;
180220
QMap<EffectWindow *, QMetaObject::Connection> windowExpandedGeometryChangedConnections;
181221
std::unordered_map<EffectWindow *, BlurEffectData> m_windows;

src/blur.kcfg

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ class3</default>
3434
<entry name="BottomCornerRadius" type="Int">
3535
<default>0</default>
3636
</entry>
37+
<entry name="MenuCornerRadius" type="Int">
38+
<default>0</default>
39+
</entry>
40+
<entry name="DockCornerRadius" type="Int">
41+
<default>0</default>
42+
</entry>
43+
<entry name="RoundedCornersAntialiasing" type="Double">
44+
<default>1.0</default>
45+
</entry>
3746
<entry name="RoundCornersOfMaximizedWindows" type="Bool">
3847
<default>false</default>
3948
</entry>

src/blur.qrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<file>shaders/downsample_core.frag</file>
55
<file>shaders/noise.frag</file>
66
<file>shaders/noise_core.frag</file>
7+
<file>shaders/roundedcorners.frag</file>
8+
<file>shaders/roundedcorners_core.frag</file>
79
<file>shaders/texture.frag</file>
810
<file>shaders/texture_core.frag</file>
911
<file>shaders/upsample.frag</file>

src/kcm/blur_config.ui

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@
321321
<item>
322322
<widget class="QLabel">
323323
<property name="text">
324-
<string>Top corner radius</string>
324+
<string>Window top corner radius</string>
325325
</property>
326326
</widget>
327327
</item>
@@ -339,7 +339,7 @@
339339
<item>
340340
<widget class="QLabel">
341341
<property name="text">
342-
<string>Bottom corner radius</string>
342+
<string>Window bottom corner radius</string>
343343
</property>
344344
</widget>
345345
</item>
@@ -352,6 +352,60 @@
352352
</item>
353353
</layout>
354354
</item>
355+
<item>
356+
<layout class="QHBoxLayout">
357+
<item>
358+
<widget class="QLabel">
359+
<property name="text">
360+
<string>Menu corner radius</string>
361+
</property>
362+
</widget>
363+
</item>
364+
<item>
365+
<widget class="QSpinBox" name="kcfg_MenuCornerRadius">
366+
<property name="minimum">
367+
<number>0</number>
368+
</property>
369+
</widget>
370+
</item>
371+
</layout>
372+
</item>
373+
<item>
374+
<layout class="QHBoxLayout">
375+
<item>
376+
<widget class="QLabel">
377+
<property name="text">
378+
<string>Dock corner radius</string>
379+
</property>
380+
</widget>
381+
</item>
382+
<item>
383+
<widget class="QSpinBox" name="kcfg_DockCornerRadius">
384+
<property name="minimum">
385+
<number>0</number>
386+
</property>
387+
</widget>
388+
</item>
389+
</layout>
390+
</item>
391+
<item>
392+
<layout class="QHBoxLayout">
393+
<item>
394+
<widget class="QLabel">
395+
<property name="text">
396+
<string>Anti-aliasing</string>
397+
</property>
398+
</widget>
399+
</item>
400+
<item>
401+
<widget class="QDoubleSpinBox" name="kcfg_RoundedCornersAntialiasing">
402+
<property name="minimum">
403+
<number>0</number>
404+
</property>
405+
</widget>
406+
</item>
407+
</layout>
408+
</item>
355409
<item>
356410
<widget class="QCheckBox" name="kcfg_RoundCornersOfMaximizedWindows">
357411
<property name="text">

src/shaders/roundedcorners.frag

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Modified version of https://www.shadertoy.com/view/ldfSDj
2+
3+
uniform bool roundTopLeftCorner;
4+
uniform bool roundTopRightCorner;
5+
uniform bool roundBottomLeftCorner;
6+
uniform bool roundBottomRightCorner;
7+
8+
uniform int topCornerRadius;
9+
uniform int bottomCornerRadius;
10+
11+
uniform float antialiasing;
12+
13+
uniform vec2 regionSize;
14+
15+
uniform sampler2D beforeBlurTexture;
16+
uniform sampler2D afterBlurTexture;
17+
18+
varying vec2 uv;
19+
20+
float udRoundBox(vec2 p, vec2 b, vec2 fragCoord)
21+
{
22+
float radius = 0.0;
23+
if ((fragCoord.y <= topCornerRadius)
24+
&& ((roundTopLeftCorner && fragCoord.x <= topCornerRadius)
25+
|| (roundTopRightCorner && fragCoord.x >= regionSize.x - topCornerRadius))) {
26+
radius = topCornerRadius;
27+
p.y -= radius;
28+
} else if ((fragCoord.y >= regionSize.y - bottomCornerRadius)
29+
&& ((roundBottomLeftCorner && fragCoord.x <= bottomCornerRadius)
30+
|| (roundBottomRightCorner && fragCoord.x >= regionSize.x - bottomCornerRadius))) {
31+
radius = bottomCornerRadius;
32+
p.y += radius;
33+
}
34+
35+
return length(max(abs(p) - (b + vec2(0.0, radius)) + radius, 0.0)) - radius;
36+
}
37+
38+
void main(void)
39+
{
40+
vec2 halfRegionSize = regionSize * 0.5;
41+
vec2 fragCoord = uv * regionSize;
42+
float box = udRoundBox(fragCoord - halfRegionSize, halfRegionSize, fragCoord);
43+
44+
// If antialiasing is 0, the shader will be used to generate corner masks.
45+
vec3 foreground = vec3(1.0, 1.0, 1.0);
46+
vec3 background = vec3(0.0, 0.0, 0.0);
47+
if (antialiasing > 0.0) {
48+
foreground = texture2D(afterBlurTexture, uv).rgb;
49+
background = texture2D(beforeBlurTexture, uv).rgb;
50+
}
51+
52+
gl_FragColor = vec4(mix(foreground, background, smoothstep(0.0, antialiasing, box)), 1.0);
53+
}

0 commit comments

Comments
 (0)