mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
Get unzoom button working with standard title/tab bar
To do this I forced a toolbar, so that we would have a place to put the button when no tabs were opened. I also took the opportunity to make the standard title/tab bar meld better with the terminal's background color, just as we do with titlebar tabs.
This commit is contained in:
@ -3,31 +3,6 @@ import Cocoa
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import GhosttyKit
|
import GhosttyKit
|
||||||
|
|
||||||
fileprivate class ZoomButtonView: NSView {
|
|
||||||
let target: Any
|
|
||||||
let action: Selector
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
init(frame frameRect: NSRect, target: Any, selector: Selector) {
|
|
||||||
self.target = target
|
|
||||||
self.action = selector
|
|
||||||
|
|
||||||
super.init(frame: frameRect)
|
|
||||||
|
|
||||||
let zoomButton = NSButton(image: NSImage(systemSymbolName: "arrow.down.right.and.arrow.up.left.square.fill", accessibilityDescription: nil)!, target: target, action: selector)
|
|
||||||
|
|
||||||
zoomButton.frame = bounds
|
|
||||||
zoomButton.isBordered = false
|
|
||||||
zoomButton.contentTintColor = .systemBlue
|
|
||||||
zoomButton.state = .on
|
|
||||||
zoomButton.imageScaling = .scaleProportionallyUpOrDown
|
|
||||||
addSubview(zoomButton)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The terminal controller is an NSWindowController that maps 1:1 to a terminal window.
|
/// The terminal controller is an NSWindowController that maps 1:1 to a terminal window.
|
||||||
class TerminalController: NSWindowController, NSWindowDelegate,
|
class TerminalController: NSWindowController, NSWindowDelegate,
|
||||||
TerminalViewDelegate, TerminalViewModel,
|
TerminalViewDelegate, TerminalViewModel,
|
||||||
@ -169,21 +144,15 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
text.setContentCompressionResistancePriority(.windowSizeStayPut, for: .horizontal)
|
text.setContentCompressionResistancePriority(.windowSizeStayPut, for: .horizontal)
|
||||||
text.postsFrameChangedNotifications = true
|
text.postsFrameChangedNotifications = true
|
||||||
|
|
||||||
let stackView = NSStackView(views: [text])
|
window.tab.accessoryView = NSStackView(views: [text])
|
||||||
// stackView.setHuggingPriority(.defaultHigh, for: .horizontal)
|
|
||||||
|
|
||||||
window.tab.accessoryView = stackView
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if surfaceIsZoomed {
|
if surfaceIsZoomed {
|
||||||
guard let stackView = window?.tabGroup?.selectedWindow?.tab.accessoryView as? NSStackView else { return }
|
guard let stackView = window?.tabGroup?.selectedWindow?.tab.accessoryView as? NSStackView,
|
||||||
|
let buttonView = window?.toolbar?.items.first(where: { $0.itemIdentifier == .unZoom })?.view
|
||||||
let zoomButton: ZoomButtonView = ZoomButtonView(frame: NSRect(x: 0, y: 0, width: 20, height: 20), target: self, selector: #selector(splitZoom(_:)))
|
else { return }
|
||||||
|
|
||||||
zoomButton.translatesAutoresizingMaskIntoConstraints = false
|
stackView.addArrangedSubview(buttonView)
|
||||||
zoomButton.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
|
||||||
zoomButton.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
|
||||||
stackView.addArrangedSubview(zoomButton)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,14 +212,10 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func windowDidUpdate(_ notification: Notification) {
|
private func updateToolbarUnZoomButton() {
|
||||||
updateToolbarZoomButton()
|
guard let buttonView = window?.toolbar?.items.first(where: { $0.itemIdentifier == .unZoom })?.view else { return }
|
||||||
}
|
|
||||||
|
|
||||||
private func updateToolbarZoomButton() {
|
buttonView.isHidden = !surfaceIsZoomed
|
||||||
guard let itemView = window?.toolbar?.items.last?.view as? ZoomButtonView else { return }
|
|
||||||
|
|
||||||
itemView.isHidden = !surfaceIsZoomed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - NSWindowController
|
//MARK: - NSWindowController
|
||||||
@ -307,6 +272,12 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
// when cascading.
|
// when cascading.
|
||||||
window.center()
|
window.center()
|
||||||
|
|
||||||
|
// Set the background color of the window
|
||||||
|
window.backgroundColor = NSColor(ghostty.config.backgroundColor)
|
||||||
|
|
||||||
|
// This makes sure our titlebar renders correctly when there is a transparent background
|
||||||
|
window.titlebarOpacity = ghostty.config.backgroundOpacity
|
||||||
|
|
||||||
// Handle titlebar tabs config option. Something about what we do while setting up the
|
// 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
|
// titlebar tabs interferes with the window restore process unless window.tabbingMode
|
||||||
// is set to .preferred, so we set it, and switch back to automatic as soon as we can.
|
// is set to .preferred, so we set it, and switch back to automatic as soon as we can.
|
||||||
@ -317,19 +288,14 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
window.tabbingMode = .automatic
|
window.tabbingMode = .automatic
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the background color of the window
|
|
||||||
window.backgroundColor = NSColor(ghostty.config.backgroundColor)
|
|
||||||
|
|
||||||
// Set a custom background on the titlebar - this is required for when
|
|
||||||
// titlebar tabs are used in conjunction with a transparent background.
|
|
||||||
window.setTitlebarBackground(
|
|
||||||
window
|
|
||||||
.backgroundColor
|
|
||||||
.withAlphaComponent(ghostty.config.backgroundOpacity)
|
|
||||||
.cgColor
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set a toolbar that is used with toolbar tabs
|
||||||
|
let toolbar = TerminalToolbar(identifier: "Toolbar")
|
||||||
|
toolbar.hasTitle = ghostty.config.macosTitlebarTabs
|
||||||
|
|
||||||
|
window.toolbar = toolbar
|
||||||
|
window.toolbarStyle = .unifiedCompact
|
||||||
|
|
||||||
// Initialize our content view to the SwiftUI root
|
// Initialize our content view to the SwiftUI root
|
||||||
window.contentView = NSHostingView(rootView: TerminalView(
|
window.contentView = NSHostingView(rootView: TerminalView(
|
||||||
@ -357,11 +323,6 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
window.tabGroup?.removeWindow(window)
|
window.tabGroup?.removeWindow(window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let toolbarZoomItem = window.toolbar?.items.last else { return }
|
|
||||||
var zoomButton: ZoomButtonView = ZoomButtonView(frame: NSRect(x: 0, y: 0, width: 20, height: 20), target: self, selector: #selector(splitZoom(_:)))
|
|
||||||
|
|
||||||
toolbarZoomItem.view = zoomButton
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shows the "+" button in the tab bar, responds to that click.
|
// Shows the "+" button in the tab bar, responds to that click.
|
||||||
@ -370,7 +331,7 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
guard let surface = self.focusedSurface?.surface else { return }
|
guard let surface = self.focusedSurface?.surface else { return }
|
||||||
ghostty.newTab(surface: surface)
|
ghostty.newTab(surface: surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - NSWindowDelegate
|
//MARK: - NSWindowDelegate
|
||||||
|
|
||||||
// This is called when performClose is called on a window (NOT when close()
|
// This is called when performClose is called on a window (NOT when close()
|
||||||
@ -450,7 +411,11 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func windowDidUpdate(_ notification: Notification) {
|
||||||
|
updateToolbarUnZoomButton()
|
||||||
|
}
|
||||||
|
|
||||||
// Called when the window will be encoded. We handle the data encoding here in the
|
// Called when the window will be encoded. We handle the data encoding here in the
|
||||||
// window controller.
|
// window controller.
|
||||||
func window(_ window: NSWindow, willEncodeRestorableState state: NSCoder) {
|
func window(_ window: NSWindow, willEncodeRestorableState state: NSCoder) {
|
||||||
@ -654,7 +619,7 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
|||||||
|
|
||||||
func zoomStateDidChange(to: Bool) {
|
func zoomStateDidChange(to: Bool) {
|
||||||
self.surfaceIsZoomed = to
|
self.surfaceIsZoomed = to
|
||||||
updateToolbarZoomButton()
|
updateToolbarUnZoomButton()
|
||||||
relabelTabs()
|
relabelTabs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
fileprivate extension NSToolbarItem.Identifier {
|
|
||||||
static let zoom = NSToolbarItem.Identifier("zoom")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom NSToolbar subclass that displays a centered window title,
|
// Custom NSToolbar subclass that displays a centered window title,
|
||||||
// in order to accommodate the titlebar tabs feature.
|
// in order to accommodate the titlebar tabs feature.
|
||||||
class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
||||||
static private let identifier = NSToolbarItem.Identifier("TitleText")
|
|
||||||
private let titleTextField = CenteredDynamicLabel(labelWithString: "👻 Ghostty")
|
private let titleTextField = CenteredDynamicLabel(labelWithString: "👻 Ghostty")
|
||||||
|
|
||||||
var titleText: String {
|
var titleText: String {
|
||||||
@ -19,16 +14,18 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
|||||||
titleTextField.stringValue = newValue
|
titleTextField.stringValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasTitle: Bool = false
|
||||||
|
|
||||||
override init(identifier: NSToolbar.Identifier) {
|
override init(identifier: NSToolbar.Identifier) {
|
||||||
super.init(identifier: identifier)
|
super.init(identifier: identifier)
|
||||||
|
|
||||||
delegate = self
|
delegate = self
|
||||||
|
|
||||||
if #available(macOS 13.0, *) {
|
if #available(macOS 13.0, *) {
|
||||||
centeredItemIdentifiers.insert(Self.identifier)
|
centeredItemIdentifiers.insert(.titleText)
|
||||||
} else {
|
} else {
|
||||||
centeredItemIdentifier = Self.identifier
|
centeredItemIdentifier = .titleText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +35,8 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
|||||||
var item: NSToolbarItem
|
var item: NSToolbarItem
|
||||||
|
|
||||||
switch itemIdentifier {
|
switch itemIdentifier {
|
||||||
case Self.identifier:
|
case .titleText:
|
||||||
item = NSToolbarItem(itemIdentifier: itemIdentifier)
|
item = NSToolbarItem(itemIdentifier: .titleText)
|
||||||
item.view = self.titleTextField
|
item.view = self.titleTextField
|
||||||
item.visibilityPriority = .user
|
item.visibilityPriority = .user
|
||||||
|
|
||||||
@ -55,8 +52,24 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
|||||||
item.maxSize = NSSize(width: 1024, height: self.titleTextField.intrinsicContentSize.height)
|
item.maxSize = NSSize(width: 1024, height: self.titleTextField.intrinsicContentSize.height)
|
||||||
|
|
||||||
item.isEnabled = true
|
item.isEnabled = true
|
||||||
case .zoom:
|
case .unZoom:
|
||||||
item = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier("zoom"))
|
item = NSToolbarItem(itemIdentifier: .unZoom)
|
||||||
|
|
||||||
|
let view = NSView(frame: NSRect(x: 0, y: 0, width: 20, height: 20))
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
view.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
|
||||||
|
let button = NSButton(image: NSImage(systemSymbolName: "arrow.down.right.and.arrow.up.left.square.fill", accessibilityDescription: nil)!, target: nil, action: #selector(TerminalController.splitZoom(_:)))
|
||||||
|
|
||||||
|
button.frame = view.bounds
|
||||||
|
button.isBordered = false
|
||||||
|
button.contentTintColor = .systemBlue
|
||||||
|
button.state = .on
|
||||||
|
button.imageScaling = .scaleProportionallyUpOrDown
|
||||||
|
view.addSubview(button)
|
||||||
|
|
||||||
|
item.view = view
|
||||||
default:
|
default:
|
||||||
item = NSToolbarItem(itemIdentifier: itemIdentifier)
|
item = NSToolbarItem(itemIdentifier: itemIdentifier)
|
||||||
}
|
}
|
||||||
@ -65,15 +78,19 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
||||||
return [Self.identifier, .space, .zoom]
|
return [.titleText, .flexibleSpace, .space, .unZoom]
|
||||||
}
|
}
|
||||||
|
|
||||||
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
||||||
// These space items are here to ensure that the title remains centered when it starts
|
// These space items are here to ensure that the title remains centered when it starts
|
||||||
// getting smaller than the max size so starts clipping. Lucky for us, three of the
|
// getting smaller than the max size so starts clipping. Lucky for us, two of the
|
||||||
// built-in spacers seems to exactly match the space on the left that's reserved for
|
// built-in spacers plus the un-zoom button item seems to exactly match the space
|
||||||
// the window buttons.
|
// on the left that's reserved for the window buttons.
|
||||||
return [Self.identifier, .space, .space, .zoom]
|
if hasTitle {
|
||||||
|
return [.titleText, .flexibleSpace, .space, .space, .unZoom]
|
||||||
|
} else {
|
||||||
|
return [.flexibleSpace, .unZoom]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,3 +109,8 @@ fileprivate class CenteredDynamicLabel: NSTextField {
|
|||||||
needsLayout = true
|
needsLayout = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension NSToolbarItem.Identifier {
|
||||||
|
static let unZoom = NSToolbarItem.Identifier("UnZoom")
|
||||||
|
static let titleText = NSToolbarItem.Identifier("TitleText")
|
||||||
|
}
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
class TerminalWindow: NSWindow {
|
class TerminalWindow: NSWindow {
|
||||||
|
var titlebarOpacity: CGFloat = 1 {
|
||||||
|
didSet {
|
||||||
|
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
||||||
|
$0.className == "NSTitlebarContainerView"
|
||||||
|
}) else { return }
|
||||||
|
|
||||||
|
titlebarContainer.wantsLayer = true
|
||||||
|
titlebarContainer.layer?.backgroundColor = backgroundColor.withAlphaComponent(titlebarOpacity).cgColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Both of these must be true for windows without decorations to be able to
|
// Both of these must be true for windows without decorations to be able to
|
||||||
// still become key/main and receive events.
|
// still become key/main and receive events.
|
||||||
override var canBecomeKey: Bool { return true }
|
override var canBecomeKey: Bool { return true }
|
||||||
@ -35,13 +46,12 @@ class TerminalWindow: NSWindow {
|
|||||||
// Used by the window controller to enable/disable titlebar tabs.
|
// Used by the window controller to enable/disable titlebar tabs.
|
||||||
var titlebarTabs = false {
|
var titlebarTabs = false {
|
||||||
didSet {
|
didSet {
|
||||||
changedTitlebarTabs(to: titlebarTabs)
|
self.titleVisibility = titlebarTabs ? .hidden : .visible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var windowButtonsBackdrop: WindowButtonsBackdropView? = nil
|
private var windowButtonsBackdrop: WindowButtonsBackdropView? = nil
|
||||||
private var windowDragHandle: WindowDragView? = nil
|
private var windowDragHandle: WindowDragView? = nil
|
||||||
private var storedTitlebarBackgroundColor: CGColor? = nil
|
|
||||||
private var newTabButtonImageLayer: VibrantLayer? = nil
|
private var newTabButtonImageLayer: VibrantLayer? = nil
|
||||||
|
|
||||||
// The tab bar controller ID from macOS
|
// The tab bar controller ID from macOS
|
||||||
@ -66,72 +76,22 @@ class TerminalWindow: NSWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called by titlebarTabs changing so that we can setup the rest of our window
|
override func awakeFromNib() {
|
||||||
private func changedTitlebarTabs(to newValue: Bool) {
|
super.awakeFromNib()
|
||||||
if (newValue) {
|
|
||||||
// By hiding the visual effect view, we allow the window's (or titlebar's in this case)
|
|
||||||
// background color to show through. If we were to set `titlebarAppearsTransparent` to true
|
|
||||||
// the selected tab would look fine, but the unselected ones and new tab button backgrounds
|
|
||||||
// would be an opaque color. When the titlebar isn't transparent, however, the system applies
|
|
||||||
// a compositing effect to the unselected tab backgrounds, which makes them blend with the
|
|
||||||
// titlebar's/window's background.
|
|
||||||
if let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
|
||||||
$0.className == "NSTitlebarContainerView"
|
|
||||||
}), let effectView = titlebarContainer.descendants(withClassName: "NSVisualEffectView").first {
|
|
||||||
effectView.isHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
self.titlebarSeparatorStyle = .none
|
// By hiding the visual effect view, we allow the window's (or titlebar's in this case)
|
||||||
|
// background color to show through. If we were to set `titlebarAppearsTransparent` to true
|
||||||
// We use the toolbar to anchor our tab bar positions in the titlebar,
|
// the selected tab would look fine, but the unselected ones and new tab button backgrounds
|
||||||
// so we make sure it's the right size/position, and exists.
|
// would be an opaque color. When the titlebar isn't transparent, however, the system applies
|
||||||
self.toolbarStyle = .unifiedCompact
|
// a compositing effect to the unselected tab backgrounds, which makes them blend with the
|
||||||
if (self.toolbar == nil) {
|
// titlebar's/window's background.
|
||||||
self.toolbar = TerminalToolbar(identifier: "Toolbar")
|
if let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
||||||
}
|
$0.className == "NSTitlebarContainerView"
|
||||||
|
}), let effectView = titlebarContainer.descendants(withClassName: "NSVisualEffectView").first {
|
||||||
// Set a custom background on the titlebar - this is required for when
|
effectView.isHidden = true
|
||||||
// titlebar tabs is used in conjunction with a transparent background.
|
|
||||||
self.restoreTitlebarBackground()
|
|
||||||
|
|
||||||
// Reset the new tab button image so that we are sure to generate a fresh
|
|
||||||
// one, tinted appropriately for the given theme.
|
|
||||||
self.newTabButtonImageLayer = nil
|
|
||||||
|
|
||||||
// We have to wait before setting the titleVisibility or else it prevents
|
|
||||||
// the window from hiding the tab bar when we get down to a single tab.
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.titleVisibility = .hidden
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// "expanded" places the toolbar below the titlebar, so setting this style and
|
|
||||||
// removing the toolbar ensures that the titlebar will be the default height.
|
|
||||||
self.toolbarStyle = .expanded
|
|
||||||
self.toolbar = nil
|
|
||||||
|
|
||||||
// Reset the appearance to whatever our app global value is
|
|
||||||
self.appearance = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign a background color to the titlebar area.
|
|
||||||
func setTitlebarBackground(_ color: CGColor) {
|
|
||||||
storedTitlebarBackgroundColor = color
|
|
||||||
|
|
||||||
guard let titlebarContainer = contentView?.superview?.subviews.first(where: {
|
|
||||||
$0.className == "NSTitlebarContainerView"
|
|
||||||
}) else { return }
|
|
||||||
|
|
||||||
titlebarContainer.wantsLayer = true
|
|
||||||
titlebarContainer.layer?.backgroundColor = color
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the titlebar has the assigned background color.
|
|
||||||
private func restoreTitlebarBackground() {
|
|
||||||
guard let color = storedTitlebarBackgroundColor else { return }
|
|
||||||
setTitlebarBackground(color)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is called by macOS for native tabbing in order to add the tab bar. We hook into
|
// This is called by macOS for native tabbing in order to add the tab bar. We hook into
|
||||||
// this, detect the tab bar being added, and override its behavior.
|
// this, detect the tab bar being added, and override its behavior.
|
||||||
override func addTitlebarAccessoryViewController(_ childViewController: NSTitlebarAccessoryViewController) {
|
override func addTitlebarAccessoryViewController(_ childViewController: NSTitlebarAccessoryViewController) {
|
||||||
@ -217,13 +177,13 @@ class TerminalWindow: NSWindow {
|
|||||||
override func update() {
|
override func update() {
|
||||||
super.update()
|
super.update()
|
||||||
|
|
||||||
guard titlebarTabs else { return }
|
titlebarSeparatorStyle = tabbedWindows != nil && !titlebarTabs ? .line : .none
|
||||||
|
|
||||||
// This is called when we open, close, switch, and reorder tabs, at which point we determine if the
|
// This is called when we open, close, switch, and reorder tabs, at which point we determine if the
|
||||||
// first tab in the tab bar is selected. If it is, we make the `windowButtonsBackdrop` color the same
|
// first tab in the tab bar is selected. If it is, we make the `windowButtonsBackdrop` color the same
|
||||||
// as that of the active tab (i.e. the titlebar's background color), otherwise we make it the same
|
// as that of the active tab (i.e. the titlebar's background color), otherwise we make it the same
|
||||||
// color as the background of unselected tabs.
|
// color as the background of unselected tabs.
|
||||||
if let index = windowController?.window?.tabbedWindows?.firstIndex(of: self) {
|
if let index = windowController?.window?.tabbedWindows?.firstIndex(of: self), titlebarTabs {
|
||||||
windowButtonsBackdrop?.isHighlighted = index == 0
|
windowButtonsBackdrop?.isHighlighted = index == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +199,8 @@ class TerminalWindow: NSWindow {
|
|||||||
$0 as? NSImageView != nil
|
$0 as? NSImageView != nil
|
||||||
}) as? NSImageView else { return }
|
}) as? NSImageView else { return }
|
||||||
guard let newTabButtonImage = newTabButtonImageView.image else { return }
|
guard let newTabButtonImage = newTabButtonImageView.image else { return }
|
||||||
guard let storedTitlebarBackgroundColor, let isLightTheme = NSColor(cgColor: storedTitlebarBackgroundColor)?.isLightColor else { return }
|
|
||||||
|
let isLightTheme = backgroundColor.isLightColor
|
||||||
|
|
||||||
if newTabButtonImageLayer == nil {
|
if newTabButtonImageLayer == nil {
|
||||||
let fillColor: NSColor = isLightTheme ? .black.withAlphaComponent(0.85) : .white.withAlphaComponent(0.85)
|
let fillColor: NSColor = isLightTheme ? .black.withAlphaComponent(0.85) : .white.withAlphaComponent(0.85)
|
||||||
@ -294,7 +255,9 @@ class TerminalWindow: NSWindow {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let view = WindowButtonsBackdropView(backgroundColor: storedTitlebarBackgroundColor ?? NSColor.windowBackgroundColor.cgColor)
|
let backdropColor = backgroundColor.withAlphaComponent(titlebarOpacity).usingColorSpace(colorSpace!)!.cgColor
|
||||||
|
|
||||||
|
let view = WindowButtonsBackdropView(backgroundColor: backdropColor)
|
||||||
view.identifier = NSUserInterfaceItemIdentifier("_windowButtonsBackdrop")
|
view.identifier = NSUserInterfaceItemIdentifier("_windowButtonsBackdrop")
|
||||||
titlebarView.addSubview(view)
|
titlebarView.addSubview(view)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user