config: allow booleans for background-blur-radius

This commit is contained in:
Leah Amelia Chen
2025-01-04 14:11:35 +08:00
committed by Mitchell Hashimoto
parent cd90821b93
commit f2c357a209
5 changed files with 127 additions and 13 deletions

View File

@ -1953,7 +1953,7 @@ pub const CAPI = struct {
_ = CGSSetWindowBackgroundBlurRadius( _ = CGSSetWindowBackgroundBlurRadius(
CGSDefaultConnectionForThread(), CGSDefaultConnectionForThread(),
nswindow.msgSend(usize, objc.sel("windowNumber"), .{}), nswindow.msgSend(usize, objc.sel("windowNumber"), .{}),
@intCast(config.@"background-blur-radius"), @intCast(config.@"background-blur-radius".cval()),
); );
} }

View File

@ -400,7 +400,12 @@ pub fn syncAppearance(self: *Window, config: *const configpkg.Config) !void {
} }
if (self.wayland) |*wl| { if (self.wayland) |*wl| {
try wl.setBlur(config.@"background-blur-radius" > 0); const blurred = switch (config.@"background-blur-radius") {
.false => false,
.true => true,
.value => |v| v > 0,
};
try wl.setBlur(blurred);
} }
} }

View File

@ -533,7 +533,7 @@ fn parsePackedStruct(comptime T: type, v: []const u8) !T {
return result; return result;
} }
fn parseBool(v: []const u8) !bool { pub fn parseBool(v: []const u8) !bool {
const t = &[_][]const u8{ "1", "t", "T", "true" }; const t = &[_][]const u8{ "1", "t", "T", "true" };
const f = &[_][]const u8{ "0", "f", "F", "false" }; const f = &[_][]const u8{ "0", "f", "F", "false" };

View File

@ -582,29 +582,38 @@ palette: Palette = .{},
/// On macOS, changing this configuration requires restarting Ghostty completely. /// On macOS, changing this configuration requires restarting Ghostty completely.
@"background-opacity": f64 = 1.0, @"background-opacity": f64 = 1.0,
/// A positive value enables blurring of the background when background-opacity /// Whether to blur the background when `background-opacity` is less than 1.
/// is less than 1.
/// ///
/// On macOS, the value is the blur radius to apply. A value of 20 /// Valid values are:
/// is reasonable for a good looking blur. Higher values will cause strange
/// rendering issues as well as performance issues.
/// ///
/// On KDE Plasma under Wayland, the exact value is _ignored_ the reason is /// * a nonnegative integer specifying the *blur intensity*
/// that KWin, the window compositor powering Plasma, only has one global blur /// * `false`, equivalent to a blur intensity of 0
/// setting and does not allow applications to have individual blur settings. /// * `true`, equivalent to the default blur intensity of 20, which is
/// reasonable for a good looking blur. Higher blur intensities may
/// cause strange rendering and performance issues.
///
/// Supported on macOS and on some Linux desktop environments, including:
///
/// * KDE Plasma (Wayland only)
///
/// Warning: the exact blur intensity is _ignored_ under KDE Plasma, and setting
/// this setting to either `true` or any positive blur intensity value would
/// achieve the same effect. The reason is that KWin, the window compositor
/// powering Plasma, only has one global blur setting and does not allow
/// applications to specify individual blur settings.
/// ///
/// To configure KWin's global blur setting, open System Settings and go to /// To configure KWin's global blur setting, open System Settings and go to
/// "Apps & Windows" > "Window Management" > "Desktop Effects" and select the /// "Apps & Windows" > "Window Management" > "Desktop Effects" and select the
/// "Blur" plugin. If disabled, enable it by ticking the checkbox to the left. /// "Blur" plugin. If disabled, enable it by ticking the checkbox to the left.
/// Then click on the "Configure" button and there will be two sliders that /// Then click on the "Configure" button and there will be two sliders that
/// allow you to set background blur and noise strengths for all apps, /// allow you to set background blur and noise intensities for all apps,
/// including Ghostty. /// including Ghostty.
/// ///
/// All other Linux desktop environments are as of now unsupported. Users may /// All other Linux desktop environments are as of now unsupported. Users may
/// need to set environment-specific settings and/or install third-party plugins /// need to set environment-specific settings and/or install third-party plugins
/// in order to support background blur, as there isn't a unified interface for /// in order to support background blur, as there isn't a unified interface for
/// doing so. /// doing so.
@"background-blur-radius": u8 = 0, @"background-blur-radius": BackgroundBlur = .false,
/// The opacity level (opposite of transparency) of an unfocused split. /// The opacity level (opposite of transparency) of an unfocused split.
/// Unfocused splits by default are slightly faded out to make it easier to see /// Unfocused splits by default are slightly faded out to make it easier to see
@ -5653,6 +5662,68 @@ pub const AutoUpdate = enum {
download, download,
}; };
/// See background-blur-radius
pub const BackgroundBlur = union(enum) {
false,
true,
value: u8,
pub fn parseCLI(self: *BackgroundBlur, input: ?[]const u8) !void {
const input_ = input orelse {
// Emulate behavior for bools
self.* = .true;
return;
};
if (cli.args.parseBool(input_)) |b| {
self.* = if (b) .true else .false;
} else |_| {
const value = std.fmt.parseInt(u8, input_, 0) catch return error.InvalidValue;
self.* = .{ .value = value };
}
}
pub fn cval(self: BackgroundBlur) u8 {
return switch (self) {
.false => 0,
.true => 20,
.value => |v| v,
};
}
pub fn formatEntry(
self: BackgroundBlur,
formatter: anytype,
) !void {
switch (self) {
.false => try formatter.formatEntry(bool, false),
.true => try formatter.formatEntry(bool, true),
.value => |v| try formatter.formatEntry(u8, v),
}
}
test "parse BackgroundBlur" {
const testing = std.testing;
var v: BackgroundBlur = undefined;
try v.parseCLI(null);
try testing.expectEqual(.true, v);
try v.parseCLI("true");
try testing.expectEqual(.true, v);
try v.parseCLI("false");
try testing.expectEqual(.false, v);
try v.parseCLI("42");
try testing.expectEqual(42, v.value);
try testing.expectError(error.InvalidValue, v.parseCLI(""));
try testing.expectError(error.InvalidValue, v.parseCLI("aaaa"));
try testing.expectError(error.InvalidValue, v.parseCLI("420"));
}
};
/// See theme /// See theme
pub const Theme = struct { pub const Theme = struct {
light: []const u8, light: []const u8,

View File

@ -84,6 +84,17 @@ fn getValue(ptr_raw: *anyopaque, value: anytype) bool {
ptr.* = @intCast(@as(Backing, @bitCast(value))); ptr.* = @intCast(@as(Backing, @bitCast(value)));
}, },
.Union => |_| {
if (@hasDecl(T, "cval")) {
const PtrT = @typeInfo(@TypeOf(T.cval)).Fn.return_type.?;
const ptr: *PtrT = @ptrCast(@alignCast(ptr_raw));
ptr.* = value.cval();
return true;
}
return false;
},
else => return false, else => return false,
}, },
} }
@ -172,3 +183,30 @@ test "c_get: optional" {
try testing.expectEqual(0, cval.b); try testing.expectEqual(0, cval.b);
} }
} }
test "c_get: background-blur" {
const testing = std.testing;
const alloc = testing.allocator;
var c = try Config.default(alloc);
defer c.deinit();
{
c.@"background-blur-radius" = .false;
var cval: u8 = undefined;
try testing.expect(get(&c, .@"background-blur-radius", @ptrCast(&cval)));
try testing.expectEqual(0, cval);
}
{
c.@"background-blur-radius" = .true;
var cval: u8 = undefined;
try testing.expect(get(&c, .@"background-blur-radius", @ptrCast(&cval)));
try testing.expectEqual(20, cval);
}
{
c.@"background-blur-radius" = .{ .value = 42 };
var cval: u8 = undefined;
try testing.expect(get(&c, .@"background-blur-radius", @ptrCast(&cval)));
try testing.expectEqual(42, cval);
}
}