Swift macOS kCGWindowNameが出ない場合

Swift macOS kCGWindowNameが出ない場合

macOSアプリで、起動中の他のアプリ(Windw)の状態を列挙したい場合CGWindowListCopyWindowInfo()を使えば macOS上で起動しているWindowなどが列挙できます。下記はコード例です。

if let enumWindows = CGWindowListCopyWindowInfo([.optionAll], 0) {
	for windowInfo in enumWindows as NSArray {
		if let info = windowInfo as? NSDictionary {
			print("\(info)")
		}
	}
}

上記コードで、kCGWindowNumber・kCGWindowOwnerName・kCGWindowOwnerPID・kCGWindowBoundsなどの情報を取得することができます。しかし、kCGWindowNameは取得できないようです。kCGWindowNameを取得したい場合は、macOSの[システム環境設定|セキュリティーとプライバシー|画面収録]に開発中のアプリを登録することで、取得可能になります。

[システム環境設定|セキュリティーとプライバシー]
[システム環境設定|セキュリティーとプライバシー]
func getWindowText(_ windowInfo: NSDictionary) -> String {
	let windowName = windowInfo["kCGWindowName"]
	if (windowName != nil) {
		let windowText: String = windowName as! NSString as String
		return windowText
	} else {
		return ""
	}
}

func enumWindows() {
	if let enumWindows = CGWindowListCopyWindowInfo([.optionAll], 0) {
		for windowInfo in enumWindows as NSArray {
			if let info = windowInfo as? NSDictionary {
				let strWindowText:String = getWindowText(info)
				if (strWindowText.count > 0)  {
					print(strWindowText)
				}
			}
		}
	}
}

SwiftUI macOSでmakeKeyAndOrderFrontが機能しない場合

SwiftUI macOSでmakeKeyAndOrderFrontが機能しない場合

Xcode 12.3macOSアプリのプロジェクトをSwiftUIで作成した場合、windowをClose()してしまうとmakeKeyAndOrderFront()が機能しませんでした。makeKeyAndOrderFrontは、ウィンドウを表示させるメソッドでNSWindowに入っています。

macOSアプリ内でウィンドウを閉じた場合再表示できない原因は、NSWindowControllerで所有していないwindowは、ウィンドウが閉じられると解放してしまうためでした。

これらを回避してmakeKeyAndOrderFrontを機能させる方法の一つは、windowを閉じない処理を入れた[NSWindowをラップしたクラス]を作ってclose()をoverrideする。

class Window: NSWindow {
    override func close() {
        self.orderOut(NSApp)
    }
}

別の方法としては、SwiftUIでアプリ作成の場合ObservableObject継承したクラスを作成すると思うので、そのクラス内にでもNSWindowControllerを入れてしまう。

windowController = NSWindowController(window: window)

NSWindowControllerinitpublic init(window: NSWindow?)があるのでそこにAppDelegateなどで作ったwindowを入れます。

この2つの方法どちらかでmakeKeyAndOrderFrontが機能し閉じてもウィンドウが再表示されました。

2022 MJELD TECHNOLOGIES. ALL RIGHTS RESERVED