【问题标题】:How to track the location of a window belonging to another app如何跟踪属于另一个应用程序的窗口的位置
【发布时间】:2021-03-13 22:48:54
【问题描述】:

当在 macOS 上与 Zoom 或 Skype/Teams 共享特定窗口时,它们会在该窗口(属于不同的应用程序)周围绘制一个红色或绿色的高亮边框,以表明它正在被共享。边框实时跟随目标窗口,可调整大小、z-order 变化等。

查看示例:

可以使用哪些 macOS API 和技术来实现此效果?

【问题讨论】:

  • 前几天有一个几乎相同的话题。它被解雇了,我想。不是你写的吗?
  • Accessibility API 不是这样做的唯一方法,但是您需要用户同意以避免被禁止进入沙盒,这就是要走的路。并确保即使是 Zoom 和 Skype 也在使用 API。好吧,也许 WebRTC 涉及..但仍然要从 wkwebview 外部共享屏幕,他们至少在安装时需要用户同意。
  • 当然,他们有录屏权限,但没有访问权限。此外,可访问性观察者仅在窗口移动后触发,但这些应用程序都没有显示任何明显的更新延迟。
  • 如果您只是在谈论绘制绿框(而不是实际捕获内容),您可以使用沙盒应用程序可用的CGWindowListCopyWindowInfo 和相关 API 找到窗口的位置。绘制边框可以通过创建覆盖在原始窗口顶部的自己的透明窗口来完成,然后在其中绘制一个绿色框。如果我们可以重新提出这个问题,我会进一步详细说明。
  • @Hypherion kCGWindowLayer 应该帮助解决这个问题以及 relativeToWindow 参数。如果您巧妙地过滤并花时间使代码正确,那么计算相交矩形应该非常快。当不涉及 API 调用或 IO 时,您会惊讶于现代处理器上的数值运算有多快。 CGWindowList API 很快。 SonOfGrab 示例代码是尝试这些东西的绝佳平台。 developer.apple.com/library/archive/samplecode/SonOfGrab

标签: objective-c macos cocoa core-graphics


【解决方案1】:

您可以使用CGWindowListCopyWindowInfo 和相关 API 找到窗口的位置,这些 API 可用于沙盒应用。

这是一个非常快速和高效的 API,速度快到可以被轮询。 SonOfGrab 示例代码是尝试这些东西的绝佳平台。

您还可以使用+[NSEvent addGlobalMonitorForEventsMatchingMask:handler:](在沙盒中提供)安装全局事件点击来跟踪鼠标向下、拖动和鼠标向上事件,然后您可以在用户开始或释放拖动时立即响应。这样你的反应就会很敏捷。

(通过创建自己的透明窗口来绘制边框,该窗口略大于您正在跟踪的窗口,并且与您正在跟踪的窗口处于同一窗口层。然后简单地在其中绘制一个漂亮的绿色框。我不是完全确定设置z-order。这部分的细节最好作为一个单独的问题。)

【讨论】:

  • 我会试试这个。以前当我尝试获取窗口信息和相交矩形时,由于频繁轮询,我的应用程序基本上被阻止了。我想这是因为我是在主队列上做的,所以会使用新的方法,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
相关资源
最近更新 更多