From 298d6194f4c4de6727b6391b631d4d7f54d7f6b1 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 14 Dec 2024 10:48:43 -0800 Subject: [PATCH] config: change color to a defined C struct for libghostty --- include/ghostty.h | 14 +++++++++ macos/Sources/Ghostty/Ghostty.Config.swift | 34 +++++++++------------- src/config/Config.zig | 20 +++++++++---- src/config/c_get.zig | 30 +++++++++++-------- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index d2e59b09f..43981cdc5 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -333,6 +333,20 @@ typedef struct { uint32_t cell_height_px; } 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 typedef enum { GHOSTTY_TARGET_APP, diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index ee37c8cc5..c52b247d5 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -261,9 +261,9 @@ extension Ghostty { } var backgroundColor: Color { - var rgb: UInt32 = 0 + var color: ghostty_config_color_s = .init(); 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) return Color(NSColor.windowBackgroundColor) #elseif os(iOS) @@ -273,14 +273,10 @@ extension Ghostty { #endif } - let red = Double(rgb & 0xff) - let green = Double((rgb >> 8) & 0xff) - let blue = Double((rgb >> 16) & 0xff) - - return Color( - red: red / 255, - green: green / 255, - blue: blue / 255 + return .init( + red: Double(color.r) / 255, + green: Double(color.g) / 255, + blue: Double(color.b) / 255 ) } @@ -311,21 +307,17 @@ extension Ghostty { var unfocusedSplitFill: Color { 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" - if (!ghostty_config_get(config, &rgb, key, UInt(key.count))) { + if (!ghostty_config_get(config, &color, key, UInt(key.count))) { 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) - let green = Double((rgb >> 8) & 0xff) - let blue = Double((rgb >> 16) & 0xff) - - return Color( - red: red / 255, - green: green / 255, - blue: blue / 255 + return .init( + red: Double(color.r), + green: Double(color.g) / 255, + blue: Double(color.b) / 255 ) } diff --git a/src/config/Config.zig b/src/config/Config.zig index 720c1f305..bb17fece9 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -3529,11 +3529,22 @@ pub const WindowPaddingColor = enum { /// /// This is a packed struct so that the C API to read color values just /// works by setting it to a C integer. -pub const Color = packed struct(u24) { +pub const Color = struct { r: u8, g: 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 pub fn toTerminalRGB(self: Color) terminal.color.RGB { return .{ .r = self.r, .g = self.g, .b = self.b }; @@ -4906,7 +4917,7 @@ pub const MacTitlebarStyle = enum { }; /// See macos-titlebar-proxy-icon -pub const MacTitlebarProxyIcon: type = enum { +pub const MacTitlebarProxyIcon = enum { visible, hidden, }; @@ -5246,9 +5257,8 @@ pub const Duration = struct { } } - pub fn c_get(self: Duration, ptr_raw: *anyopaque) void { - const ptr: *usize = @ptrCast(@alignCast(ptr_raw)); - ptr.* = @intCast(self.asMilliseconds()); + pub fn cval(self: Duration) usize { + return @intCast(self.asMilliseconds()); } /// Convenience function to convert to milliseconds since many OS and diff --git a/src/config/c_get.zig b/src/config/c_get.zig index 32a19df1c..dd7c7cce8 100644 --- a/src/config/c_get.zig +++ b/src/config/c_get.zig @@ -60,9 +60,11 @@ fn getValue(ptr_raw: *anyopaque, value: anytype) bool { }, .Struct => |info| { - // If the struct implements c_get then we call that - if (@hasDecl(@TypeOf(value), "c_get")) { - value.c_get(ptr_raw); + // If the struct implements cval then we call then. + 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; } @@ -100,7 +102,7 @@ fn fieldByKey(self: *const Config, comptime k: Key) Value(k) { return @field(self, field.name); } -test "u8" { +test "c_get: u8" { const testing = std.testing; const alloc = testing.allocator; @@ -113,7 +115,7 @@ test "u8" { try testing.expectEqual(@as(f32, 24), cval); } -test "enum" { +test "c_get: enum" { const testing = std.testing; const alloc = testing.allocator; @@ -128,7 +130,7 @@ test "enum" { try testing.expectEqualStrings("dark", str); } -test "color" { +test "c_get: color" { const testing = std.testing; const alloc = testing.allocator; @@ -136,12 +138,14 @@ test "color" { defer c.deinit(); 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.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 alloc = testing.allocator; @@ -150,14 +154,16 @@ test "optional" { { 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))); } { 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.expectEqual(@as(c_uint, 255), cval); + try testing.expectEqual(255, cval.r); + try testing.expectEqual(0, cval.g); + try testing.expectEqual(0, cval.b); } }