Skip to content

Commit f6eb7eb

Browse files
committed
feat: change titlebar text color based on background color
1 parent 51b3e77 commit f6eb7eb

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

MacHelix/MacHelixApp.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct HelixApp: App {
3232
.toolbar { ToolbarItem { Spacer() } } // empty toolbar forces title to left
3333
.introspect(.window, on: .macOS(.v14)) { window in
3434
window.titlebarAppearsTransparent = true
35-
NSApp.appearance = NSAppearance(named: .darkAqua)
35+
NSApp.appearance = NSAppearance(named: viewStore.isDarkMode ? .darkAqua : .aqua)
3636
}
3737
}
3838
.windowStyle(.automatic)

Modules/Common/Color.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public struct Color: Equatable, Sendable {
1111
public let red: Int
1212
public let green: Int
1313
public let blue: Int
14+
}
1415

16+
extension Color {
1517
public init(hexColorString: String) {
1618
// Ensure the string has the expected length
1719
guard hexColorString.count == 7 else { fatalError("malformed hex color string: \(hexColorString)") }
@@ -32,3 +34,23 @@ public struct Color: Equatable, Sendable {
3234
}
3335

3436

37+
// origin: https://chat.openai.com/share/23d90922-b701-4c91-b40c-08e58974ce11
38+
extension Color {
39+
public func isDark() -> Bool {
40+
let red = Double(red)/256
41+
let green = Double(green)/256
42+
let blue = Double(blue)/256
43+
44+
// Convert sRGB values to linear values
45+
let linearRed = (red <= 0.04045) ? red / 12.92 : pow((red + 0.055) / 1.055, 2.4)
46+
let linearGreen = (green <= 0.04045) ? green / 12.92 : pow((green + 0.055) / 1.055, 2.4)
47+
let linearBlue = (blue <= 0.04045) ? blue / 12.92 : pow((blue + 0.055) / 1.055, 2.4)
48+
49+
// Calculate relative luminance
50+
let luminance = 0.2126 * linearRed + 0.7152 * linearGreen + 0.0722 * linearBlue
51+
52+
// Use a threshold to determine if the color is dark
53+
return luminance < 0.5
54+
}
55+
}
56+

Modules/Feature/AppFeature/AppFeature.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import ComposableArchitecture
2+
import Common
23
import Foundation
3-
import TerminalFeature
44
import HelixFeature
5+
import TerminalFeature
56

67
public enum Position {
78
case left
@@ -18,6 +19,8 @@ public struct AppFeature: Reducer {
1819
public var mouseReportingEnabled: Bool = true
1920
public var currentDocumentURL: URL?
2021
public var helixState: HelixFeature.State
22+
public var isDarkMode: Bool = true
23+
2124
public init(helixState: HelixFeature.State = HelixFeature.State()) {
2225
self.helixState = helixState
2326
}
@@ -44,6 +47,10 @@ public struct AppFeature: Reducer {
4447
state.currentDocumentURL = url
4548
return .none
4649

50+
case .helix(.themeChanged(bgColor: let bgColor)):
51+
state.isDarkMode = bgColor.isDark()
52+
return .none
53+
4754
case .helix(_):
4855
return .none
4956

Modules/Feature/AppFeature/HelixView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ public struct HelixView: View {
4242

4343
extension Common.Color {
4444
func toSwiftUI() -> SwiftUI.Color {
45-
SwiftUI.Color(red: Double(red)/256, green: Double(green)/256, blue: Double(blue)/256)
45+
Color(red: Double(red)/256, green: Double(green)/256, blue: Double(blue)/256)
4646
}
4747
}

Modules/Feature/HelixFeature/HelixFeature.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ public struct HelixFeature: Reducer, Sendable {
114114
let rest = parts
115115
.dropFirst()
116116
.joined()
117-
.trimmingCharacters(in: .whitespacesAndNewlines)
118117
.components(separatedBy: ",")
118+
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
119119

120120
return (command, rest)
121121
}

0 commit comments

Comments
 (0)