Skip to content

fix(welcome): keep the welcome toolbar at Icon Only - #3146

Merged
datlechin merged 4 commits into
TableProApp:mainfrom
shuvroroy:fix/welcome-toolbar-label-layout
Sep 28, 2026
Merged

datlechin merged 4 commits into
TableProApp:mainfrom
shuvroroy:fix/welcome-toolbar-label-layout

Conversation

@shuvroroy

@shuvroroy shuvroroy commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The welcome window's toolbar is built for three icon buttons and a search field in a fixed 900x600 window, but on macOS 15 and later a right-click on it offered Icon and Text and Text Only. Choosing Icon and Text put titles under New Connection and New Group and AppKit's own "Search" caption under the search field, and the toolbar grew taller.

The toolbar now stays at Icon Only and offers no display-mode choice, the same way Contacts, Calendar, Music and App Store handle their fixed toolbars.

Root cause

WelcomeWindowController did declare a fixed toolbar: an NSToolbar with displayMode = .iconOnly and allowsUserCustomization = false. That declaration never reached the toolbar on screen, for two reasons:

  1. On macOS 14 and later the list pane is an NSHostingController with sceneBridgingOptions = [.toolbars]. Setting contentViewController makes SwiftUI replace window.toolbar with its own toolbar. That toolbar has an empty identifier, no autosave, and allowsDisplayModeCustomization == true. Measured on macOS 27.
  2. allowsDisplayModeCustomization (macOS 15) is separate from allowsUserCustomization and defaults to true. So even the original toolbar never opted out of the display-mode menu.

Fix

  • WelcomeWindowController.makeWelcomeWindow() builds the window. It is an NSWindow subclass whose toolbar didSet fixes whichever toolbar is installed at Icon Only: the original toolbar on macOS 13, and SwiftUI's replacement on 14 and later, whenever it arrives. Measured: the setter runs for both, and the lock survives a SwiftUI state change, a root view swap and re-showing the window.
  • No app-owned Toolbar submenu, custom label style, KVO snap-back or extra observable object. Apple ships no app with its own Icon and Text setting, and no display mode puts titles beside icons. Titles beside the icons would also show every title twice if the system mode were ever on (measured).
  • macOS 14 needs no code. NSToolbar.h says allowsDisplayModeCustomization "defaults to YES for apps linked on macOS 15.0 and above". Before that, AppKit offers the display-mode menu only on a toolbar with allowsUserCustomization set, and the toolbar SwiftUI installs has it off. Measured by stamping a probe binary as linked against the macOS 14 SDK (vtool -set-build-version macos 14.0 14.0) and running it on macOS 27. The non-customizable toolbar, both AppKit-owned and SwiftUI-bridged, showed an empty context menu. The same binary linked against SDK 27 offered Icon and Text, Icon Only and Text Only. This is AppKit's own compatibility path on macOS 27, not a run on a macOS 14 machine.

This replaces the earlier version of this PR, which added View Options > Toolbar > Icon and Text / Icon Only. The review found that setting was never saved, made the system menu a control that did nothing on macOS 14, and needed a second observable object passed through four constructors. Locking the toolbar fixes the same bug with none of that.

Before / After

Before, in Icon and Text (titles under the icons and a Search caption):

Welcome toolbar in Icon and Text

After, the only mode the toolbar has, Icon Only:

Welcome toolbar in Icon Only

Right-clicking an empty part of the toolbar now shows no display-mode items. I did not capture a new screenshot: another session was running a load test on this machine, and a second TablePro process would have disturbed it.

Testing

  • WelcomeToolbarTests (3 cases) runs against the real makeWelcomeWindow(). It covers the window's own toolbar, a toolbar assigned later, and the toolbar SwiftUI installs for a scene-bridged hosting controller with a .searchable field. 3 of 3 pass.
  • Negative control: with the lock removed from the window subclass, all 3 fail.
  • swiftlint lint --strict on both changed Swift files: 0 violations.
  • No UI test. The only way to exercise this is right-clicking AppKit's own NSToolbarView background. No existing UI test does that, and XCUITest has no deterministic way to hit an empty toolbar spot instead of the search field or a button.

@shuvroroy

Copy link
Copy Markdown
Contributor Author

@datlechin Not sure failing test are relevant with this changes

@datlechin datlechin changed the title fix(welcome): keep the toolbar on one row in Icon and Text mode fix(welcome): keep the welcome toolbar at Icon Only Sep 28, 2026
@datlechin
datlechin merged commit ce7808c into TableProApp:main Sep 28, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants