问题描述
我正在 Mac 上开展一个项目,该项目跟踪用户的活动。我使用这些常量来获取当前窗口的名称并验证用户是否已将其更改为另一个窗口:
static let ownerPid: String = "kCGWindowOwnerPID"
static let ownerName: String = "kCGWindowOwnerName"
static let ownerWindowName: String = "kCGWindowOwnerName"
static let windowName: String = "kCGWindowName"
var currentOwnerName: String {
let currentPid = NSWorkspace.shared.frontmostApplication?.processIdentifier
let windowList = CGWindowListcopyWindowInfo([.optionOnScreenOnly],kCGNullWindowID) as! Array<Dictionary<String,AnyHashable>>
let window = windowList.first(where: {
guard let pid = $0[Constans.ownerPid] as? pid_t else { return false }
return currentPid == pid
})
_ = windowList.filter({
guard let pid = $0[Constans.ownerPid] as? pid_t,let _ = window?[Constans.ownerName],let _ = window?[Constans.windowName] else {
return false
}
if currentPid == pid {
print("From window \(window?[Constans.windowName])")
}
return currentPid == pid
})
let ownerName = window?[Constans.ownerWindowName] as? String ?? ""
return ownerName
}
这里使用的是 currentOwnerName(),这里我们依赖于不同窗口之间的转换:
private func performSnapshot(result: @escaping (trackerResult) -> ()) {
guard continueTracking else { return }
let delay = dispatchTime.Now() + dispatchTimeInterval.seconds(1)
dispatchQueue.global(qos: .background).asyncAfter(deadline: delay) { [weak self] in
guard let strongSelf = self else { return }
let output = strongSelf.currentOwnerName
if output != strongSelf.lastOutput {
strongSelf.lastOutput = output
dispatchQueue.main.async {
result(strongSelf.createActivity())
}
}
strongSelf.performSnapshot(result: result)
}
}
如您所见,我正在验证焦点窗口是否已更改为另一个窗口。它工作正常,但问题在于用户要更改该应用程序内的选项卡的情况。
示例:
- 用户正在使用 Chrome 并且他正在切换到 Xcode - 此活动将被正确跟踪,跟踪器将捕获带有窗口名称和窗口转换的数据;
- 用户正在使用 Chrome,但更改选项卡后不会捕获更改,因为我们在同一窗口中操作。如果用户将 Chrome 窗口最小化并将其恢复,它将起作用,但我想确保在不最小化的情况下捕获活动。
您是否知道我们可以使用一些方法或机制来验证用户是否会更改我们正在跟踪的当前窗口内的选项卡?我试图自己解决这个问题,但现在,我感到绝望。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)