mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
Update standard title/tab bar when config changes
This commit is contained in:
@ -166,15 +166,9 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
||||
private func syncAppearance() {
|
||||
guard let window = self.window as? TerminalWindow else { return }
|
||||
|
||||
// We match the appearance depending on the lightness/darkness of the
|
||||
// background color. We have to do this because our titlebars in tabs inherit
|
||||
// our background color for the focused tab but use the macOS theme for the
|
||||
// rest of the titlebar.
|
||||
if (window.titlebarTabs) {
|
||||
let color = OSColor(ghostty.config.backgroundColor)
|
||||
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
||||
window.appearance = appearance
|
||||
}
|
||||
let backgroundColor = OSColor(ghostty.config.backgroundColor)
|
||||
let appearance = NSAppearance(named: backgroundColor.isLightColor ? .aqua : .darkAqua)
|
||||
window.appearance = appearance
|
||||
|
||||
// Set the font for the window and tab titles.
|
||||
if let titleFontName = ghostty.config.windowTitleFontFamily {
|
||||
@ -182,6 +176,10 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
||||
} else {
|
||||
window.titlebarFont = nil
|
||||
}
|
||||
|
||||
window.backgroundColor = backgroundColor
|
||||
window.titlebarColor = backgroundColor.withAlphaComponent(ghostty.config.backgroundOpacity)
|
||||
window.updateToolbar()
|
||||
}
|
||||
|
||||
/// Update all surfaces with the focus state. This ensures that libghostty has an accurate view about
|
||||
@ -254,10 +252,11 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
||||
window.center()
|
||||
|
||||
// Set the background color of the window
|
||||
window.backgroundColor = NSColor(ghostty.config.backgroundColor)
|
||||
let backgroundColor = NSColor(ghostty.config.backgroundColor)
|
||||
window.backgroundColor = backgroundColor
|
||||
|
||||
// This makes sure our titlebar renders correctly when there is a transparent background
|
||||
window.titlebarOpacity = ghostty.config.backgroundOpacity
|
||||
window.titlebarColor = backgroundColor.withAlphaComponent(ghostty.config.backgroundOpacity)
|
||||
|
||||
// Handle titlebar tabs config option. Something about what we do while setting up the
|
||||
// titlebar tabs interferes with the window restore process unless window.tabbingMode
|
||||
|
@ -4,14 +4,14 @@ class TerminalWindow: NSWindow {
|
||||
@objc dynamic var surfaceIsZoomed: Bool = false
|
||||
@objc dynamic var keyEquivalent: String = ""
|
||||
|
||||
var titlebarOpacity: CGFloat = 1 {
|
||||
lazy var titlebarColor: NSColor = backgroundColor {
|
||||
didSet {
|
||||
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
||||
$0.className == "NSTitlebarContainerView"
|
||||
}) else { return }
|
||||
|
||||
titlebarContainer.wantsLayer = true
|
||||
titlebarContainer.layer?.backgroundColor = backgroundColor.withAlphaComponent(titlebarOpacity).cgColor
|
||||
titlebarContainer.layer?.backgroundColor = titlebarColor.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +182,12 @@ class TerminalWindow: NSWindow {
|
||||
|
||||
// MARK: -
|
||||
|
||||
func updateToolbar() {
|
||||
newTabButtonImageLayer = nil
|
||||
effectViewIsHidden = false
|
||||
}
|
||||
|
||||
private var newTabButtonImage: NSImage? = nil
|
||||
private var newTabButtonImageLayer: VibrantLayer? = nil
|
||||
|
||||
// Since we are coloring the new tab button's image, it doesn't respond to the
|
||||
@ -209,7 +215,12 @@ class TerminalWindow: NSWindow {
|
||||
guard let newTabButtonImageView: NSImageView = newTabButton.subviews.first(where: {
|
||||
$0 as? NSImageView != nil
|
||||
}) as? NSImageView else { return }
|
||||
guard let newTabButtonImage = newTabButtonImageView.image else { return }
|
||||
|
||||
if newTabButtonImage == nil {
|
||||
newTabButtonImage = newTabButtonImageView.image
|
||||
}
|
||||
|
||||
guard let newTabButtonImage else { return }
|
||||
|
||||
let isLightTheme = backgroundColor.isLightColor
|
||||
|
||||
@ -242,8 +253,6 @@ class TerminalWindow: NSWindow {
|
||||
backgroundColor.luminance < 0.05
|
||||
}
|
||||
|
||||
lazy var backgroundColorWithOpacity: NSColor = backgroundColor.withAlphaComponent(titlebarOpacity)
|
||||
|
||||
private func updateTabsForVeryDarkBackgrounds() {
|
||||
guard hasVeryDarkBackground else { return }
|
||||
|
||||
@ -255,13 +264,15 @@ class TerminalWindow: NSWindow {
|
||||
guard let activeTabBackgroundView = titlebarContainer.firstDescendant(withClassName: "NSTabButton")?.superview?.subviews.last?.firstDescendant(withID: "_backgroundView")
|
||||
else { return }
|
||||
|
||||
activeTabBackgroundView.layer?.backgroundColor = backgroundColorWithOpacity.cgColor
|
||||
titlebarContainer.layer?.backgroundColor = backgroundColorWithOpacity.highlight(withLevel: 0.14)?.cgColor
|
||||
activeTabBackgroundView.layer?.backgroundColor = titlebarColor.cgColor
|
||||
titlebarContainer.layer?.backgroundColor = titlebarColor.highlight(withLevel: 0.14)?.cgColor
|
||||
} else {
|
||||
titlebarContainer.layer?.backgroundColor = backgroundColorWithOpacity.cgColor
|
||||
titlebarContainer.layer?.backgroundColor = titlebarColor.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Split zooming
|
||||
|
||||
private func updateResetZoomTitlebarButtonVisibility() {
|
||||
guard let tabGroup, let resetZoomTitlebarAccessoryViewController else { return }
|
||||
|
||||
@ -282,24 +293,6 @@ class TerminalWindow: NSWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// We have to regenerate a toolbar when the titlebar tabs setting changes since our
|
||||
// custom toolbar conditionally generates the items based on this setting. I tried to
|
||||
// invalidate the toolbar items and force a refresh, but as far as I can tell that
|
||||
// isn't possible.
|
||||
private func generateToolbar() {
|
||||
let terminalToolbar = TerminalToolbar(identifier: "Toolbar")
|
||||
|
||||
toolbar = terminalToolbar
|
||||
toolbarStyle = .unifiedCompact
|
||||
if let resetZoomItem = terminalToolbar.items.first(where: { $0.itemIdentifier == .resetZoom }) {
|
||||
resetZoomItem.view = resetZoomToolbarButton
|
||||
resetZoomItem.view!.removeConstraints(resetZoomItem.view!.constraints)
|
||||
resetZoomItem.view!.widthAnchor.constraint(equalToConstant: 22).isActive = true
|
||||
resetZoomItem.view!.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||
}
|
||||
updateResetZoomTitlebarButtonVisibility()
|
||||
}
|
||||
|
||||
private func generateResetZoomButton() -> NSButton {
|
||||
let button = NSButton()
|
||||
button.target = nil
|
||||
@ -356,6 +349,24 @@ class TerminalWindow: NSWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// We have to regenerate a toolbar when the titlebar tabs setting changes since our
|
||||
// custom toolbar conditionally generates the items based on this setting. I tried to
|
||||
// invalidate the toolbar items and force a refresh, but as far as I can tell that
|
||||
// isn't possible.
|
||||
func generateToolbar() {
|
||||
let terminalToolbar = TerminalToolbar(identifier: "Toolbar")
|
||||
|
||||
toolbar = terminalToolbar
|
||||
toolbarStyle = .unifiedCompact
|
||||
if let resetZoomItem = terminalToolbar.items.first(where: { $0.itemIdentifier == .resetZoom }) {
|
||||
resetZoomItem.view = resetZoomToolbarButton
|
||||
resetZoomItem.view!.removeConstraints(resetZoomItem.view!.constraints)
|
||||
resetZoomItem.view!.widthAnchor.constraint(equalToConstant: 22).isActive = true
|
||||
resetZoomItem.view!.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||
}
|
||||
updateResetZoomTitlebarButtonVisibility()
|
||||
}
|
||||
|
||||
// Find the NSTextField responsible for displaying the titlebar's title.
|
||||
private var titlebarTextField: NSTextField? {
|
||||
guard let titlebarContainer = contentView?.superview?.subviews
|
||||
@ -382,14 +393,15 @@ 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()
|
||||
|
||||
// For titlebar tabs, we want to hide the separator view so that we get rid
|
||||
// of an aesthetically unpleasing shadow.
|
||||
hideTitleBarSeparators()
|
||||
}
|
||||
|
||||
// For titlebar tabs, we want to hide the separator view so that we get rid
|
||||
// of an aesthetically unpleasing shadow.
|
||||
private func hideTitleBarSeparators() {
|
||||
guard titlebarTabs else { return }
|
||||
|
||||
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
||||
@ -589,7 +601,7 @@ fileprivate class WindowButtonsBackdropView: NSView {
|
||||
layer?.backgroundColor = .clear
|
||||
} else {
|
||||
let systemOverlayColor = NSColor(cgColor: CGColor(genericGrayGamma2_2Gray: 0.0, alpha: 0.45))!
|
||||
let titlebarBackgroundColor = terminalWindow.backgroundColorWithOpacity.blended(withFraction: 1, of: systemOverlayColor)
|
||||
let titlebarBackgroundColor = terminalWindow.titlebarColor.blended(withFraction: 1, of: systemOverlayColor)
|
||||
|
||||
let highlightedColor = terminalWindow.hasVeryDarkBackground ? terminalWindow.backgroundColor : .clear
|
||||
let backgroundColor = terminalWindow.hasVeryDarkBackground ? titlebarBackgroundColor : systemOverlayColor
|
||||
|
Reference in New Issue
Block a user