Skip to content

Commit a9f4c28

Browse files
committed
gtk/wayland: support the ext-background-effect-v1 protocol
Fixes #10721
1 parent c232ace commit a9f4c28

File tree

8 files changed

+98
-33
lines changed

8 files changed

+98
-33
lines changed

build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@
9191
.lazy = true,
9292
},
9393
.wayland_protocols = .{
94-
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
95-
.hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
94+
.url = "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz",
95+
.hash = "N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA",
9696
.lazy = true,
9797
},
9898
.plasma_wayland_protocols = .{

build.zig.zon.json

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

build.zig.zon.nix

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

build.zig.zon.txt

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

flatpak/zig-packages.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@
167167
"dest": "vendor/p/N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
168168
"sha256": "5cedcadde81b75e60f23e5e83b5dd2b8eb4efb9f8f79bd7a347d148aeb0530f8"
169169
},
170+
{
171+
"type": "archive",
172+
"url": "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/1.47/wayland-protocols-1.47.tar.gz",
173+
"dest": "vendor/p/N-V-__8AAFdWDwA0ktbNUi9pFBHCRN4weXIgIfCrVjfGxqgA",
174+
"sha256": "dd2df14ab5f41038257aaedcc4b5fb9ac0ee018f3f0f94af9097028e60d33223"
175+
},
170176
{
171177
"type": "archive",
172178
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",

src/apprt/gtk/winproto/blur.zig

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,12 @@ pub const Region = struct {
6262
width = @max(0, width - x * 2);
6363
height = @max(0, height - y * 2);
6464

65-
// Transform surface coordinates to device coordinates.
66-
const scale: f64 = @floatFromInt(surface.getScaleFactor());
67-
6865
// TODO: Add more regions to mitigate the "korners bug".
6966
try slices.append(alloc, .{
70-
.x = @intFromFloat(x * scale),
71-
.y = @intFromFloat(y * scale),
72-
.width = @intFromFloat(width * scale),
73-
.height = @intFromFloat(height * scale),
67+
.x = @intFromFloat(x),
68+
.y = @intFromFloat(y),
69+
.width = @intFromFloat(width),
70+
.height = @intFromFloat(height),
7471
});
7572

7673
return .{

src/apprt/gtk/winproto/wayland.zig

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const blur = @import("blur.zig");
1717
const wl = wayland.client.wl;
1818
const org = wayland.client.org;
1919
const xdg = wayland.client.xdg;
20+
const ext = wayland.client.ext;
2021

2122
const log = std.log.scoped(.winproto_wayland);
2223

@@ -30,6 +31,9 @@ pub const App = struct {
3031

3132
kde_blur_manager: ?*org.KdeKwinBlurManager = null,
3233

34+
ext_bg_effect_manager: ?*ext.BackgroundEffectManagerV1 = null,
35+
ext_bg_capabilities: ext.BackgroundEffectManagerV1.Capability = .{},
36+
3337
// FIXME: replace with `zxdg_decoration_v1` once GTK merges
3438
// https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6398
3539
kde_decoration_manager: ?*org.KdeKwinServerDecorationManager = null,
@@ -86,9 +90,19 @@ pub const App = struct {
8690
registry.setListener(*Context, registryListener, context);
8791
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
8892

89-
// Do another round-trip to get the default decoration mode
93+
// Sometimes we need to do another roundtrip
94+
// to get all information we need.
95+
var needs_roundtrip = false;
9096
if (context.kde_decoration_manager) |deco_manager| {
9197
deco_manager.setListener(*Context, decoManagerListener, context);
98+
needs_roundtrip = true;
99+
}
100+
if (context.ext_bg_effect_manager) |mgr| {
101+
mgr.setListener(*Context, effectManagerListener, context);
102+
needs_roundtrip = true;
103+
}
104+
105+
if (needs_roundtrip) {
92106
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
93107
}
94108

@@ -224,6 +238,18 @@ pub const App = struct {
224238
},
225239
}
226240
}
241+
242+
fn effectManagerListener(
243+
_: *ext.BackgroundEffectManagerV1,
244+
event: ext.BackgroundEffectManagerV1.Event,
245+
context: *Context,
246+
) void {
247+
switch (event) {
248+
.capabilities => |cap| {
249+
context.ext_bg_capabilities = cap.flags;
250+
},
251+
}
252+
}
227253
};
228254

229255
/// Per-window (wl_surface) state for the Wayland protocol.
@@ -239,6 +265,9 @@ pub const Window = struct {
239265
/// A token that, when present, indicates that the window is blurred.
240266
blur_token: ?*org.KdeKwinBlur = null,
241267

268+
/// Object that controls background effects like blur.
269+
bg_effect: ?*ext.BackgroundEffectSurfaceV1 = null,
270+
242271
/// Object that controls the decoration mode (client/server/auto)
243272
/// of the window.
244273
decoration: ?*org.KdeKwinServerDecoration = null,
@@ -362,38 +391,55 @@ pub const Window = struct {
362391
/// Update the blur state of the window.
363392
pub fn setBlur(self: *Window, region: blur.Region) !void {
364393
const compositor = self.app_context.compositor orelse return;
365-
const manager = self.app_context.kde_blur_manager orelse return;
366394

367395
const config = if (self.apprt_window.getConfig()) |v|
368396
v.get()
369397
else
370398
return;
371399
const blur_setting = config.@"background-blur";
372400

373-
if (blur_setting.enabled()) {
374-
// Do we already have a blur token? If not, create one.
375-
const token = self.blur_token orelse try manager.create(self.surface);
376-
defer self.blur_token = token;
377-
378-
const wl_region = try compositor.createRegion();
379-
errdefer wl_region.destroy();
380-
381-
for (region.slices.items) |slice| {
382-
// X11 coming over to bite Wayland.
383-
wl_region.add(
384-
@intCast(slice.x),
385-
@intCast(slice.y),
386-
@intCast(slice.width),
387-
@intCast(slice.height),
388-
);
401+
const wl_region = try compositor.createRegion();
402+
errdefer wl_region.destroy();
403+
404+
for (region.slices.items) |slice| {
405+
// X11 coming over to bite Wayland.
406+
wl_region.add(
407+
@intCast(slice.x),
408+
@intCast(slice.y),
409+
@intCast(slice.width),
410+
@intCast(slice.height),
411+
);
412+
}
413+
414+
// Does the compositor support the `ext-background-effect-v1`
415+
// protocol? If so, try that first, though it might not actually
416+
// support the blur setting.
417+
if (self.app_context.ext_bg_effect_manager) |mgr| fx: {
418+
if (!self.app_context.ext_bg_capabilities.blur) break :fx;
419+
420+
if (blur_setting.enabled()) {
421+
// Do we already have a blur token? If not, create one.
422+
const effect = self.bg_effect orelse try mgr.getBackgroundEffect(self.surface);
423+
defer self.bg_effect = effect;
424+
effect.setBlurRegion(wl_region);
425+
} else if (self.bg_effect) |effect| {
426+
// Destroy the blur token if present.
427+
effect.destroy();
428+
self.bg_effect = null;
389429
}
430+
return;
431+
}
390432

391-
token.setRegion(wl_region);
392-
token.commit();
393-
} else {
394-
// Destroy the blur token if present.
395-
if (self.blur_token) |token| {
396-
manager.unset(self.surface);
433+
if (self.app_context.kde_blur_manager) |mgr| {
434+
if (blur_setting.enabled()) {
435+
// Do we already have a blur token? If not, create one.
436+
const token = self.blur_token orelse try mgr.create(self.surface);
437+
defer self.blur_token = token;
438+
token.setRegion(wl_region);
439+
token.commit();
440+
} else if (self.blur_token) |token| {
441+
// Destroy the blur token if present.
442+
mgr.unset(self.surface);
397443
token.release();
398444
self.blur_token = null;
399445
}

src/build/SharedDeps.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,14 @@ fn addGtkNg(
635635
plasma_wayland_protocols_dep.path("src/protocols/slide.xml"),
636636
);
637637
scanner.addSystemProtocol("staging/xdg-activation/xdg-activation-v1.xml");
638+
scanner.addSystemProtocol("staging/ext-background-effect/ext-background-effect-v1.xml");
638639

639640
scanner.generate("wl_compositor", 1);
640641
scanner.generate("org_kde_kwin_blur_manager", 1);
641642
scanner.generate("org_kde_kwin_server_decoration_manager", 1);
642643
scanner.generate("org_kde_kwin_slide_manager", 1);
643644
scanner.generate("xdg_activation_v1", 1);
645+
scanner.generate("ext_background_effect_manager_v1", 1);
644646

645647
step.root_module.addImport("wayland", b.createModule(.{
646648
.root_source_file = scanner.result,

0 commit comments

Comments
 (0)