You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift macOS开发中如何判断Safari是否处于前台激活状态

实现方法

你提到的NSWorkspace和NSRunningApplication就是实现这个需求的正确方案,CGWindowList本身不提供应用激活状态的判断能力,不需要遍历全量窗口列表来做前台应用检测,直接调用系统封装好的接口准确率更高、性能开销更低。

核心逻辑非常直接:

  • 通过NSWorkspace.shared.frontmostApplication直接获取当前处于前台激活状态的应用
  • 不要用应用名称做匹配判断:应用名存在多语言本地化改名、重名应用的问题,直接判断应用的固定Bundle ID即可,Safari的官方Bundle ID为com.apple.Safari
  • 你原有代码中对kCGWindowOwnerName的as!强制类型转换存在崩溃风险,建议避免使用强制解包

修改后的可运行代码如下:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    NSEvent.addGlobalMonitorForEvents(matching: .otherMouseDown) { event in
        print("鼠标按键按下,按钮编号:\(event.buttonNumber)")
        
        // 直接获取当前前台激活应用
        guard let frontmostApp = NSWorkspace.shared.frontmostApplication else {
            return
        }
        // 判断前台应用是否为Safari
        if frontmostApp.bundleIdentifier == "com.apple.Safari" {
            print("Safari处于前台激活状态,执行后续逻辑")
            
            // 如果后续仍需要获取Safari的窗口信息,再调用CGWindowList接口即可
            let options = CGWindowListOption(arrayLiteral: .excludeDesktopElements, .optionOnScreenOnly)
            if let windowListInfo = CGWindowListCopyWindowInfo(options, kCGNullWindowID) as? [[String: Any]] {
                // 通过kCGWindowOwnerPID匹配前台应用进程ID,过滤出属于当前前台Safari的窗口
                let safariPID = frontmostApp.processIdentifier
                let safariWindows = windowListInfo.filter { windowInfo in
                    guard let windowPID = windowInfo[kCGWindowOwnerPID as String] as? pid_t else {
                        return false
                    }
                    return windowPID == safariPID
                }
                print("Safari当前在屏窗口数量:\(safariWindows.count)")
            }
        }
    }
}

注意事项

  • 全局鼠标事件监控需要你的应用在系统设置的「隐私与安全性-辅助功能」中获得用户授权,否则无法收到全局的鼠标按键事件
  • 如果你只需要判断Safari是否在前台,完全不需要调用CGWindowListCopyWindowInfo接口,上面的前台应用判断逻辑已经可以满足需求
  • 如果需要兼容非系统默认安装路径的Safari,Bundle ID判断的方式依然生效,比匹配应用名可靠得多

内容的提问来源于stack exchange,提问作者Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:42:28