Convert CGDisplay coordinates to NSScreen (AppKit) coordinates so blur windows on secondary displays are positioned correctly. swiftformat reformatting.

This commit is contained in:
Greg Neagle
2025-06-17 11:31:25 -07:00
parent abb511e6f8
commit 7bda74b2f1
@@ -4,24 +4,22 @@
// Heavily based on code by Bart Reardon in CocoaDialog
//
import Foundation
import Cocoa
import Foundation
class BlurWindow: NSWindow {
override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
super.init(contentRect: contentRect, styleMask: [.fullSizeContentView], backing: .buffered, defer: true)
}
override init(contentRect: NSRect, styleMask _: NSWindow.StyleMask, backing _: NSWindow.BackingStoreType, defer _: Bool) {
super.init(contentRect: contentRect, styleMask: [.fullSizeContentView], backing: .buffered, defer: true)
}
}
class BlurWindowController: NSWindowController {
var screen: CGDirectDisplayID? = nil
func updateWindowRect() {
if let screen {
let bounds = CGDisplayBounds(screen)
if let window = self.window {
let bounds = appKitDisplayBounds(screen)
if let window = window {
window.setFrame(bounds, display: true)
window.setFrameOrigin(bounds.origin)
}
@@ -29,29 +27,34 @@ class BlurWindowController: NSWindowController {
}
override func loadWindow() {
window = BlurWindow(contentRect: CGRect(x: 0, y: 0, width: 100, height: 100), styleMask: [], backing: .buffered, defer: true)
self.window?.contentViewController = BlurViewController()
self.window?.collectionBehavior = [.canJoinAllSpaces]
window = BlurWindow(
contentRect: CGRect(x: 0, y: 0, width: 100, height: 100),
styleMask: [],
backing: .buffered,
defer: true
)
window?.contentViewController = BlurViewController()
window?.collectionBehavior = [.canJoinAllSpaces]
if atLoginWindow() {
self.window?.canBecomeVisibleWithoutLogin = true
window?.canBecomeVisibleWithoutLogin = true
}
updateWindowRect()
}
}
class BlurViewController: NSViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError()
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError()
}
override func loadView() {
super.viewDidLoad()
self.view = NSView()
view = NSView()
}
override func viewWillAppear() {
@@ -75,26 +78,34 @@ class BlurViewController: NSViewController {
super.viewWillDisappear()
view.window?.contentView?.removeFromSuperview()
}
}
func getCGDisplayIds() -> [CGDirectDisplayID] {
var displayCount: UInt32 = 0
let err = CGGetActiveDisplayList(0, nil, &displayCount)
if err == .success {
var displayIDs: [CGDirectDisplayID] = Array(repeating: 0, count: Int(displayCount))
let err = CGGetActiveDisplayList(displayCount, &displayIDs, nil)
if err == .success {
return displayIDs
}
}
return []
}
/// Converts CGDisplayBounds to NSScreen.frame coordinates
func appKitDisplayBounds(_ display: CGDirectDisplayID) -> CGRect {
let bounds = CGDisplayBounds(display)
let mainDisplayHeight = CGDisplayBounds(CGMainDisplayID()).size.height
return CGRect(x: bounds.origin.x,
y: mainDisplayHeight - bounds.origin.y - bounds.size.height,
width: bounds.size.width,
height: bounds.size.height)
}
class BackgroundBlurrer {
var blurWindows = [BlurWindowController]()
func getCGDisplayIds() -> [CGDirectDisplayID] {
var displayCount: UInt32 = 0
let err = CGGetActiveDisplayList(0, nil, &displayCount)
if err == .success {
var displayIDs: [CGDirectDisplayID] = Array(repeating: 0, count: Int(displayCount))
let err = CGGetActiveDisplayList(displayCount, &displayIDs, nil)
if err == .success {
return displayIDs
}
}
return []
}
init() {
for screen in getCGDisplayIds() {
let blurWindow = BlurWindowController()
@@ -107,12 +118,12 @@ class BackgroundBlurrer {
// React to display connected / disconnected / resized events
NotificationCenter.default.addObserver(
self,
selector: #selector(self.updateBlur),
selector: #selector(updateBlur),
name: NSApplication.didChangeScreenParametersNotification,
object: nil
)
}
@objc func updateBlur() {
let currentScreens = getCGDisplayIds()
var existingScreens: Set<CGDirectDisplayID> = []
@@ -124,7 +135,7 @@ class BackgroundBlurrer {
blurWindow.screen = nil
} else {
existingScreens.insert(screen)
let screenRect = CGDisplayBounds(screen)
let screenRect = appKitDisplayBounds(screen)
let windowRect = blurWindow.window?.frame ?? .zero
if screenRect != windowRect {
// screen changed location or size
@@ -164,6 +175,4 @@ class BackgroundBlurrer {
}
blurWindows = [BlurWindowController]()
}
}