NSScrollPocket overlay appearing on scroll views in NSSplitViewController on macOS Tahoe

I have an NSSplitViewController with three columns:

  1. sidebar
  2. full-height content view with NSScrollView/NSTableView
  3. detail view.

There's no (visible) titlebar and no toolbar.

This layout has worked fine for years, but in Tahoe an unwanted overlay (~30-50px high) appears at the top of any column containing a scroll view with table content. Xcode suggests it's an NSScrollPocket.

My research suggests it...

  • Only affects columns with NSScrollView
  • Plain NSView columns are unaffected
  • Overlay height varies (~50px or ~30px depending on how I mess with title / toolbar settings)
  • Disabling titlebar/toolbar settings reduces but doesn't eliminate the overlay

The overlay obscures content and there doesn't appear to be any API to control its visibility. Is this intended behavior, and if so, is there a way to disable it for applications that don't need this UI element?

If it helps visualise the desired result, the app is https://indigostack.app

Any guidance would be appreciated!

I'm seeing the same problem. I was investigating the titlebar itself, your post helped me by identifying the real culprit - thanks!

The use of NSSplitViewController is not relevant, it's enough to e.g. put NSTableView inside a titlebar-less window with NSWindowStyleMaskFullSizeContentView, titleVisibility = NSWindowTitleHidden and titlebarAppearsTransparent = YES. Despite having no visible titlebar, the pocket meant for it is still present.

My affected window is essentially the same thing as Xcode's welcome window, which however doesn't suffer from it, so I wonder what they do differently...

I don't think there's any public API for this, certainly not documented one, scrollEdgeEffectStyle is SwiftUI-only. You can see that WebKit has to do some private API sorcery with NSScrollPocket...

In my case at least, hiding the pocket is enough to fix the visual artifacts, so I grudgingly resorted to that:

static NSView* FindSubviewOfClass(NSView *root, Class cls)
{
    if (!root || !cls)
        return nil;

    for (NSView *sub in root.subviews) {
        if ([sub class] == cls) {
            return sub;
        }
        NSView *found = FindSubviewOfClass(sub, cls);
        if (found)
            return found;
    }

    return nil;
}

...

NSView *pocket = FindSubviewOfClass(scrollView, @"NSScrollPocket");
if (pocket)
    pocket.hidden = YES;

@vslavik very glad to hear it's not just me having this problem. With Apple never giving an official OS release date, I'm stressed, because my app is visually broken, and for all I know Tahoe might be released in a week. And I didn't know for certain whether the issue is my bad code, or Apple's bad code, or something else entirely. There's a lot of uncertainty for me!

Thanks for the suggested fix; I had tried to completely remove the view without success, but hopefully hiding it will work for me also!

NSScrollPocket overlay appearing on scroll views in NSSplitViewController on macOS Tahoe
 
 
Q