【问题标题】:Separating real and dummy windows returned by CGWindowListCopyWindowInfo分离由 CGWindowListCopyWindowInfo 返回的真实和虚拟窗口
【发布时间】:2019-10-18 14:35:23
【问题描述】:

我正在为 macOS 创建一个窗口切换器。

我正在使用CGWindowListCopyWindowInfo 来获取打开的窗口列表。

    let windows = CGWindowListCopyWindowInfo([.excludeDesktopElements], kCGNullWindowID)

我没有将optionOnScreenOnly 选项与CGWindowListCopyWindowInfo 一起使用,因为它不包括关闭-space 窗口。

但是,这会导致某些虚拟窗口也包含在窗口列表中。例如,Xcode 上每个打开的选项卡都有一个窗口。除了实际窗口外,VLC 播放器还有一个额外的不可见窗口。如果我使用optionOnScreenOnly,这些窗口将不存在。

有没有办法将这些虚拟窗口与实际窗口分开?

我探索了CGWindowListCopyWindowInfo 返回的字典中的kCGWindowLayerkCGWindowStoreType 键,但无法区分窗口。

编辑

我对 Swift 和 Objective-C 解决方案以及私有 API 调用持开放态度。

编辑 2

我知道这是可能的,因为应用程序 Witch 正确处理了这些情况。

【问题讨论】:

  • 来自 Witch 的常见问题解答:“Witch 使用称为 Accessibility API 的公共 API(应用程序编程接口)来获取有关其他程序中打开的窗口的信息。”
  • 你有一个我可以检查并尝试帮助你的最小工作示例吗?

标签: objective-c swift macos


【解决方案1】:

我不确定这是否涵盖了您感兴趣的所有案例,但如果我们采用 CGWindowListCopyWindowInfo() 返回的字典数组并按 kCGWindowNumber(窗口 ID)对条目进行分组,它看起来像我们最终会遇到以下三种情况之一:

  • 只有一个字典条目具有该窗口编号(它是一个简单的寡妇,可能在屏幕上或屏幕外)
  • 几个字典都有那个窗口 id,并且组中只有一个将键 kCGWindowIsOnscreen 设置为 1:其他的要么没有键,要么将其设置为 0。这意味着我们有一个带有多个选项卡的窗口,而设置了kCGWindowIsOnscreen 的条目是可见选项卡。
  • 几个字典都有那个窗口 id,没有一个将键 kCGWindowIsOnscreen 设置为 1(在所有情况下它都丢失或设置为 0)。这意味着我们有一个窗口,其中包含几个当前不在屏幕上的选项卡。

我假设您可能已经过滤掉了不在第 0 层 (kCGWindowLayer = 0) 中的任何内容。似乎我们视觉上视为“窗口”的大多数东西都在第 0 层(状态菜单项似乎在具有单个或低两位数的层中;小部件似乎在第 100 层左右......)。

我没有看到任何简单直接的方法来解决这个问题,但你应该能够将这个逻辑构建成可行的东西。

【讨论】:

    【解决方案2】:

    如何使用不同的方法,通过以下方式检查哪些应用正在运行和可见:

    let runningApps = NSWorkspace.shared.runningApplications.filter{ $0.activationPolicy == .regular }
    

    如果您print(runningApps),您将获得当前在您的工作区中运行的应用程序列表。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-21
      • 1970-01-01
      • 2011-07-14
      • 2023-03-22
      • 2021-04-27
      • 1970-01-01
      相关资源
      最近更新 更多