config: change color to a defined C struct for libghostty

This commit is contained in:
Mitchell Hashimoto
2024-12-14 10:48:43 -08:00
parent adba2036e3
commit 298d6194f4
4 changed files with 60 additions and 38 deletions

View File

@ -333,6 +333,20 @@ typedef struct {
uint32_t cell_height_px; uint32_t cell_height_px;
} ghostty_surface_size_s; } ghostty_surface_size_s;
// Config types
// config.Color
typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
} ghostty_config_color_s;
typedef struct {
const ghostty_config_color_s* colors;
size_t len;
} ghostty_config_color_list_s;
// apprt.Target.Key // apprt.Target.Key
typedef enum { typedef enum {
GHOSTTY_TARGET_APP, GHOSTTY_TARGET_APP,

View File

@ -261,9 +261,9 @@ extension Ghostty {
} }
var backgroundColor: Color { var backgroundColor: Color {
var rgb: UInt32 = 0 var color: ghostty_config_color_s = .init();
let bg_key = "background" let bg_key = "background"
if (!ghostty_config_get(config, &rgb, bg_key, UInt(bg_key.count))) { if (!ghostty_config_get(config, &color, bg_key, UInt(bg_key.count))) {
#if os(macOS) #if os(macOS)
return Color(NSColor.windowBackgroundColor) return Color(NSColor.windowBackgroundColor)
#elseif os(iOS) #elseif os(iOS)
@ -273,14 +273,10 @@ extension Ghostty {
#endif #endif
} }
let red = Double(rgb & 0xff) return .init(
let green = Double((rgb >> 8) & 0xff) red: Double(color.r) / 255,
let blue = Double((rgb >> 16) & 0xff) green: Double(color.g) / 255,
blue: Double(color.b) / 255
return Color(
red: red / 255,
green: green / 255,
blue: blue / 255
) )
} }
@ -311,21 +307,17 @@ extension Ghostty {
var unfocusedSplitFill: Color { var unfocusedSplitFill: Color {
guard let config = self.config else { return .white } guard let config = self.config else { return .white }
var rgb: UInt32 = 16777215 // white default var color: ghostty_config_color_s = .init();
let key = "unfocused-split-fill" let key = "unfocused-split-fill"
if (!ghostty_config_get(config, &rgb, key, UInt(key.count))) { if (!ghostty_config_get(config, &color, key, UInt(key.count))) {
let bg_key = "background" let bg_key = "background"
_ = ghostty_config_get(config, &rgb, bg_key, UInt(bg_key.count)); _ = ghostty_config_get(config, &color, bg_key, UInt(bg_key.count));
} }
let red = Double(rgb & 0xff) return .init(
let green = Double((rgb >> 8) & 0xff) red: Double(color.r),
let blue = Double((rgb >> 16) & 0xff) green: Double(color.g) / 255,
blue: Double(color.b) / 255
return Color(
red: red / 255,
green: green / 255,
blue: blue / 255
) )
} }

View File

@ -3529,11 +3529,22 @@ pub const WindowPaddingColor = enum {
/// ///
/// This is a packed struct so that the C API to read color values just /// This is a packed struct so that the C API to read color values just
/// works by setting it to a C integer. /// works by setting it to a C integer.
pub const Color = packed struct(u24) { pub const Color = struct {
r: u8, r: u8,
g: u8, g: u8,
b: u8, b: u8,
/// ghostty_config_color_s
pub const C = extern struct {
r: u8,
g: u8,
b: u8,
};
pub fn cval(self: Color) Color.C {
return .{ .r = self.r, .g = self.g, .b = self.b };
}
/// Convert this to the terminal RGB struct /// Convert this to the terminal RGB struct
pub fn toTerminalRGB(self: Color) terminal.color.RGB { pub fn toTerminalRGB(self: Color) terminal.color.RGB {
return .{ .r = self.r, .g = self.g, .b = self.b }; return .{ .r = self.r, .g = self.g, .b = self.b };
@ -4906,7 +4917,7 @@ pub const MacTitlebarStyle = enum {
}; };
/// See macos-titlebar-proxy-icon /// See macos-titlebar-proxy-icon
pub const MacTitlebarProxyIcon: type = enum { pub const MacTitlebarProxyIcon = enum {
visible, visible,
hidden, hidden,
}; };
@ -5246,9 +5257,8 @@ pub const Duration = struct {
} }
} }
pub fn c_get(self: Duration, ptr_raw: *anyopaque) void { pub fn cval(self: Duration) usize {
const ptr: *usize = @ptrCast(@alignCast(ptr_raw)); return @intCast(self.asMilliseconds());
ptr.* = @intCast(self.asMilliseconds());
} }
/// Convenience function to convert to milliseconds since many OS and /// Convenience function to convert to milliseconds since many OS and

View File

@ -60,9 +60,11 @@ fn getValue(ptr_raw: *anyopaque, value: anytype) bool {
}, },
.Struct => |info| { .Struct => |info| {
// If the struct implements c_get then we call that // If the struct implements cval then we call then.
if (@hasDecl(@TypeOf(value), "c_get")) { if (@hasDecl(T, "cval")) {
value.c_get(ptr_raw); const PtrT = @typeInfo(@TypeOf(T.cval)).Fn.return_type.?;
const ptr: *PtrT = @ptrCast(@alignCast(ptr_raw));
ptr.* = value.cval();
return true; return true;
} }
@ -100,7 +102,7 @@ fn fieldByKey(self: *const Config, comptime k: Key) Value(k) {
return @field(self, field.name); return @field(self, field.name);
} }
test "u8" { test "c_get: u8" {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
@ -113,7 +115,7 @@ test "u8" {
try testing.expectEqual(@as(f32, 24), cval); try testing.expectEqual(@as(f32, 24), cval);
} }
test "enum" { test "c_get: enum" {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
@ -128,7 +130,7 @@ test "enum" {
try testing.expectEqualStrings("dark", str); try testing.expectEqualStrings("dark", str);
} }
test "color" { test "c_get: color" {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
@ -136,12 +138,14 @@ test "color" {
defer c.deinit(); defer c.deinit();
c.background = .{ .r = 255, .g = 0, .b = 0 }; c.background = .{ .r = 255, .g = 0, .b = 0 };
var cval: c_uint = undefined; var cval: Color.C = undefined;
try testing.expect(get(&c, .background, @ptrCast(&cval))); try testing.expect(get(&c, .background, @ptrCast(&cval)));
try testing.expectEqual(@as(c_uint, 255), cval); try testing.expectEqual(255, cval.r);
try testing.expectEqual(0, cval.g);
try testing.expectEqual(0, cval.b);
} }
test "optional" { test "c_get: optional" {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
@ -150,14 +154,16 @@ test "optional" {
{ {
c.@"unfocused-split-fill" = null; c.@"unfocused-split-fill" = null;
var cval: c_uint = undefined; var cval: Color.C = undefined;
try testing.expect(!get(&c, .@"unfocused-split-fill", @ptrCast(&cval))); try testing.expect(!get(&c, .@"unfocused-split-fill", @ptrCast(&cval)));
} }
{ {
c.@"unfocused-split-fill" = .{ .r = 255, .g = 0, .b = 0 }; c.@"unfocused-split-fill" = .{ .r = 255, .g = 0, .b = 0 };
var cval: c_uint = undefined; var cval: Color.C = undefined;
try testing.expect(get(&c, .@"unfocused-split-fill", @ptrCast(&cval))); try testing.expect(get(&c, .@"unfocused-split-fill", @ptrCast(&cval)));
try testing.expectEqual(@as(c_uint, 255), cval); try testing.expectEqual(255, cval.r);
try testing.expectEqual(0, cval.g);
try testing.expectEqual(0, cval.b);
} }
} }