如何获取任意屏幕位置的最前端窗口并聚焦(macOS)
macOS 聚焦指定坐标窗口的实现方案
下面分别提供AppleScript、Swift、Python三种语言的实现方式,均无需模拟鼠标点击,直接通过系统API定位并激活目标窗口。
AppleScript 实现
利用System Events的hit test功能定位坐标处的UI元素,向上遍历找到所属窗口后激活对应应用及窗口。
-- 替换为目标坐标(原点为屏幕左上角) set targetX to 500 set targetY to 300 tell application "System Events" set hitItems to hit test {targetX, targetY} if hitItems is not {} then set currentItem to item 1 of hitItems -- 向上遍历父元素,直到找到窗口 repeat while class of currentItem is not window set currentItem to parent of currentItem if currentItem is missing value then exit repeat end repeat if class of currentItem is window then set targetApp to application process of currentItem -- 激活应用并将窗口置为最前端 set frontmost of targetApp to true set frontmost of currentItem to true end if end if end tell
注意:需要给运行脚本的应用(如Script Editor)开启「系统设置-隐私与安全性-辅助功能」权限。
Swift 实现
基于AppKit和Quartz框架,获取屏幕窗口列表并按层级排序,筛选包含目标坐标的窗口后激活对应应用。
import AppKit func activateWindow(at point: CGPoint) { guard let windowInfos = CGWindowListCopyWindowInfo([.optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID) as? [[String: Any]] else { return } // 按窗口层级从高到低排序(值越大越靠前) let sortedWindows = windowInfos.sorted { ($0[kCGWindowOrderingKey as String] as? Int ?? 0) > ($1[kCGWindowOrderingKey as String] as? Int ?? 0) } let screen = NSScreen.main! // 转换坐标:输入Y为屏幕左上角原点,系统原生Y以屏幕底部为原点 let convertedPoint = CGPoint(x: point.x, y: screen.frame.height - point.y) for windowInfo in sortedWindows { guard let bounds = windowInfo[kCGWindowBounds as String] as? [String: CGFloat], let x = bounds["X"], let y = bounds["Y"], let width = bounds["Width"], let height = bounds["Height"] else { continue } let windowFrame = CGRect(x: x, y: y, width: width, height: height) if windowFrame.contains(convertedPoint) { guard let pid = windowInfo[kCGWindowOwnerPID as String] as? pid_t, let app = NSRunningApplication(processIdentifier: pid) else { continue } app.activate(options: .activateIgnoringOtherApps) print("Activated window at \(point) (app: \(app.bundleIdentifier ?? "unknown"))") return } } } // 替换为目标坐标 activateWindow(at: CGPoint(x: 500, y: 300))
使用方式:将代码保存为.swift文件,通过swiftc filename.swift -o activateWindow编译为可执行文件,运行前需给可执行文件开启辅助功能权限。
Python 实现
通过pyobjc桥接macOS原生框架,实现逻辑与Swift一致,适合Python开发者快速编写脚本。
import objc from Cocoa import NSRunningApplication, NSScreen from Quartz import ( CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements, kCGNullWindowID, kCGWindowBounds, kCGWindowOwnerPID, kCGWindowOrderingKey ) def activate_window_at(x, y): window_list = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID ) if not window_list: return # 按窗口层级从高到低排序 sorted_windows = sorted(window_list, key=lambda w: w[kCGWindowOrderingKey], reverse=True) screen_height = NSScreen.mainScreen().frame().size.height converted_y = screen_height - y for window in sorted_windows: bounds = window[kCGWindowBounds] window_x = bounds['X'] window_y = bounds['Y'] window_width = bounds['Width'] window_height = bounds['Height'] if (window_x <= x <= window_x + window_width) and (window_y <= converted_y <= window_y + window_height): pid = window[kCGWindowOwnerPID] app = NSRunningApplication.runningApplicationWithProcessIdentifier_(pid) if app: app.activateWithOptions_(1) # NSApplicationActivateIgnoringOtherApps print(f"Activated app: {app.bundleIdentifier()}") return # 替换为目标坐标 activate_window_at(500, 300)
注意:先安装依赖pip install pyobjc,并给Python解释器开启辅助功能权限。
内容的提问来源于stack exchange,提问作者poplitea
相关产品推荐
相关产品推荐

