mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-16 00:08:23 +00:00
config: make unfocused-split-fill default to bg
This commit is contained in:
@@ -67,7 +67,10 @@ extension Ghostty {
|
|||||||
private var unfocusedFill: Color {
|
private var unfocusedFill: Color {
|
||||||
var rgb: UInt32 = 16777215 // white default
|
var rgb: UInt32 = 16777215 // white default
|
||||||
let key = "unfocused-split-fill"
|
let key = "unfocused-split-fill"
|
||||||
_ = ghostty_config_get(ghostty.config, &rgb, key, UInt(key.count))
|
if (!ghostty_config_get(ghostty.config, &rgb, key, UInt(key.count))) {
|
||||||
|
let bg_key = "background"
|
||||||
|
_ = ghostty_config_get(ghostty.config, &rgb, bg_key, UInt(bg_key.count));
|
||||||
|
}
|
||||||
|
|
||||||
let red = Double(rgb & 0xff)
|
let red = Double(rgb & 0xff)
|
||||||
let green = Double((rgb >> 8) & 0xff)
|
let green = Double((rgb >> 8) & 0xff)
|
||||||
|
@@ -312,13 +312,15 @@ palette: Palette = .{},
|
|||||||
/// minimum value is 0.15. This value still looks weird but you can at least
|
/// minimum value is 0.15. This value still looks weird but you can at least
|
||||||
/// see what's going on. A value outside of the range 0.15 to 1 will be
|
/// see what's going on. A value outside of the range 0.15 to 1 will be
|
||||||
/// clamped to the nearest valid value.
|
/// clamped to the nearest valid value.
|
||||||
@"unfocused-split-opacity": f64 = 0.85,
|
@"unfocused-split-opacity": f64 = 0.7,
|
||||||
|
|
||||||
// The color to dim the unfocused split. Unfocused splits are dimmed by
|
// The color to dim the unfocused split. Unfocused splits are dimmed by
|
||||||
// rendering a semi-transparent rectangle over the split. This sets
|
// rendering a semi-transparent rectangle over the split. This sets
|
||||||
// the color of that rectangle and can be used to carefully control
|
// the color of that rectangle and can be used to carefully control
|
||||||
// the dimming effect.
|
// the dimming effect.
|
||||||
@"unfocused-split-fill": Color = .{ .r = 255, .g = 255, .b = 255 },
|
//
|
||||||
|
// This will default to the background color.
|
||||||
|
@"unfocused-split-fill": ?Color = null,
|
||||||
|
|
||||||
/// The command to run, usually a shell. If this is not an absolute path,
|
/// The command to run, usually a shell. If this is not an absolute path,
|
||||||
/// it'll be looked up in the PATH. If this is not set, a default will
|
/// it'll be looked up in the PATH. If this is not set, a default will
|
||||||
|
@@ -18,54 +18,66 @@ pub fn get(config: *const Config, k: Key, ptr_raw: *anyopaque) bool {
|
|||||||
switch (k) {
|
switch (k) {
|
||||||
inline else => |tag| {
|
inline else => |tag| {
|
||||||
const value = fieldByKey(config, tag);
|
const value = fieldByKey(config, tag);
|
||||||
switch (@TypeOf(value)) {
|
return getValue(ptr_raw, value);
|
||||||
?[:0]const u8 => {
|
|
||||||
const ptr: *?[*:0]const u8 = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = if (value) |slice| @ptrCast(slice.ptr) else null;
|
|
||||||
},
|
|
||||||
|
|
||||||
bool => {
|
|
||||||
const ptr: *bool = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = value;
|
|
||||||
},
|
|
||||||
|
|
||||||
u8, u32 => {
|
|
||||||
const ptr: *c_uint = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = @intCast(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
f32, f64 => {
|
|
||||||
const ptr: *f64 = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = @floatCast(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
else => |T| switch (@typeInfo(T)) {
|
|
||||||
.Enum => {
|
|
||||||
const ptr: *[*:0]const u8 = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = @tagName(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
.Struct => |info| {
|
|
||||||
// Packed structs that are less than or equal to the
|
|
||||||
// size of a C int can be passed directly as their
|
|
||||||
// bit representation.
|
|
||||||
if (info.layout != .Packed) return false;
|
|
||||||
const Backing = info.backing_integer orelse return false;
|
|
||||||
if (@bitSizeOf(Backing) > @bitSizeOf(c_uint)) return false;
|
|
||||||
|
|
||||||
const ptr: *c_uint = @ptrCast(@alignCast(ptr_raw));
|
|
||||||
ptr.* = @intCast(@as(Backing, @bitCast(value)));
|
|
||||||
},
|
|
||||||
|
|
||||||
else => return false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the value anytype and put it into the pointer. Returns false if
|
||||||
|
/// the type is not supported by the C API yet or the value is null.
|
||||||
|
fn getValue(ptr_raw: *anyopaque, value: anytype) bool {
|
||||||
|
switch (@TypeOf(value)) {
|
||||||
|
?[:0]const u8 => {
|
||||||
|
const ptr: *?[*:0]const u8 = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = if (value) |slice| @ptrCast(slice.ptr) else null;
|
||||||
|
},
|
||||||
|
|
||||||
|
bool => {
|
||||||
|
const ptr: *bool = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
u8, u32 => {
|
||||||
|
const ptr: *c_uint = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = @intCast(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
f32, f64 => {
|
||||||
|
const ptr: *f64 = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = @floatCast(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
else => |T| switch (@typeInfo(T)) {
|
||||||
|
.Optional => {
|
||||||
|
// If an optional has no value we return false.
|
||||||
|
const unwrapped = value orelse return false;
|
||||||
|
return getValue(ptr_raw, unwrapped);
|
||||||
|
},
|
||||||
|
|
||||||
|
.Enum => {
|
||||||
|
const ptr: *[*:0]const u8 = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = @tagName(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
.Struct => |info| {
|
||||||
|
// Packed structs that are less than or equal to the
|
||||||
|
// size of a C int can be passed directly as their
|
||||||
|
// bit representation.
|
||||||
|
if (info.layout != .Packed) return false;
|
||||||
|
const Backing = info.backing_integer orelse return false;
|
||||||
|
if (@bitSizeOf(Backing) > @bitSizeOf(c_uint)) return false;
|
||||||
|
|
||||||
|
const ptr: *c_uint = @ptrCast(@alignCast(ptr_raw));
|
||||||
|
ptr.* = @intCast(@as(Backing, @bitCast(value)));
|
||||||
|
},
|
||||||
|
|
||||||
|
else => return false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a value from the config by key.
|
/// Get a value from the config by key.
|
||||||
fn fieldByKey(self: *const Config, comptime k: Key) Value(k) {
|
fn fieldByKey(self: *const Config, comptime k: Key) Value(k) {
|
||||||
const field = comptime field: {
|
const field = comptime field: {
|
||||||
@@ -109,3 +121,37 @@ test "enum" {
|
|||||||
const str = std.mem.sliceTo(cval, 0);
|
const str = std.mem.sliceTo(cval, 0);
|
||||||
try testing.expectEqualStrings("dark", str);
|
try testing.expectEqualStrings("dark", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "color" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var c = try Config.default(alloc);
|
||||||
|
defer c.deinit();
|
||||||
|
c.background = .{ .r = 255, .g = 0, .b = 0 };
|
||||||
|
|
||||||
|
var cval: c_uint = undefined;
|
||||||
|
try testing.expect(get(&c, .background, @ptrCast(&cval)));
|
||||||
|
try testing.expectEqual(@as(c_uint, 255), cval);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "optional" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var c = try Config.default(alloc);
|
||||||
|
defer c.deinit();
|
||||||
|
|
||||||
|
{
|
||||||
|
c.@"unfocused-split-fill" = null;
|
||||||
|
var cval: c_uint = undefined;
|
||||||
|
try testing.expect(!get(&c, .@"unfocused-split-fill", @ptrCast(&cval)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
c.@"unfocused-split-fill" = .{ .r = 255, .g = 0, .b = 0 };
|
||||||
|
var cval: c_uint = undefined;
|
||||||
|
try testing.expect(get(&c, .@"unfocused-split-fill", @ptrCast(&cval)));
|
||||||
|
try testing.expectEqual(@as(c_uint, 255), cval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user