toolbarappkitnstoolbar

macOS toolbar items in sidebar go to overflow menu when sidebar is hidden


I've a toolbar with a .sidebarTrackingSeparator and a NSTrackingSeparatorToolbarItem tracking the second divider.

There are toolbar items to in all three resulting toolbar divisions, but the middles ones are currently removed to avoid clutter. There is also the standard window (document) title: Full toolbar

The second tracking separator works fine. When the panel is collapsed the toolbar items are still visible with a small line indicating the position of the tracker. Collapsed panel

The sidebar tracking item gives problems. When the sidebar is collapsed, the toolbar items above it are moved to the overflow menu: Collapsed sidebar

There is plenty of space left on the toolbar, so there is little reason to move them to the overflow menu. Why are they moved there and not shown to the left of the window title?

The odd thing is that if my app starts with the sidebar already collapsed, then the items are shown in the location where I would expect them: Fresh start

They disappear as soon as the sidebar is shown and collapsed again.

Changing the (system supplied) sidebar tracker by a custom NSTrackingSeparatorToolbarItem gives the same behavior.

I create the toolbar items using a delegate:

extension WindowController: NSToolbarDelegate {
    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [.toggleSidebar, .importData, .toggleGrid, .toggleInspector, .sidebarTrackingSeparator, .splitViewTracker]
    }

    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [.toggleSidebar, .importData, .sidebarTrackingSeparator, .toggleGrid, .splitViewTracker, .toggleInspector]
    }

    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        let item = NSToolbarItem(itemIdentifier: itemIdentifier)

        switch itemIdentifier {
           ...
        case .splitViewTracker:
                return NSTrackingSeparatorToolbarItem(identifier: itemIdentifier, splitView: window!.contentViewController!.view.subviews[0] as! NSSplitView, dividerIndex: 1)
        default:
            break
        }

        return item
    }

How can I make sure that the sidebar toolbar items are still shown on the toolbar when the sidebar is collapsed (and there is sufficient space)?


Solution

  • This is a bug introduced in macOS Sonoma, the workaround is to make the minimumThickness of the Sidebar be sufficient for the two items displayed above it.

    A better approach would be to file a bug report and let Apple fix it as soon as possible.