Skip to content

Commit 7eb1780

Browse files
authored
fix: make split-pane dividers visible via explicit borderHex (#26) (#40)
1 parent 5ba0146 commit 7eb1780

1 file changed

Lines changed: 49 additions & 5 deletions

File tree

Sources/Workspace.swift

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6768,6 +6768,47 @@ final class Workspace: Identifiable, ObservableObject {
67686768
return themedColor.hexString(includeAlpha: includeAlpha)
67696769
}
67706770

6771+
/// Returns a clearly-perceptible divider hex derived from the chrome background hex.
6772+
/// Dark backgrounds are lightened ~28% toward white; light backgrounds are darkened ~20% toward
6773+
/// black. These factors are meaningfully stronger than bonsplit's built-in weak fallback (0.16/0.12
6774+
/// tone at reduced alpha), ensuring the 1pt split divider is visible in both dark and light themes.
6775+
/// The result is always an opaque #RRGGBB string (no alpha), matching hexString(includeAlpha:false).
6776+
static func bonsplitDividerHex(fromChromeHex chromeHex: String) -> String {
6777+
// Parse #RRGGBB or #RRGGBBAA produced by hexString(includeAlpha:)
6778+
let stripped = chromeHex.hasPrefix("#") ? String(chromeHex.dropFirst()) : chromeHex
6779+
guard stripped.count >= 6,
6780+
let rByte = UInt8(stripped.prefix(2), radix: 16),
6781+
let gByte = UInt8(stripped.dropFirst(2).prefix(2), radix: 16),
6782+
let bByte = UInt8(stripped.dropFirst(4).prefix(2), radix: 16)
6783+
else {
6784+
return chromeHex // fallback: return unchanged on parse failure
6785+
}
6786+
6787+
var r = CGFloat(rByte) / 255.0
6788+
var g = CGFloat(gByte) / 255.0
6789+
var b = CGFloat(bByte) / 255.0
6790+
6791+
// Perceptual luminance check (sRGB coefficients, no gamma expansion needed for light/dark)
6792+
let luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
6793+
6794+
if luminance < 0.5 {
6795+
// Dark background: lighten 28% toward white
6796+
r += (1.0 - r) * 0.28
6797+
g += (1.0 - g) * 0.28
6798+
b += (1.0 - b) * 0.28
6799+
} else {
6800+
// Light background: darken 20% toward black
6801+
r *= 0.80
6802+
g *= 0.80
6803+
b *= 0.80
6804+
}
6805+
6806+
let rOut = min(255, max(0, Int((r * 255).rounded())))
6807+
let gOut = min(255, max(0, Int((g * 255).rounded())))
6808+
let bOut = min(255, max(0, Int((b * 255).rounded())))
6809+
return String(format: "#%02X%02X%02X", rOut, gOut, bOut)
6810+
}
6811+
67716812
nonisolated static func resolvedChromeColors(
67726813
from backgroundColor: NSColor
67736814
) -> BonsplitConfiguration.Appearance.ChromeColors {
@@ -6778,14 +6819,16 @@ final class Workspace: Identifiable, ObservableObject {
67786819
from backgroundColor: NSColor,
67796820
backgroundOpacity: Double
67806821
) -> BonsplitConfiguration.Appearance {
6781-
BonsplitConfiguration.Appearance(
6822+
let chromeHex = Self.bonsplitChromeHex(
6823+
backgroundColor: backgroundColor,
6824+
backgroundOpacity: backgroundOpacity
6825+
)
6826+
return BonsplitConfiguration.Appearance(
67826827
splitButtonTooltips: Self.currentSplitButtonTooltips(),
67836828
enableAnimations: false,
67846829
chromeColors: .init(
6785-
backgroundHex: Self.bonsplitChromeHex(
6786-
backgroundColor: backgroundColor,
6787-
backgroundOpacity: backgroundOpacity
6788-
)
6830+
backgroundHex: chromeHex,
6831+
borderHex: Self.bonsplitDividerHex(fromChromeHex: chromeHex)
67896832
)
67906833
)
67916834
}
@@ -6817,6 +6860,7 @@ final class Workspace: Identifiable, ObservableObject {
68176860
return
68186861
}
68196862
bonsplitController.configuration.appearance.chromeColors.backgroundHex = nextHex
6863+
bonsplitController.configuration.appearance.chromeColors.borderHex = Self.bonsplitDividerHex(fromChromeHex: nextHex)
68206864
if GhosttyApp.shared.backgroundLogEnabled {
68216865
GhosttyApp.shared.logBackground(
68226866
"theme applied workspace=\(id.uuidString) reason=\(reason) resultingBg=\(bonsplitController.configuration.appearance.chromeColors.backgroundHex ?? "nil")"

0 commit comments

Comments
 (0)