🖥️

【AppKit】NSWindow.center()を自前で計算する

2021/07/12に公開

概要

ProjectでNSWindowをフォーカスされていないscreen上かつcenter()で表示される位置に表示したいことがあった。

前置き

NSWindowのcenter()は名前の通りscreen上でx軸y軸共に真ん中にくるように表示されるわけではなく、 実際にはx軸は真ん中y軸は真ん中よりやや上に表示される。

AppleのDocumentにも、以下の通りで、中央よりやや上に配置することで目につきやすいようにしているとある。

NSWindow.center()
Discussion
The window is placed exactly in the center horizontally and somewhat 
above center vertically. Such a placement carries a certain visual 
immediacy and importance. This method doesn’t put the window onscreen, 
however; use makeKeyAndOrderFront(_:) to do that.

You typically use this method to place a window—most likely an alert 
dialog—where the user can’t miss it. This method is invoked automatically 
when a panel is placed on the screen by the runModal(for:) method of the 
NSApplication class.

https://developer.apple.com/documentation/appkit/nswindow/1419090-center

center()の計算方法

SomeViewController.swift
func originalCenter() {
    guard let window = view.window, let visibleFrame = window.screen?.visibleFrame else { return }

    let pointX = (visibleFrame.width - window.frame.width) / 2
    let pointY = (visibleFrame.height - window.frame.height) / 4
    let point = NSPoint(x: pointX + visibleFrame.origin.x,
			y: pointY * 3 + visibleFrame.origin.y)
    window.setFrameOrigin(point)
}

図示

画像図示

解説

Menu Barを除いた領域(visibleFrame)からNSWindowのサイズを引き、NSWindowの余白が上下で1:3になるように計算している。
これで、NSWindow.center()と一致した挙動になる。

昔のHuman Interface Guidelineでは、1:2での記載があったので、そこをヒントにした結果、center()の計算方法を導き出せた
OS X Human Interface Guidelines

Discussion