macos: hide the reset zoom titlebar accessory when tab bar is shown

pull/7588/head
Mitchell Hashimoto 2025-06-12 15:11:35 -07:00
parent 5c8f1948ce
commit 6ae8bd737a
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
3 changed files with 42 additions and 2 deletions

View File

@ -104,6 +104,26 @@ class TerminalWindow: NSWindow {
}
}
override func addTitlebarAccessoryViewController(_ childViewController: NSTitlebarAccessoryViewController) {
super.addTitlebarAccessoryViewController(childViewController)
// Tab bar is attached as a titlebar accessory view controller (layout bottom). We
// can detect when it is shown or hidden by overriding add/remove and searching for
// it. This has been verified to work on macOS 12 to 26
if childViewController.view.contains(className: "NSTabBar") {
viewModel.hasTabBar = true
}
}
override func removeTitlebarAccessoryViewController(at index: Int) {
if let childViewController = titlebarAccessoryViewControllers[safe: index],
childViewController.view.contains(className: "NSTabBar") {
viewModel.hasTabBar = false
}
super.removeTitlebarAccessoryViewController(at: index)
}
// MARK: Tab Key Equivalents
var keyEquivalent: String? = nil {
@ -348,6 +368,7 @@ extension TerminalWindow {
class ViewModel: ObservableObject {
@Published var isSurfaceZoomed: Bool = false
@Published var hasToolbar: Bool = false
@Published var hasTabBar: Bool = false
}
struct ResetZoomAccessoryView: View {
@ -355,7 +376,7 @@ extension TerminalWindow {
let action: () -> Void
var body: some View {
if viewModel.isSurfaceZoomed {
if viewModel.isSurfaceZoomed && !viewModel.hasTabBar {
VStack {
Button(action: action) {
Image("ResetZoom")

View File

@ -1,4 +1,8 @@
extension Array {
subscript(safe index: Int) -> Element? {
return indices.contains(index) ? self[index] : nil
}
/// Returns the index before i, with wraparound. Assumes i is a valid index.
func indexWrapping(before i: Int) -> Int {
if i == 0 {

View File

@ -42,6 +42,21 @@ extension NSView {
return false
}
/// Checks if the view contains the given class in its hierarchy.
func contains(className name: String) -> Bool {
if String(describing: type(of: self)) == name {
return true
}
for subview in subviews {
if subview.contains(className: name) {
return true
}
}
return false
}
/// Recursively finds and returns the first descendant view that has the given class name.
func firstDescendant(withClassName name: String) -> NSView? {
for subview in subviews {
@ -113,7 +128,7 @@ extension NSView {
}
/// Returns a string representation of the view hierarchy in a tree-like format.
private func viewHierarchyDescription(indent: String = "", isLast: Bool = true) -> String {
func viewHierarchyDescription(indent: String = "", isLast: Bool = true) -> String {
var result = ""
// Add the tree branch characters