diff --git a/macos/Ghostty.xcodeproj/project.pbxproj b/macos/Ghostty.xcodeproj/project.pbxproj index eb8c236e7..d0942cad2 100644 --- a/macos/Ghostty.xcodeproj/project.pbxproj +++ b/macos/Ghostty.xcodeproj/project.pbxproj @@ -68,6 +68,7 @@ AEF9CE242B6AD07A0017E195 /* TerminalToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEF9CE232B6AD07A0017E195 /* TerminalToolbar.swift */; }; C159E81D2B66A06B00FDFE9C /* OSColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */; }; C159E89D2B69A2EF00FDFE9C /* OSColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */; }; + C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F26EA62B738B9900404083 /* NSView+Extension.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -128,6 +129,7 @@ A5FEB2FF2ABB69450068369E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; AEF9CE232B6AD07A0017E195 /* TerminalToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalToolbar.swift; sourceTree = ""; }; C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OSColor+Extension.swift"; sourceTree = ""; }; + C1F26EA62B738B9900404083 /* NSView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSView+Extension.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -193,6 +195,7 @@ A59630962AEE163600D64628 /* HostingWindow.swift */, A59FB5D02AE0DEA7009128F3 /* MetalView.swift */, C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */, + C1F26EA62B738B9900404083 /* NSView+Extension.swift */, A5CEAFDA29B8005900646FDA /* SplitView */, ); path = Helpers; @@ -468,6 +471,7 @@ A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */, A5D0AF3D2B37804400D21823 /* CodableBridge.swift in Sources */, A5D0AF3B2B36A1DE00D21823 /* TerminalRestorable.swift in Sources */, + C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */, A596309C2AEE1C9E00D64628 /* TerminalController.swift in Sources */, A56D58892ACDE6CA00508D2C /* ServiceProvider.swift in Sources */, A51BFC222B2FB6B400E92F16 /* AboutView.swift in Sources */, diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index e2d14ad1f..457b3bd08 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -33,7 +33,22 @@ class TerminalWindow: NSWindow { // The tab bar controller ID from macOS static private let TabBarController = NSUserInterfaceItemIdentifier("_tabBarController") - + + // Look through the titlebar's view hierarchy and hide any of the internal + // views used to create a separator between the title/toolbar and unselected + // tabs in the tab bar. + override func updateConstraintsIfNeeded() { + super.updateConstraintsIfNeeded() + + guard let titlebarContainer = contentView?.superview?.subviews.first(where: { + $0.className == "NSTitlebarContainerView" + }) else { return } + + for v in titlebarContainer.descendants(withClassName: "NSTitlebarSeparatorView") { + v.isHidden = true + } + } + /// This is called by titlebarTabs changing so that we can setup the rest of our window private func changedTitlebarTabs(to newValue: Bool) { self.titlebarAppearsTransparent = newValue @@ -73,7 +88,7 @@ class TerminalWindow: NSWindow { guard let titlebarContainer = contentView?.superview?.subviews.first(where: { $0.className == "NSTitlebarContainerView" }) else { return } - + titlebarContainer.wantsLayer = true titlebarContainer.layer?.backgroundColor = color } @@ -137,7 +152,7 @@ class TerminalWindow: NSWindow { guard let toolbarView = titlebarView.subviews.first(where: { $0.className == "NSToolbarView" }) else { return } - + addWindowButtonsBackdrop(titlebarView: titlebarView, toolbarView: toolbarView) guard let windowButtonsBackdrop = windowButtonsBackdrop else { return } @@ -190,24 +205,13 @@ class TerminalWindow: NSWindow { view.heightAnchor.constraint(equalTo: toolbarView.heightAnchor).isActive = true view.wantsLayer = true - let topBorder = NSView() - view.addSubview(topBorder) - topBorder.translatesAutoresizingMaskIntoConstraints = false - topBorder.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true - topBorder.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true - topBorder.topAnchor.constraint(equalTo: view.topAnchor).isActive = true - topBorder.bottomAnchor.constraint(equalTo: view.topAnchor, constant: 1).isActive = true - topBorder.wantsLayer = true - // This is jank but this makes the background color for light themes on the button // backdrop look MUCH better. I couldn't figure out a perfect color to use that works // for both so we just check the appearance. if effectiveAppearance.name == .aqua { view.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.95, alpha: 1) - topBorder.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.2) } else { view.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.45) - topBorder.layer?.backgroundColor = CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.85) } windowButtonsBackdrop = view diff --git a/macos/Sources/Helpers/NSView+Extension.swift b/macos/Sources/Helpers/NSView+Extension.swift new file mode 100644 index 000000000..8612c0417 --- /dev/null +++ b/macos/Sources/Helpers/NSView+Extension.swift @@ -0,0 +1,18 @@ +import AppKit + +extension NSView { + /// Recursively finds and returns descendant views that have the given class name. + func descendants(withClassName name: String) -> [NSView] { + var result = [NSView]() + + for subview in subviews { + if String(describing: type(of: subview)) == name { + result.append(subview) + } + + result += subview.descendants(withClassName: name) + } + + return result + } +}