I know that I can do
tell application "Safari" to id of window 1
to get the window ID of Safari. However, this only works for Applescriptable applications. I want to be able to write a program that will take a PID as input and output the window ID. (In case you are curious, this will be used in turn to supply the window ID to the undocumented "CGSMoveWorkspaceWindowList" to move applications between spaces on 10.6.)
According to this question, it is possible to do it via undocumented APIs in the OSX Accessibility API with Objective-C. Unfortunately, the author didn't specify any additional information about it.
Of course, I'm not married to Objective-C, I just want to get the WID from a PID by any means possible. One other possibility, if anyone knows how, is to get the WID from the currently activated/frontmost process (I have a command line tool to activate a given PID).
Edit: Thanks to weichsel pointing me down the right path, I made a program to output all window data.
#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);
}
Then, I used Python to parse all of the data, mostly because I have 0 idea on how to do that in Objective-C, and Python would probably be less lines of code anyway. =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))
Note that NSLog writes everything to system.log, so this method isn't suitable for an infinite checking loop.
Thanks again to weichsel.
The question you linked to already contains a part of the answer.
The Objective-C way to get an ordered list of windows (including their ID and level) is the Quartz Window Services API (CGWindowList...).
Apple provides the "Son of Grab" sample code project, that allows you to explore all values returned by CGWindowListCopyWindowInfo
:
https://developer.apple.com/library/mac/samplecode/SonOfGrab/
While the window information dictionary doesn't explicitly contain a "frontmost" key, you should be able to find the correct window by filtering the list for elements where kCGWindowLayer == 0
and choose the first element (the list is ordered front-to-back).
The dictionary also contains a kCGWindowOwnerPID
key.