Enable reset zoom button when `macos-titlebar-style = tabs` and only one tab (#7502)

This is the conversion of #7496 into a PR. The problem was discussed in
#3288: When `macos-titlebar-style = tabs`, the reset zoom button doesn't
appear with only a single tab, i.e., no tab bar.

This fix was simply to remove an unnecessary branch, as the titlebar
style doesn't make any difference for the required logic. If the tab bar
is visible, you should unconditionally hide the titlebar's button and
rely on the per-tab buttons. If the tab bar is not visible, you should
hide or show the titlebar button depending on `surfaceIsZoomed`.

One wrinkle was that the main toolbar title started showing on top of
the tabs. Turns out it was previously not showing only because it would
always be pushed into the hidden overflow menu. With the reset zoom
button present (either hidden or visible, but always there), this no
longer happens reliably, presumably due to some cascading change in the
overflow calculations. In any case, it seems brittle to rely on this way
of concealing the main title, so I added a few lines of code to properly
hide it when the tab bar is visible.

Screenshots:
![Screenshot 2025-06-01 at 15 42
37](https://github.com/user-attachments/assets/893ba88e-a7e0-4d2f-8d08-45af4a2ba11b)
![Screenshot 2025-06-01 at 15 42
51](https://github.com/user-attachments/assets/f45db556-15a9-4655-96df-c41a34a80ec2)
![Screenshot 2025-06-01 at 15 42
58](https://github.com/user-attachments/assets/645cfe42-014c-4259-afd4-489b8ccdb311)
pull/7504/head
Mitchell Hashimoto 2025-06-02 09:18:09 -07:00 committed by GitHub
commit 3638916819
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 18 deletions

View File

@ -25,6 +25,16 @@ class TerminalToolbar: NSToolbar, NSToolbarDelegate {
} }
} }
var titleIsHidden: Bool {
get {
titleTextField.isHidden
}
set {
titleTextField.isHidden = newValue
}
}
override init(identifier: NSToolbar.Identifier) { override init(identifier: NSToolbar.Identifier) {
super.init(identifier: identifier) super.init(identifier: identifier)

View File

@ -153,7 +153,7 @@ class TerminalWindow: NSWindow {
// This is required because the removeTitlebarAccessoryViewController hook does not // This is required because the removeTitlebarAccessoryViewController hook does not
// catch the creation of a new window by "tearing off" a tab from a tabbed window. // catch the creation of a new window by "tearing off" a tab from a tabbed window.
if let tabGroup = self.tabGroup, tabGroup.windows.count < 2 { if let tabGroup = self.tabGroup, tabGroup.windows.count < 2 {
hideCustomTabBarViews() resetCustomTabBarViews()
} }
super.becomeKey() super.becomeKey()
@ -372,21 +372,10 @@ class TerminalWindow: NSWindow {
private func updateResetZoomTitlebarButtonVisibility() { private func updateResetZoomTitlebarButtonVisibility() {
guard let tabGroup, let resetZoomTitlebarAccessoryViewController else { return } guard let tabGroup, let resetZoomTitlebarAccessoryViewController else { return }
let isHidden = tabGroup.isTabBarVisible ? true : !surfaceIsZoomed if !titlebarAccessoryViewControllers.contains(resetZoomTitlebarAccessoryViewController) {
addTitlebarAccessoryViewController(resetZoomTitlebarAccessoryViewController)
if titlebarTabs { }
resetZoomToolbarButton.isHidden = isHidden resetZoomTitlebarAccessoryViewController.view.isHidden = tabGroup.isTabBarVisible ? true : !surfaceIsZoomed
for (index, vc) in titlebarAccessoryViewControllers.enumerated() {
guard vc == resetZoomTitlebarAccessoryViewController else { return }
removeTitlebarAccessoryViewController(at: index)
}
} else {
if !titlebarAccessoryViewControllers.contains(resetZoomTitlebarAccessoryViewController) {
addTitlebarAccessoryViewController(resetZoomTitlebarAccessoryViewController)
}
resetZoomTitlebarAccessoryViewController.view.isHidden = isHidden
}
} }
private func generateResetZoomButton() -> NSButton { private func generateResetZoomButton() -> NSButton {
@ -549,17 +538,22 @@ class TerminalWindow: NSWindow {
let isTabBar = titlebarAccessoryViewControllers[index].identifier == Self.TabBarController let isTabBar = titlebarAccessoryViewControllers[index].identifier == Self.TabBarController
super.removeTitlebarAccessoryViewController(at: index) super.removeTitlebarAccessoryViewController(at: index)
if (isTabBar) { if (isTabBar) {
hideCustomTabBarViews() resetCustomTabBarViews()
} }
} }
// To be called immediately after the tab bar is disabled. // To be called immediately after the tab bar is disabled.
private func hideCustomTabBarViews() { private func resetCustomTabBarViews() {
// Hide the window buttons backdrop. // Hide the window buttons backdrop.
windowButtonsBackdrop?.isHidden = true windowButtonsBackdrop?.isHidden = true
// Hide the window drag handle. // Hide the window drag handle.
windowDragHandle?.isHidden = true windowDragHandle?.isHidden = true
// Reenable the main toolbar title
if let toolbar = toolbar as? TerminalToolbar {
toolbar.titleIsHidden = false
}
} }
private func pushTabsToTitlebar(_ tabBarController: NSTitlebarAccessoryViewController) { private func pushTabsToTitlebar(_ tabBarController: NSTitlebarAccessoryViewController) {
@ -568,6 +562,11 @@ class TerminalWindow: NSWindow {
generateToolbar() generateToolbar()
} }
// The main title conflicts with titlebar tabs, so hide it
if let toolbar = toolbar as? TerminalToolbar {
toolbar.titleIsHidden = true
}
// HACK: wait a tick before doing anything, to avoid edge cases during startup... :/ // HACK: wait a tick before doing anything, to avoid edge cases during startup... :/
// If we don't do this then on launch windows with restored state with tabs will end // If we don't do this then on launch windows with restored state with tabs will end
// up with messed up tab bars that don't show all tabs. // up with messed up tab bars that don't show all tabs.