Applying scroll edge effects to views outside an NSScrollView

I’m developing a text editor. In the main pane of a window managed by NSSplitViewController, I place an NSTextView enclosed in an NSScrollView alongside a custom NSView subclass that displays line numbers.

The issue is that the line number view sits outside the scroll view, so it does not participate in the visual effects applied by the title bar or by an NSSplitViewItemAccessoryViewController attached to the parent view controller.

This problem has existed since around macOS 26, but it appears to be more noticeable in macOS 27 Beta 1.

Due to various implementation requirements, my line number view cannot be implemented as a subclass of NSRulerView. In this situation, is there any supported way to ensure that accessory view and toolbar effects are also properly applied to views that are outside the scroll view?

The attached screenshot demonstrates a case where the edge effect is not applied correctly. The line number view on the left side does not participate in the effect and instead appears to visually break through it.

Answered by Frameworks Engineer in 892434022

Thanks for the question. I love CotEditor!

As my colleague mentioned, one way to achieve this would be to have the editor scroll view extend the full width of the window, and have the line number view overlap with the editor. In the case of horizontally-scrolling text (line wrapping disabled), you could draw an opaque background on the line number view to avoid line numbers drawing directly on top of the editor’s text. The editor content and scroller insets will have to be adjusted on the leading edge to avoid intersecting with the line number view.

I would also recommend looking into NSScrollView’s addFloatingSubview(_:for:) API so that the line numbers appear just above the scrolling content, but below visual effects.

Would it be possible to extend your scroll view to underlap the line numbers, and inset your content views to compensate?

Thank you for the suggestion.

Would it be possible to extend your scroll view to underlap the line numbers, and inset your content views to compensate?

I have tried that approach before, however, unfortunately, it did not work well in my case.

My text view can be configured to scroll horizontally instead of soft-wrapping lines at the window edge. In addition, the line number view can be made semi-transparent. As a result, when the text content scrolls underneath the line number area, I was unable to achieve correct visual compositing between the line numbers and the text view’s content.

For reference, the following screenshot shows the appearance of my application with its background transparency feature enabled.

Accepted Answer

Thanks for the question. I love CotEditor!

As my colleague mentioned, one way to achieve this would be to have the editor scroll view extend the full width of the window, and have the line number view overlap with the editor. In the case of horizontally-scrolling text (line wrapping disabled), you could draw an opaque background on the line number view to avoid line numbers drawing directly on top of the editor’s text. The editor content and scroller insets will have to be adjusted on the leading edge to avoid intersecting with the line number view.

I would also recommend looking into NSScrollView’s addFloatingSubview(_:for:) API so that the line numbers appear just above the scrolling content, but below visual effects.

Thank you for the suggestions. I’ll experiment with a few more approaches based on the ideas you provided.

The interaction between NSScrollView and NSTextView is quite complex, and there are still many aspects of their behavior that I don’t fully understand. You and your colleague's advice has been very helpful.

Thanks for the question. I love CotEditor!

Thank you! I’m glad to hear that. I’m always striving to make it the most macOS-native text editor possible.

Applying scroll edge effects to views outside an NSScrollView
 
 
Q