import CoreGraphics import os /// A single on-screen window as reported by the window server, reduced to /// the fields FocusFixer needs. Kept separate from the raw CGWindowList /// dictionary so the resolution logic below can be unit tested with /// synthetic data instead of the real window server. struct WindowInfo: Equatable { let ownerPID: pid_t let layer: Int let bounds: CGRect } enum WindowLocator { private static let logger = Logger(subsystem: "com.local.focusfixer", category: "WindowLocator") /// Resolves the owning process ID of the frontmost on-screen window /// under `point`, using the live window server state. static func ownerPID(at point: CGPoint) -> pid_t? { guard let list = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[String: Any]] else { logger.error("CGWindowListCopyWindowInfo returned nil") return nil } return ownerPID(at: point, in: list.compactMap(parse)) } /// Pure resolution logic: `windows` is assumed to be in front-to-back /// z-order, matching CGWindowListCopyWindowInfo's contract. Only /// layer-0 windows (ordinary app windows, excluding menu bar, Dock, /// Spotlight, and Control Center) are considered. static func ownerPID(at point: CGPoint, in windows: [WindowInfo]) -> pid_t? { for window in windows where window.layer == 0 && window.bounds.contains(point) { return window.ownerPID } return nil } private static func parse(_ dict: [String: Any]) -> WindowInfo? { guard let pid = dict[kCGWindowOwnerPID as String] as? pid_t, let layer = dict[kCGWindowLayer as String] as? Int, let boundsDict = dict[kCGWindowBounds as String] as? [String: Any], let bounds = CGRect(dictionaryRepresentation: boundsDict as CFDictionary) else { return nil } return WindowInfo(ownerPID: pid, layer: layer, bounds: bounds) } }