如何使用swift从core-grapics API获取窗口列表

per*_*lin 4 macos core-graphics swift

我试图从使用Swift的核心图形API获取OSX上的窗口列表(以便稍后捕获它们的图像).经过一些研究,我发现CGWindowListCopyWindowInfo Objective-C API调用具有以下签名:

CFArrayRef CGWindowListCopyWindowInfo(
   CGWindowListOption option,
   CGWindowID relativeToWindow
);
Run Code Online (Sandbox Code Playgroud)

参数

option:描述要返回的窗口词典的选项.通过典型选项,您可以返回所有窗口的字典,也可以返回relativeToWindow参数中指定的窗口上方或下方的窗口.有关更多信息,请参阅窗口列表选项常量.

relativeToWindow:在确定要返回的其他窗口词典时用作参考点的窗口的ID.对于不需要引用窗口的选项,此参数可以是kCGNullWindowID.

https://developer.apple.com/library/mac/documentation/Carbon/Reference/CGWindow_Reference/Reference/Functions.html

在我的快速应用程序中,我试图像这样使用它:

import Cocoa
import CoreFoundation

let option: CGWindowListOption = kCGWindowListOptionOnScreenOnly
let relativeToWindow: CGWindowID = kCGNullWindowID

let info = CGWindowListCopyWindowInfo(option, relativeToWindow)
Run Code Online (Sandbox Code Playgroud)

但XCode(游乐场)告诉我

  • 它不能使用int作为CGWindowListOption(kCGWindowListOptionOnScreenOnly == 0)
  • kCGNullWindowID是未解析的标识符

我在这做错了什么?

Mar*_*n R 9

  • kCGWindowListOptionOnScreenOnly是一个Int,你必须将其转换CGWindowListOptionaka UInt32.
  • C定义

    #define kCGNullWindowID ((CGWindowID)0) 
    
    Run Code Online (Sandbox Code Playgroud)

    没有导入Swift,因此你必须使用常量 0.

  • 此外,CGWindowListCopyWindowInfo()返回一个Unmanaged<CFArray>!,因此您必须调用takeRetainedValue() 返回的值(如"使用Cocoa数据类型"中所述).

一起:

let option = CGWindowListOption(kCGWindowListOptionOnScreenOnly)
let relativeToWindow = CGWindowID(0)
let info = CGWindowListCopyWindowInfo(option, relativeToWindow).takeRetainedValue()
Run Code Online (Sandbox Code Playgroud)

然后你可以枚举这个字典数组

for dict in info as! [ [ String : AnyObject] ] {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Swift 3更新:

if let info = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[ String : Any]] {
    for dict in info {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)