Skip to content

gtk: various blur-related fixes #10727

Open
pluiedev wants to merge 7 commits intoghostty-org:mainfrom
pluiedev:pluie/jj-kknnrxwtxqzx
Open

gtk: various blur-related fixes #10727
pluiedev wants to merge 7 commits intoghostty-org:mainfrom
pluiedev:pluie/jj-kknnrxwtxqzx

Conversation

@pluiedev
Copy link
Member

@pluiedev pluiedev commented Feb 15, 2026

Fixes #10721
Fixes #10720

I recommend reviewing this per-commit as there's a lot of refactoring to go over. I do want to fix the "korner bug" but that would require a bit more reading on my part.

This hasn't been tested on X11. If you're able, please see if this still works on KWin X11. I'm currently in the countryside celebrating Chinese New Year, and I'm not really in the mood of downloading half a gig worth of KDE libraries x)

Since both X11 and Wayland need to keep track of the actual size of the
blur region, I've taken the liberty to extract that piece of code into
our common winproto structure. Works just fine.

Part of ghostty-org#10720
@pluiedev pluiedev requested a review from a team as a code owner February 15, 2026 19:43
@pluiedev pluiedev force-pushed the pluie/jj-kknnrxwtxqzx branch from d728922 to a9f4c28 Compare February 15, 2026 20:03
@pluiedev
Copy link
Member Author

pluiedev commented Feb 16, 2026

So trying to find a satisfactory way to implement rounded corners actually drove me somewhat insane. I had to jerry-rig my own cursed nested-Niri white-noise-backed test setup in order to determine exactly where the blur regions are.
This is the best that I've been able to get - while this looks OK with a solid border, it is by no means perfect. Note that this is extremely blown up (at 3x scaling on the Niri side) and at normal scaling this isn't really noticable.

Image

@YaLTeR thoughts? :P

1.5x scale for comparison:
image

And with a solid border (the color doesn't really matter)

1.5x:
image

3x:
image

@YaLTeR
Copy link

YaLTeR commented Feb 16, 2026

Yeah it's probably fine. Unfortunately due to ext-bg-effect region being in surface-local integer coordinates, the precision does not increase with the scale factor, but that's the best we can do with the current protocols (I think).

FYI in niri you can set

blur {
    saturation 10
}

to make it obvious. But yeah, in normal scenarios it is much less noticeable.

I tried the current code in this PR but I guess it doesn't do corners yet.

Also, I see on the current PR that the region starts from the top-left of the geometry, but it should probably start from the terminal widget, since the headerbar is opaque anyway:

image

@pluiedev
Copy link
Member Author

Applying it just to the terminal widget is unfortunately really, really complicated. GTK 4 doesn't allow you to get the absolute position of a widget AFAICT, only relative to the parent widget, so you have to manually compute the offsets yourself. Our widget tree is really quite complicated so that isn't really feasible... The simplest way would be to just apply the blur to the entire window, even if it's somewhat wasteful on the compositor side

@pluiedev pluiedev force-pushed the pluie/jj-kknnrxwtxqzx branch from 0da3904 to 5f637d2 Compare February 16, 2026 11:27
@pluiedev pluiedev force-pushed the pluie/jj-kknnrxwtxqzx branch from 5f637d2 to 254b38b Compare February 16, 2026 11:29
@pluiedev
Copy link
Member Author

Refined the rounding logic a bit more and this is fully ready on the Wayland side. Still have no way to test on X11.

@YaLTeR
Copy link

YaLTeR commented Feb 16, 2026

At 3x scale pixels start visibly peeking out, perhaps some pixel offset isn't scaled properly?

image

@YaLTeR
Copy link

YaLTeR commented Feb 16, 2026

Ah, actually it's the same at 1x:

image

I'd add 1-2 px of offset

@YaLTeR
Copy link

YaLTeR commented Feb 16, 2026

Also idk if this is relevant but quitting Ghostty results in a bunch of leak reports:

error(gpa): memory address 0x7f83490dc800 leaked:
/usr/lib/zig/std/array_list.zig:1231:56: 0x30be2d4 in ensureTotalCapacityPrecise (ghostty)
                const new_memory = try gpa.alignedAlloc(T, alignment, new_capacity);
                                                       ^
/usr/lib/zig/std/array_list.zig:1207:51: 0x307c93c in ensureTotalCapacity (ghostty)
            return self.ensureTotalCapacityPrecise(gpa, growCapacity(self.capacity, new_capacity));
                                                  ^
/usr/lib/zig/std/array_list.zig:1261:41: 0x3031154 in addOne (ghostty)
            try self.ensureTotalCapacity(gpa, newlen);
                                        ^
/usr/lib/zig/std/array_list.zig:894:49: 0x2fc287a in append (ghostty)
            const new_item_ptr = try self.addOne(gpa);
                                                ^
/var/home/yalter/source/zig/ghostty/src/apprt/gtk/winproto/blur.zig:133:30: 0x2f2d584 in approxRoundedRect (ghostty)
            try slices.append(alloc, .{
                             ^
/var/home/yalter/source/zig/ghostty/src/apprt/gtk/winproto/blur.zig:67:44: 0x2ed1e5a in calcForWindow (ghostty)
            .slices = try approxRoundedRect(
                                           ^

@pluiedev
Copy link
Member Author

Ah looks like I forgot to deinit some of these. Shucks

Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approve, just my one comment.

.wayland_protocols = .{
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
.hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
.url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Freedesktop has terrible reliability, so when this is good to go let me know and I'll fix this before we merge.

I approve otherwise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea to push the zip to S3 in any case since the ext-bg-effect commit will likely be merged regardless of the other two

@YaLTeR
Copy link

YaLTeR commented Feb 19, 2026

Thanks, this looks much better. Though I suspect you may have added an extra 1 px of padding now:

image

@YaLTeR
Copy link

YaLTeR commented Feb 19, 2026

And another thing: when the window is in a maximized or tiled state, the corners aren't rounded:

image

(in CSS this is defined here I believe)

(yeah, this should really be handled in GTK itself at some point...)

@pluiedev
Copy link
Member Author

GTK implementing something that will never land in GNOME? Imagine that! If that happened half of the Wayland winproto implementation straight up wouldn't need to exist!

...Aaanyway, I thought I could be a bit clever and simply read the --window-radius CSS variable GTK sets for itself. Turns out one does not simply read CSS variables in GTK. Bummer. Now I gotta reimplement that logic myself.

@YaLTeR
Copy link

YaLTeR commented Feb 19, 2026

GTK implementing something that will never land in GNOME?

I wouldn't assume that background effects would never land in GNOME

@pluiedev
Copy link
Member Author

Right, but before that happens I shall lean more on the pessimistic side :p I'll work on more specific criteria for disabling rounded corners now. Thanks for testing this too btw!

In an ideal world one can simply read what --window-radius is set to
within libadwaita. Unfortunately, we do not live in that world.
@pluiedev
Copy link
Member Author

As for the transparent "border", I believe that's actually the box shadow that libadwaita applies globally, so I don't think we should change any of it. Comes with the territory.

@YaLTeR
Copy link

YaLTeR commented Feb 19, 2026

Thanks, looks good now!

@pluiedev
Copy link
Member Author

pluiedev commented Feb 19, 2026

Excellent! I'm testing this on Plasma X11 right now and yeah, this is about what I expected - for some reason the secret KDE atoms defining blur regions are specified in device/physical pixels instead of logical/surface pixels, so if you run this branch on 2x scaling, only one quarter of the area would be blurred... More reasons to hate developing for (or rather in this case against) X11.

image

@pluiedev
Copy link
Member Author

image

... Why is Plasma Wayland having problems as well...?

@YaLTeR I think there's genuinely an issue here. I suspect that the KDE blur protocol implemented by KWin assumes device coordinates sans the CSD padding, while the impl in Niri assumes surface coordinates with the CSD padding (aka same semantics as ext-bg-effect). As there's pretty much no "real" specification of the KDE blur protocol I would probably recommend aligning Niri's impl to be the same as KDE's so that existing apps at least render correctly. Right now this PR looks correct under Niri but is terribly wrong under KDE.

@YaLTeR
Copy link

YaLTeR commented Feb 19, 2026

But the latest KDE code is exactly the same between ext-background-effect and KDE blur?

https://invent.kde.org/plasma/kwin/-/blob/f3a4d9630662e325bc22047a3c1a3fda6ddd17a1/src/wayland/backgroundeffect_v1.cpp#L109-115

https://invent.kde.org/plasma/kwin/-/commit/7f9e0aa1cd2c2ab4fea1097800893b6f780089eb#5b56b3256a35f6b7844ddb50958917fa13fd345d_99_0

Actually, seems the KDE blur protocol got axed from KDE, so maybe I need to reconsider implementing it in niri

@pluiedev
Copy link
Member Author

Interesting... Is this part of any current Plasma release? If they're removing the custom protocol anyways, I think it's a better idea to keep the original behavior just for the old protocol so people on older Plasma/KWin versions will enjoy the same behavior, while Niri users and people using more recent Plasma releases can get the benefits of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GTK/Wayland: Use the ext-background-effects-v1 protocol for background blur GTK/Wayland: Explicitly cull CSD borders from background blur region

3 participants

Comments