diff --git a/macos/Sources/Features/About/About.xib b/macos/Sources/Features/About/About.xib
index e884beff1..5803a32de 100644
--- a/macos/Sources/Features/About/About.xib
+++ b/macos/Sources/Features/About/About.xib
@@ -14,7 +14,7 @@
-
+
diff --git a/macos/Sources/Features/About/AboutController.swift b/macos/Sources/Features/About/AboutController.swift
index d2ae68ea7..efd7a515a 100644
--- a/macos/Sources/Features/About/AboutController.swift
+++ b/macos/Sources/Features/About/AboutController.swift
@@ -10,6 +10,7 @@ class AboutController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
guard let window = window else { return }
window.center()
+ window.isMovableByWindowBackground = true
window.contentView = NSHostingView(rootView: AboutView())
}
diff --git a/macos/Sources/Features/About/AboutView.swift b/macos/Sources/Features/About/AboutView.swift
index 02f899cc4..71fe9c252 100644
--- a/macos/Sources/Features/About/AboutView.swift
+++ b/macos/Sources/Features/About/AboutView.swift
@@ -1,35 +1,136 @@
import SwiftUI
struct AboutView: View {
+ @Environment(\.openURL) var openURL
+
+ private let githubLink = URL(string: "https://github.com/ghostty-org/ghostty")
+
/// Read the commit from the bundle.
- var build: String? { Bundle.main.infoDictionary?["CFBundleVersion"] as? String }
- var commit: String? { Bundle.main.infoDictionary?["GhosttyCommit"] as? String }
- var version: String? { Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String }
+ private var build: String? { Bundle.main.infoDictionary?["CFBundleVersion"] as? String }
+ private var commit: String? { Bundle.main.infoDictionary?["GhosttyCommit"] as? String }
+ private var version: String? { Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String }
+ private var copyright: String? { Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String }
+
+ private var properties: [KeyValue] {
+ let list: [KeyValue] = [
+ .init(key: "Version", value: version),
+ .init(key: "Build", value: build),
+ .init(key: "Commit", value: commit == "" ? nil : commit)
+ ]
+
+ return list.compactMap {
+ guard let value = $0.value else { return nil }
+ return .init(key: $0.key, value: value)
+ }
+ }
+
+ private struct KeyValue: Identifiable {
+ var id = UUID()
+ public let key: LocalizedStringResource
+ public let value: Value
+ }
+
+ #if os(macOS)
+ // This creates a background style similar to the Apple "About My Mac" Window
+ private struct VisualEffectBackground: NSViewRepresentable {
+ let material: NSVisualEffectView.Material
+ let blendingMode: NSVisualEffectView.BlendingMode
+ let isEmphasized: Bool
+
+ init(material: NSVisualEffectView.Material,
+ blendingMode: NSVisualEffectView.BlendingMode = .behindWindow,
+ isEmphasized: Bool = false)
+ {
+ self.material = material
+ self.blendingMode = blendingMode
+ self.isEmphasized = isEmphasized
+ }
+
+ func updateNSView(_ nsView: NSVisualEffectView, context: Context) {
+ nsView.material = material
+ nsView.blendingMode = blendingMode
+ nsView.isEmphasized = isEmphasized
+ }
+
+ func makeNSView(context: Context) -> NSVisualEffectView {
+ let visualEffect = NSVisualEffectView()
+ visualEffect.autoresizingMask = [.width, .height]
+ return visualEffect
+ }
+ }
+ #endif
var body: some View {
VStack(alignment: .center) {
Image("AppIconImage")
.resizable()
.aspectRatio(contentMode: .fit)
- .frame(maxHeight: 96)
+ .frame(height: 128)
- Text("Ghostty")
- .font(.title3)
+ VStack(alignment: .center, spacing: 32) {
+ VStack(alignment: .center, spacing: 8) {
+ Text("Ghostty")
+ .bold()
+ .font(.title)
+ Text("Fast, native, feature-rich terminal \nemulator pushing modern features.")
+ .multilineTextAlignment(.center)
+ .fixedSize(horizontal: false, vertical: true)
+ .font(.caption)
+ .tint(.secondary)
+ .opacity(0.8)
+ }
.textSelection(.enabled)
+ VStack(spacing: 2) {
+ ForEach(properties) { item in
+ HStack(spacing: 4) {
+ Text(item.key)
+ .frame(width: 126, alignment: .trailing)
+ .padding(.trailing, 2)
+ Text(item.value)
+ .frame(width: 125, alignment: .leading)
+ .padding(.leading, 2)
+ .tint(.secondary)
+ .opacity(0.8)
+ }
+ .font(.callout)
+ .textSelection(.enabled)
+ .frame(maxWidth: .infinity)
+ }
+ }
+ .frame(maxWidth: .infinity)
- if let version = self.version {
- Text("Version: \(version)")
- .font(.body)
- .textSelection(.enabled)
- }
+ HStack(spacing: 8) {
+ if let url = githubLink {
+ Button("GitHub") {
+ openURL(url)
+ }
+ }
- if let build = self.build {
- Text("Build: \(build)")
- .font(.body)
- .textSelection(.enabled)
+ }
+
+ if let copy = self.copyright {
+ Text(copy)
+ .font(.caption)
+ .textSelection(.enabled)
+ .tint(.secondary)
+ .opacity(0.8)
+ .multilineTextAlignment(.center)
+ .frame(maxWidth: .infinity)
+ }
}
+ .frame(maxWidth: .infinity)
}
- .frame(minWidth: 300)
- .padding()
+ .padding(.top, 8)
+ .padding(32)
+ .frame(minWidth: 256)
+ #if os(macOS)
+ .background(VisualEffectBackground(material: .underWindowBackground).ignoresSafeArea())
+ #endif
+ }
+}
+
+struct AboutView_Previews: PreviewProvider {
+ static var previews: some View {
+ AboutView()
}
}