macOS: Fix more `macos-titlebar-style` related issues (#9163)
Ghosty is active will result in similar nastiness. https://github.com/user-attachments/assets/fcd7761e-a521-4382-8d7a-9d93dc0806bc - [Sequoia/Ventura] Fix flickering new tab icon, and it also didn't respond to window's key status change correctly - [Sequoia/Ventura] Fix after changing appearance, tab bar may disappear or have inconsistent background colour - Fix initial tint of reset zoom button on Sequoia/Ventura with `macos-titlebar-style=tabs` and all `native/transparent` titlebars - Fix title alignment with custom font with `native/transparent` titlebar1.2.x
parent
537b304cd6
commit
5c9ceab0bf
|
|
@ -124,6 +124,12 @@ class TerminalWindow: NSWindow {
|
|||
} else {
|
||||
tabBarDidDisappear()
|
||||
}
|
||||
viewModel.isMainWindow = true
|
||||
}
|
||||
|
||||
override func resignMain() {
|
||||
super.resignMain()
|
||||
viewModel.isMainWindow = false
|
||||
}
|
||||
|
||||
override func mergeAllWindows(_ sender: Any?) {
|
||||
|
|
@ -260,7 +266,7 @@ class TerminalWindow: NSWindow {
|
|||
button.isBordered = false
|
||||
button.allowsExpansionToolTips = true
|
||||
button.toolTip = "Reset Zoom"
|
||||
button.contentTintColor = .controlAccentColor
|
||||
button.contentTintColor = isMainWindow ? .controlAccentColor : .secondaryLabelColor
|
||||
button.state = .on
|
||||
button.image = NSImage(named:"ResetZoom")
|
||||
button.frame = NSRect(x: 0, y: 0, width: 20, height: 20)
|
||||
|
|
@ -286,6 +292,7 @@ class TerminalWindow: NSWindow {
|
|||
let font = titlebarFont ?? NSFont.titleBarFont(ofSize: NSFont.systemFontSize)
|
||||
|
||||
titlebarTextField?.font = font
|
||||
titlebarTextField?.usesSingleLineMode = true
|
||||
tab.attributedTitle = attributedTitle
|
||||
}
|
||||
}
|
||||
|
|
@ -467,6 +474,7 @@ extension TerminalWindow {
|
|||
class ViewModel: ObservableObject {
|
||||
@Published var isSurfaceZoomed: Bool = false
|
||||
@Published var hasToolbar: Bool = false
|
||||
@Published var isMainWindow: Bool = true
|
||||
}
|
||||
|
||||
struct ResetZoomAccessoryView: View {
|
||||
|
|
@ -488,7 +496,7 @@ extension TerminalWindow {
|
|||
VStack {
|
||||
Button(action: action) {
|
||||
Image("ResetZoom")
|
||||
.foregroundColor(.accentColor)
|
||||
.foregroundColor(viewModel.isMainWindow ? .accentColor : .secondary)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Reset Split Zoom")
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow {
|
|||
super.syncAppearance(surfaceConfig)
|
||||
|
||||
// Update our window light/darkness based on our updated background color
|
||||
let themeChanged = isLightTheme != OSColor(surfaceConfig.backgroundColor).isLightColor
|
||||
isLightTheme = OSColor(surfaceConfig.backgroundColor).isLightColor
|
||||
|
||||
// Update our titlebar color
|
||||
|
|
@ -150,7 +151,7 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow {
|
|||
titlebarColor = derivedConfig.backgroundColor.withAlphaComponent(derivedConfig.backgroundOpacity)
|
||||
}
|
||||
|
||||
if (isOpaque) {
|
||||
if (isOpaque || themeChanged) {
|
||||
// If there is transparency, calling this will make the titlebar opaque
|
||||
// so we only call this if we are opaque.
|
||||
updateTabBar()
|
||||
|
|
@ -183,41 +184,33 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow {
|
|||
// so we need to do it manually.
|
||||
private func updateNewTabButtonOpacity() {
|
||||
guard let newTabButton: NSButton = titlebarContainer?.firstDescendant(withClassName: "NSTabBarNewTabButton") as? NSButton else { return }
|
||||
guard let newTabButtonImageView: NSImageView = newTabButton.subviews.first(where: {
|
||||
$0 as? NSImageView != nil
|
||||
}) as? NSImageView else { return }
|
||||
guard let newTabButtonImageView = newTabButton.firstDescendant(withClassName: "NSImageView") as? NSImageView else { return }
|
||||
|
||||
newTabButtonImageView.alphaValue = isKeyWindow ? 1 : 0.5
|
||||
}
|
||||
|
||||
// Color the new tab button's image to match the color of the tab title/keyboard shortcut labels,
|
||||
// just as it does in the stock tab bar.
|
||||
/// Update: This method only add a vibrant overlay now,
|
||||
/// since the image itself supports light/dark tint,
|
||||
/// and system could restore it any time,
|
||||
/// altering it will only cause maintenance burden for us.
|
||||
///
|
||||
/// And if we hide original image,
|
||||
/// ``updateNewTabButtonOpacity`` will not work
|
||||
///
|
||||
/// ~~Color the new tab button's image to match the color of the tab title/keyboard shortcut labels,~~
|
||||
/// ~~just as it does in the stock tab bar.~~
|
||||
private func updateNewTabButtonImage() {
|
||||
guard let newTabButton: NSButton = titlebarContainer?.firstDescendant(withClassName: "NSTabBarNewTabButton") as? NSButton else { return }
|
||||
guard let newTabButtonImageView: NSImageView = newTabButton.subviews.first(where: {
|
||||
$0 as? NSImageView != nil
|
||||
}) as? NSImageView else { return }
|
||||
guard let newTabButtonImageView = newTabButton.firstDescendant(withClassName: "NSImageView") as? NSImageView else { return }
|
||||
guard let newTabButtonImage = newTabButtonImageView.image else { return }
|
||||
|
||||
let imageLayer = newTabButtonImageLayer ?? VibrantLayer(forAppearance: isLightTheme ? .light : .dark)!
|
||||
imageLayer.frame = NSRect(origin: NSPoint(x: newTabButton.bounds.midX - newTabButtonImage.size.width/2, y: newTabButton.bounds.midY - newTabButtonImage.size.height/2), size: newTabButtonImage.size)
|
||||
imageLayer.contentsGravity = .resizeAspect
|
||||
imageLayer.opacity = 0.5
|
||||
|
||||
if newTabButtonImageLayer == nil {
|
||||
let fillColor: NSColor = isLightTheme ? .black.withAlphaComponent(0.85) : .white.withAlphaComponent(0.85)
|
||||
let newImage = NSImage(size: newTabButtonImage.size, flipped: false) { rect in
|
||||
newTabButtonImage.draw(in: rect)
|
||||
fillColor.setFill()
|
||||
rect.fill(using: .sourceAtop)
|
||||
return true
|
||||
}
|
||||
let imageLayer = VibrantLayer(forAppearance: isLightTheme ? .light : .dark)!
|
||||
imageLayer.frame = NSRect(origin: NSPoint(x: newTabButton.bounds.midX - newTabButtonImage.size.width/2, y: newTabButton.bounds.midY - newTabButtonImage.size.height/2), size: newTabButtonImage.size)
|
||||
imageLayer.contentsGravity = .resizeAspect
|
||||
imageLayer.contents = newImage
|
||||
imageLayer.opacity = 0.5
|
||||
newTabButtonImageLayer = imageLayer
|
||||
|
||||
newTabButtonImageLayer = imageLayer
|
||||
}
|
||||
|
||||
newTabButtonImageView.isHidden = true
|
||||
newTabButton.layer?.sublayers?.first(where: { $0.className == "VibrantLayer" })?.removeFromSuperlayer()
|
||||
newTabButton.layer?.addSublayer(newTabButtonImageLayer!)
|
||||
}
|
||||
|
|
@ -448,6 +441,13 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow {
|
|||
}
|
||||
|
||||
private func addWindowButtonsBackdrop(titlebarView: NSView, toolbarView: NSView) {
|
||||
guard windowButtonsBackdrop?.superview != titlebarView else {
|
||||
/// replacing existing backdrop aggressively
|
||||
/// may cause incorrect hierarchy
|
||||
///
|
||||
/// because multiple windows are adding this around the 'same time'
|
||||
return
|
||||
}
|
||||
windowButtonsBackdrop?.removeFromSuperview()
|
||||
windowButtonsBackdrop = nil
|
||||
|
||||
|
|
@ -466,16 +466,11 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow {
|
|||
|
||||
private func addWindowDragHandle(titlebarView: NSView, toolbarView: NSView) {
|
||||
// If we already made the view, just make sure it's unhidden and correctly placed as a subview.
|
||||
if let view = windowDragHandle {
|
||||
view.removeFromSuperview()
|
||||
view.isHidden = false
|
||||
titlebarView.superview?.addSubview(view)
|
||||
view.leftAnchor.constraint(equalTo: toolbarView.leftAnchor).isActive = true
|
||||
view.rightAnchor.constraint(equalTo: toolbarView.rightAnchor).isActive = true
|
||||
view.topAnchor.constraint(equalTo: toolbarView.topAnchor).isActive = true
|
||||
view.bottomAnchor.constraint(equalTo: toolbarView.topAnchor, constant: 12).isActive = true
|
||||
guard windowDragHandle?.superview != titlebarView.superview else {
|
||||
// similar to `addWindowButtonsBackdrop`
|
||||
return
|
||||
}
|
||||
windowDragHandle?.removeFromSuperview()
|
||||
|
||||
let view = WindowDragView()
|
||||
view.identifier = NSUserInterfaceItemIdentifier("_windowDragHandle")
|
||||
|
|
@ -536,7 +531,10 @@ fileprivate class WindowButtonsBackdropView: NSView {
|
|||
// This must be weak because the window has this view. Otherwise
|
||||
// a retain cycle occurs.
|
||||
private weak var terminalWindow: TitlebarTabsVenturaTerminalWindow?
|
||||
private let isLightTheme: Bool
|
||||
private var isLightTheme: Bool {
|
||||
// using up-to-date value from hosting window directly
|
||||
terminalWindow?.isLightTheme ?? false
|
||||
}
|
||||
private let overlayLayer = VibrantLayer()
|
||||
|
||||
var isHighlighted: Bool = true {
|
||||
|
|
@ -565,7 +563,6 @@ fileprivate class WindowButtonsBackdropView: NSView {
|
|||
|
||||
init(window: TitlebarTabsVenturaTerminalWindow) {
|
||||
self.terminalWindow = window
|
||||
self.isLightTheme = window.isLightTheme
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue