4

我知道我能做到

tell application "Safari" to id of window 1

获取 Safari 的窗口 ID。但是,这只适用于 Applescriptable 应用程序。我希望能够编写一个将 PID 作为输入并输出窗口 ID 的程序。(如果您好奇,这将用于将窗口 ID 提供给未记录的“CGSMoveWorkspaceWindowList”,以在 10.6 上的空间之间移动应用程序。)

根据这个问题,可以通过带有 Objective-C 的 OSX Accessibility API 中未记录的 API 来实现。不幸的是,作者没有具体说明有关它的任何其他信息。

当然,我没有嫁给 Objective-C,我只是想通过任何可能的方式从 PID 中获取 WID。如果有人知道如何,另一种可能性是从当前激活/最前面的进程中获取 WID(我有一个命令行工具来激活给定的 PID)。

编辑:感谢weichsel 为我指明了正确的路径,我编写了一个程序来输出所有窗口数据。

#include <Carbon/Carbon.h>

// compile as such:
//  gcc -framework carbon -framework foundation GetWindowList.c

int main(int argc, char **argv) {

    CFArrayRef windowList;

    if (argc != 1) {
        printf("usage: %s\n", argv[0]);
        exit(1);
    }

    windowList = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    NSLog(CFSTR("Array: %@"), windowList);
    CFRelease(windowList);

}

然后,我使用 Python 来解析所有数据,主要是因为我对如何在 Objective-C 中做到这一点一无所知,而且 Python 可能会减少代码行数。=D

import os
import re

PID_WID_List = []
temp = os.popen('./GetWindowList 2>&1').read().strip().split('},')
for i in temp:
    match = re.search('kCGWindowOwnerPID = (\d+);', i)
    pid = match.group(1)
    match = re.search('kCGWindowNumber = (\d+);', i)
    wid = match.group(1)
    PID_WID_List.append((pid, wid))

请注意,NSLog 将所有内容都写入 system.log,因此这种方法不适合无限检查循环。

再次感谢weichsel。

4

1 回答 1

3

您链接到的问题已经包含部分答案。
获取有序窗口列表(包括它们的 ID 和级别)的 Objective-C 方法是Quartz Window Services API (CGWindowList...)。

Apple 提供了“Son of Grab”示例代码项目,可让您探索所有返回的值CGWindowListCopyWindowInfo
https ://developer.apple.com/library/mac/samplecode/SonOfGrab/

虽然窗口信息字典没有明确包含“最前面”键,但您应该能够通过过滤列表中的元素kCGWindowLayer == 0并选择第一个元素(列表从前到后排序)来找到正确的窗口。
字典还包含一个kCGWindowOwnerPID键。

于 2013-06-06T07:05:45.960 回答