2013-06-06 19 views
2

我知道我能做到如何以編程方式從10.6上的進程ID獲取OSX窗口ID? (使用AppleScript,Objective-C中,無論)

tell application "Safari" to id of window 1 

得到Safari瀏覽器的窗口ID。但是,這隻適用於Applescriptable應用程序。我希望能夠編寫一個程序,將一個PID作爲輸入並輸出窗口ID。 (如果您好奇,這將依次用於將窗口ID提供給無證「CGSMoveWorkspaceWindowList」以在10.6空間之間移動應用程序。)

根據this問題,可以通過未公開的文檔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 0的想法,和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。

回答

1

您鏈接到的問題已包含答案的一部分。
獲取有序窗口列表(包括它們的ID和級別)的Objective-C方法是Quartz Window Services API(CGWindowList ...)。

蘋果提供的「搶之子」的示例代碼項目,它允許你去探索通過CGWindowListCopyWindowInfo返回的所有值:
https://developer.apple.com/library/mac/samplecode/SonOfGrab/

雖然窗口信息字典裏沒有明確包含「最前面」鍵,您應該能夠通過過濾元素列表找到正確的窗口,其中kCGWindowLayer == 0並選擇第一個元素(該列表是從前到後排序的)。
該字典還包含一個kCGWindowOwnerPID密鑰。

+0

謝謝。 「抓鬥之子」的例子有點太複雜了,但我用最終解決方案更新了原來的問題。 – James

+0

很高興我能幫到你。感謝您粘貼您的Python代碼。 –

相關問題