Configurable unfocused dimming color

This commit is contained in:
Matt Robenolt
2023-12-12 16:34:41 -08:00
parent 7c2ecfea90
commit 8e607f372b
3 changed files with 53 additions and 4 deletions

View File

@ -60,9 +60,32 @@ extension Ghostty {
var opacity: Double = 0.85
let key = "unfocused-split-opacity"
_ = ghostty_config_get(ghostty.config, &opacity, key, UInt(key.count))
AppDelegate.logger.warning("ghostty_config_get(\(key))=\(opacity)")
return 1 - opacity
}
private var unfocusedFill: Color {
var rgb: UInt32 = 16777215 // white default
let key = "unfocused-split-fill"
_ = ghostty_config_get(ghostty.config, &rgb, key, UInt(key.count))
AppDelegate.logger.warning("ghostty_config_get(\(key))=\(rgb)")
let red = Double((rgb >> 16) & 0xff)
let green = Double((rgb >> 8) & 0xff)
let blue = Double(rgb & 0xff)
AppDelegate.logger.warning("red=\(red) green=\(green) blue=\(blue)")
return Color.init(
red: 255,
green: 0,
blue: 0
)
// return Color.init(
// red: red,
// green: green,
// blue: blue,
// opacity: unfocusedOpacity
// )
}
var body: some View {
ZStack {
// We use a GeometryReader to get the frame bounds so that our metal surface
@ -155,10 +178,13 @@ extension Ghostty {
// because we want to keep our focused surface dark even if we don't have window
// focus.
if (isSplit && !surfaceFocus) {
Rectangle()
.fill(.white)
.allowsHitTesting(false)
.opacity(unfocusedOpacity)
let overlayOpacity = unfocusedOpacity;
if (overlayOpacity > 0) {
Rectangle()
.fill(unfocusedFill)
.allowsHitTesting(false)
.opacity(overlayOpacity)
}
}
}
}

View File

@ -314,6 +314,8 @@ palette: Palette = .{},
/// clamped to the nearest valid value.
@"unfocused-split-opacity": f64 = 0.85,
@"unfocused-split-fill": ?Color = null,
/// 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
/// be looked up from your system. The rules for the default lookup are:
@ -1989,6 +1991,21 @@ pub const Color = struct {
return .{ .r = self.r, .g = self.g, .b = self.b };
}
// Pack into an integer
pub fn toInt(self: Color) u24 {
// u24 covers RGB, typically, an alpha would pack to a full u32
return (@as(u24, self.r) << 16) + (@as(u24, self.g) << 8) + self.b;
}
test "toInt" {
const testing = std.testing;
try testing.exectEqual((Color{ .r = 0, .g = 0, .b = 0 }).toInt(), 0);
try testing.exectEqual((Color{ .r = 255, .g = 255, .b = 255 }).toInt(), 16777215);
try testing.exectEqual((Color{ .r = 100, .g = 20, .b = 12 }).toInt(), 6558732);
try testing.exectEqual((Color{ .r = 55, .g = 63, .b = 202 }).toInt(), 3620810);
}
pub fn parseCLI(input: ?[]const u8) !Color {
return fromHex(input orelse return error.ValueRequired);
}

View File

@ -2,6 +2,7 @@ const std = @import("std");
const key = @import("key.zig");
const Config = @import("Config.zig");
const Color = Config.Color;
const Key = key.Key;
const Value = key.Value;
@ -38,6 +39,11 @@ pub fn get(config: *const Config, k: Key, ptr_raw: *anyopaque) bool {
ptr.* = @floatCast(value);
},
?Color => {
const ptr: *?c_uint = @ptrCast(@alignCast(ptr_raw));
ptr.* = if (value) |c| c.toInt() else null;
},
else => |T| switch (@typeInfo(T)) {
.Enum => {
const ptr: *[*:0]const u8 = @ptrCast(@alignCast(ptr_raw));