Suppy
Suppy

Reputation: 171

How do I get default title bar height of a NSWindow?

I created an OS/X app that when it runs, I position the window in the center of the screen. In order to do this, it's essential that I include the title bar height in my calculation of the y value.

Is there a way to determine the default title bar? I'd expect (based on my experience with other windowing systems) that I have to query the window manager somehow...

Upvotes: 17

Views: 13962

Answers (3)

Ky -
Ky -

Reputation: 32083

I've come up with this solution. Note that when the window's styleMask includes fullSizeContentView, this returns 0.0, because in that case the titlebar effectively has no height.

As a Swift extension:

extension NSWindow {
    var titlebarHeight: CGFloat {
        frame.height - contentRect(forFrameRect: frame).height
    }
}

Usage:

let titlebarHeight = someWindow.titlebarHeight

As an Objective-C Category-Extension:

@implementation NSWindow (TitleBarHeight)

- (CGFloat) titlebarHeight
{
    return self.frame.size.height - [self contentRectForFrameRect: self.frame].size.height;
}

@end

Usage:

CGFloat titlebarHeight = someWindow.titlebarHeight;

Upvotes: 19

vomi
vomi

Reputation: 1163

Answer for computing the height of the toolbar/titlebar area when using .fullSizeContentView on NSWindow

if let windowFrameHeight = self.view.window?.contentView?.frame.height,
    let contentLayoutRectHeight = self.view.window?.contentLayoutRect.height {
    let fullSizeContentViewNoContentAreaHeight = windowFrameHeight - contentLayoutRectHeight
}

fullSizeContentViewNoContentAreaHeight is the height you want. This is important to compute this value dynamically, because if you have an app using NSDocument and if the user creates a new document, the system might open this new document in a new tab. You might do this in updateViewConstraints() to detect this kind of changes.

Source: https://developer.apple.com/videos/play/wwdc2016/239/

Upvotes: 9

Ken Thomases
Ken Thomases

Reputation: 90541

It's not clear if you want to center the content rect and then build the frame rect to keep the content rect centered, or if you want to center the frame rect and are interested in the corresponding content rect.

In either case, NSWindow has methods that will help. Before you have an instance, you can use the class methods +frameRectForContentRect:styleMask: and +contentRectForFrameRect:styleMask:. Those take into account the window style as expressed by the style mask, but do not take any toolbar the eventual window may have into account.

If you're working with an existing instance, you can use the methods -frameRectForContentRect: and -contentRectForFrameRect:. Those use the current style of the window and take its toolbar into account, too. (The toolbar is within the frame rect but not the content rect.)

You seem determined to use the actual center of the screen for the window. However, you should consider using the -center method of NSWindow. It positions the window horizontally centered but actually higher than the true vertical center of the screen. It does that deliberately since that's deemed more prominent and immediate for the user.

Upvotes: 6

Related Questions