ScrollView/ClipView weirdness.

I have been playing around with AppKit programming and I have a sample document based app with a scroll view and rulers. When

  1. The scrollbars are not overlay style (which is usually true for me because I have "show scroll bars always" set in preferences)

and

  1. the rulers are on

The clip view seems to extend throughout the scroll view and the document can be seen through the scroll bars. However if I turn the rulers off, then the clip view seems to not include the scroll bars, and so the document is not visible through the scroll bars, having been clipped to the rectangle that lies inside the scroll bars. Additionally in this case, the small area in the lower right hand corner of the screen between the two scroll bars is white, even though all of my views have a light gray background.

If the scroll bar style is overlay, then everything seems to work as expected: the clip view always includes the scroll bars.

Is this a bug related to legacy style scrollbars or (more likely) have I just screwed something up? I should add that the window and the entire view hierarchy have been built programmatically. It is not in the xib.

Here is a sample program to demonstrate the problem. Using Xcode, create a new document project using interface: xib, language: swift

Once that is done, delete Document.xib, go into Document.swift and add the following method:

override func makeWindowControllers() {
    let controller = MyWC(document: self)
    addWindowController(controller)
    controller.showWindow(self)
    controller.window?.makeFirstResponder(nil)
}

Then make a new Swift file named MyWC.swift with this content:

import AppKit

class MyWC: NSWindowController {
    
    init(document: Document) {
        
        let window = NSWindow(
            contentRect: NSRect(x: 0.0, y: 100.0, width: 700.0, height: 500.0),
            styleMask: [.titled, .closable, .miniaturizable, .resizable],
            backing: .buffered,
            defer: false
        )
        
        super.init(window: window)
        
        window.minSize = NSSize(width: 200, height: 200)
        
        let myScrollView = NSScrollView()
        let contentView = NSView(frame: NSRect(x: 0.0, y: 0.0, width: 800.0, height: 600.0))
        let clipView = NSClipView(frame: myScrollView.contentView.frame)
        
        clipView.backgroundColor = NSColor.blue
        clipView.drawsBackground = true
        
        myScrollView.clipsToBounds = true
        myScrollView.contentView = clipView
        myScrollView.documentView = contentView
        
        myScrollView.hasHorizontalRuler = true
        myScrollView.hasVerticalRuler = true
        myScrollView.rulersVisible = true
        
        myScrollView.hasVerticalScroller = true
        myScrollView.hasHorizontalScroller = true
        myScrollView.autohidesScrollers = false
        myScrollView.scrollerStyle = .legacy
        
        contentView.wantsLayer = true
        contentView.layer!.backgroundColor = NSColor.red.cgColor
                
        window.contentView = myScrollView
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Build and run the project. Notice that the red color "shows through" the scroll bars. If you expand the window, the blue color of the NSClipView also shows through the scroll bars. I think this is how it is supposed to be. Now edit the MyWC class to set

        myScrollView.rulersVisible = false

And then run it again. This time, the red color of contentView does not show through the scroll bars. Instead the scroll bars are blue, showing the clipView background color. And the lower right corner between the scrollbars is white. To me, this seems to be wrong. First, rulers being invisible shouldn't cause the scrollbars to pick up a different background color and second, the lower right corner certainly shouldn't be white.

ScrollView/ClipView weirdness.
 
 
Q