Native tabs accessory view visibility issue
The user is reporting that for standard, native tabs, the update accessory view is not visible in the titlebar when it should be. This seems to be a macOS app issue.
Let me search for code related to:
- Update accessory view
- Native tabs implementation
- Titlebar configuration
I'll start by searching for relevant code.
I'll help you fix the update accessory view visibility issue with native tabs. Let me search for the relevant code.
I can see the issue. In TerminalWindow.swift, when a tab bar appears (native tabs), the update accessory view is removed (line 216-218) but it's only restored when the tab bar disappears (line 227-229). For native tabs, the tab bar remains visible, so the update accessory never gets re-added.
The issue is that the code assumes having a tab bar and having titlebar accessories are mutually exclusive, but they should both be visible for native tabs. Let me check if there's a specific reason for this removal:
I see. There are different window types:
TerminalWindow- standard, native tabs (the issue you're reporting)TitlebarTabsVenturaTerminalWindowandTitlebarTabsTahoeTerminalWindow- custom titlebar tabs
The comment on line 208-210 says the SwiftUI titlebar accessory causes content view scaling issues when a tab bar is present. However, this shouldn't apply to standard native tabs the same way it applies to the custom titlebar tab implementations.
Let me check if there's a way to distinguish between standard native tabs and the custom implementations:
Malformed JSON: '{"task": "Analyze the issue with update accessory view visibility in native tabs. In TerminalWindow.swift, when native tabs are shown, both resetZoomAccessory and updateAccessory are removed in tabBarDidAppear() due to content view scaling issues with SwiftUI. However, for standard native tabs (not the custom titlebar tabs), these accessories should remain visible. \n\nThe key questions:\n1. Is there a way to distinguish between standard native tabs (tabbingMode = .automatic) and custom titlebar tabs implementations?\n2. Should the accessory views be visible for standard native tabs?\n3. If yes, what's the best way to fix this without reintroducing the content view scaling bug?", "files": /Users/mitchellh/Documents/ghostty/macos/Sources/Features/Terminal/Window Styles/TerminalWindow.swift, "context": "The user reports that for standard, native tabs, the update accessory view is not visible in the titlebar when it should be. The code currently removes both resetZoomAccessory and updateAccessory when any tab bar appears (tabBarDidAppear), but only restores them when the tab bar disappears (tabBarDidDisappear).\n\nFor custom titlebar tab implementations (TitlebarTabsVenturaTerminalWindow, TitlebarTabsTahoeTerminalWindow), removing these accessories might be correct. But for standard native tabs in TerminalWindow, they should probably remain visible.{"task": "Review the tab bar detection and accessory view removal logic in TerminalWindow.swift. The issue is that for standard native tabs, the update accessory view is removed when the tab bar appears (line 216-218) but never restored because the tab bar remains visible. \n\nThe comment says \"having a SwiftUI titlebar accessory causes our content view scaling to be wrong\" but this might only apply to the custom titlebar tab implementations (TitlebarTabsVenturaTerminalWindow, TitlebarTabsTahoeTerminalWindow), not to standard native macOS tabs.\n\nQuestions:\n1. Is there a way to detect if we're using standard native tabs vs the custom titlebar tabs?\n2. Should the update accessory view remain visible for standard native tabs?\n3. What's the best fix - keep the accessory visible for native tabs, or is the scaling issue real for all tab types?", "files": ["/Users/mitchellh/Documents/ghostty/macos/Sources/Features/Terminal/Window Styles/TerminalWindow.swift"], "context": "The user reports that for standard native tabs, the update accessory view is not visible in the titlebar when it should be. The TerminalWindow base class removes both the resetZoomAccessory and updateAccessory when a tab bar appears, supposedly due to content view scaling issues with SwiftUI accessories. But these might only be relevant for the custom titlebar tab implementations, not standard native tabs."}'.
TL;DR:
Yes. For standard native tabs (NSTabBar), the reset-zoom and update accessories should remain visible. The current workaround that removes SwiftUI titlebar accessories when the tab bar appears is unnecessary for native tabs and causes them to disappear permanently.Recommended approach (simple path):
- Stop removing SwiftUI accessories when the AppKit NSTabBar appears.
- Keep tabBarDidDisappear() as-is (idempotent “ensure present” is harmless).
- Add a clarifying comment so future custom tab-strip work doesn’t re-introduce this regression.
Minimal change:
- Replace tabBarDidAppear() with a no-op (or just delete the removal code).
Suggested diff (conceptual):
- TerminalWindow.tabBarDidAppear():
- Remove:
- if let idx = titlebarAccessoryViewControllers.firstIndex(of: resetZoomAccessory) { removeTitlebarAccessoryViewController(at: idx) }
- if let idx = titlebarAccessoryViewControllers.firstIndex(of: updateAccessory) { removeTitlebarAccessoryViewController(at: idx) }
- Optionally replace with comment:
// For native NSTabBar, keep SwiftUI accessories visible. Previous removal was specific to custom tab-strips.
- Remove:
- Rationale and trade-offs:
- The removal was originally to work around content scaling issues with custom titlebar tabs; it shouldn’t apply to AppKit’s native NSTabBar.
- Current logic removes accessories on tab bar appearance but never re-adds them while the bar is visible, breaking the update pill and reset-zoom UI.
- Minimal, targeted fix; no new APIs or state required.
- Trade-off: If a rare macOS version still exhibits the scaling bug even with native tabs, this change could reintroduce it. That has not been observed in standard setups.
- Risks and guardrails:
- Risk: Content view scaling bug resurfaces on some OS builds.
- Mitigations:
- Gate the old behavior behind a feature flag or OS-version check if you can reproduce issues (e.g., only remove on specific macOS versions where it’s confirmed).
- Add a debug log when a tab bar is detected and when accessories are removed/kept to aid future triage.
- When to consider the advanced path:
- If you plan to ship a custom titlebar tab strip again.
- If QA reproduces scaling issues on specific OS versions with native tabs.
- Optional advanced path (only if relevant):
- Introduce a mode flag (usesCustomTitlebarTabs) and only perform accessory removal when that mode is on. Alternatively, change addTitlebarAccessoryViewController to pass through the detected tab VC so tabBarDidAppear(native: Bool) can conditionally remove accessories only for non-NSTabBar cases.
Effort: S (<1h).
Perfect! The oracle confirms that for standard native tabs, the accessory views should remain visible. The removal was only necessary for custom titlebar tabs implementations. Let me fix this:
@@ -204,19 +204,11 @@
return childViewController.identifier == Self.tabBarIdentifier
}
private func tabBarDidAppear() {
// Remove our reset zoom accessory. For some reason having a SwiftUI
// titlebar accessory causes our content view scaling to be wrong.
// Removing it fixes it, we just need to remember to add it again later.
if let idx = titlebarAccessoryViewControllers.firstIndex(of: resetZoomAccessory) {
removeTitlebarAccessoryViewController(at: idx)
}
// Also remove update accessory for the same reason
if let idx = titlebarAccessoryViewControllers.firstIndex(of: updateAccessory) {
removeTitlebarAccessoryViewController(at: idx)
}
// For standard native tabs (NSTabBar), SwiftUI titlebar accessories work correctly
// and should remain visible. The previous removal was specific to custom titlebar
// tab implementations and caused accessories to disappear permanently with native tabs.
}
private func tabBarDidDisappear() {
if styleMask.contains(.titled) {
Thread
Reference Thread
T-5b64618e-3884-4bf9-87cb-e041f755279f