What is changing the size of my window on first appearance?

I have some old code that a user has prodded me into trying to resolve. The issue is that the window does not size correctly on its first appearance.

Stepping through my code, on initial entry to the windowDidLoad method, the size is (800, 472), which seems to correspond with the size in Interface Builder. I go and calculate the size that I want, and in one case it turns out to be (1235, 435), and I use setContentSize to get the window to the correct size. However, it is not that size when it appears, and when I get a chance to look at it, the size is (816, 435). When it runs through the same code in response to the user setting the scale, the size is correctly (1235, 435). Just to be non-deterministic, sometimes the height is 411. The numbers may change, but the difference in height is always either 0 or 24.

Is there something that runs after windowDidLoad that changes the window size? Or any other clues to track down why the size changes?

Replies

(Deleted as inaccurate)

After a lot more experimentation, I've determined that it is nothing to do with something running after windowDidLoad. The problem occurs when I calculate the size of the window content. Here's a version of the code:

	NSScrollView *scrollView = self.myScrollView;
	MyContentView *myContentView = [scrollView documentView];
    NSSize contentSize = [[self.window contentView] bounds].size;
    NSSize viewSize = [scrollView contentSize];
    CGFloat verticalPadding = contentSize.height - viewSize.height;
    CGFloat horizontalPadding = contentSize.width - viewSize.width;
	NSSize myContentSize = [myContentView bounds].size;
    myContentSize = [NSScrollView frameSizeForContentSize:myContentSize
                                  horizontalScrollerClass:[NSScroller class]
                                    verticalScrollerClass:[NSScroller class]
                                               borderType:NSLineBorder
                                              controlSize:NSControlSizeRegular
                                            scrollerStyle:NSScrollerStyleOverlay];
    myContentSize.height += 1;
    myContentSize.width += 1;
	NSSize maximumSize = myContentSize;
    maximumSize.height += verticalPadding;
    maximumSize.width += horizontalPadding;

The problem is that viewSize, the size of the visible portion of the scroll view, can have one of two different values, which differ by 24. It seems to be arbitrary which of the two values is provided. Thus the maximum size, which is then set as the window content size with setContentSize, varies by 24, dependent on nothing that I can see.

  • Logging sizes produces these numbers for heights of contentSize, viewSize, myContentSize on several iterations of run, quit, run: window content size 420.0, scroll content size 367.0, view size 305.5; window content size 420.0, scroll content size 367.0, view size 305.5; window content size 420.0, scroll content size 343.0, view size 305.5; window content size 420.0, scroll content size 367.0, view size 305.5 Why the variation?

Add a Comment

There is actually some interaction with window restoration, which resets the size of the window after windowDidLoad. What is working is to delay the size calculation until after the window actually gets displayed (after restoration), by replacing [self calculateSize] (essentially the code above) at the end of windowDidLoad with this hack:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self calculateSize];
    });

This appears to point to a problem where the size of the various views is not always set correctly until the window has been displayed. However, I'd love to proved wrong and find out what is the actual cause.