【问题标题】:How can I detect/observe when third party app launches a full screen process?如何检测/观察第三方应用程序何时启动全屏进程?
【发布时间】:2015-04-18 06:54:20
【问题描述】:
我想为游戏玩家构建一个帮助应用程序,并构建一些额外的功能,我想观察/计时某些第三方游戏的行为,更具体地说,当游戏实际启动全屏过程时。
例如:我的应用是系统托盘应用,游戏有一个带有大厅和菜单屏幕的“启动器”应用。一旦游戏启动了额外的进程,通常 OS X 会切换分辨率(可选)并且我的应用会以某种方式得到通知。然后我可以启动一个计时器。一旦游戏比赛结束,或者进程关闭,或者游戏不再全屏,我的应用会收到第二个通知,我可以停止计时器。
是否有官方的 Apple API 提供任何方式来观察/轮询应用程序是否全屏和/或启动我可以可靠地假设它是实际游戏屏幕的其他窗口?
【问题讨论】:
标签:
objective-c
macos
cocoa
【解决方案1】:
我怀疑你会找到一个完全全面的解决方案。应用可以通过多种方式实现全屏体验,但大多数都不提供有关这一事实的通知。
全屏应用可以修改NSApplication的presentationOptions来隐藏Dock和菜单栏。另一个应用可以使用键值观察来监控其应用对象的currentSystemPresentationOptions属性,这将反映当前的系统状态。
全屏应用可以捕获显示(尽管 Apple 不鼓励这种技术)。您可以尝试通过调用CGDisplayIsCaptured() 来检测这一点,尽管它自 10.9 以来已被弃用且没有替代品。如果您使用CGDisplayRegisterReconfigurationCallback() 注册回调,则可能会在某些内容捕获显示时被调用。但是,捕获显示有点关于,它会阻止其他进程注意到这些变化,所以可能不会。在这种情况下,您必须进行投票。您还可以轮询当前的显示模式;改变模式是游戏首先捕获显示的主要原因。
全屏游戏也可以只创建一个屏幕大小的无边框窗口,并将其窗口级别设置为位于 Dock 和菜单栏(以及其他应用程序的窗口)前面。没有关于此的通知。您可以使用CGWindowList API 检测它,但您必须轮询。例如,您可以调用 CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID) 并遍历字典,查找屏幕大小和高于 kCGStatusWindowLevel 的窗口级别的字典。
(您也许可以使用 Accessibility API 在最前面的窗口发生变化时获得通知,因此您只需在发生这种情况时进行轮询。)
【解决方案2】:
如果没有通知,您将无法观察到通知。所以首先你需要知道你想要观察的应用程序是否真的发送了一个可观察的通知。未经他们计划的同意,您不能“挂钩”到其他应用程序。