tags:

views:

112

answers:

1

I want to get the list of window titles of the currently running applications.

On windows I have EnumWndProc and GetWindowText.

On Linux I have XGetWindowProperty and XFetchName.

What is the Native Mac equivalent?

A: 

A few potentially useful references:

CGSGetWindowProperty is not officially documented, but I believe you can use it with the an item of NSWindowList() as follows (completely untested):

OSErr err;
CGSValue titleValue;
char *title;
CGSConnection connection = _CGSDefaultConnection();
int windowCount, *windows, i;

NSCountWindows(&windowCount);
windows = malloc(windowCount * sizeof(*windows));
if (windows) {
    NSWindowList(windowCount, windows);
    for (i=0; i < windowCount; ++i) {
        err = CGSGetWindowProperty(connection, windows[i], 
                    CGSCreateCStringNoCopy("kCGSWindowTitle"), 
                    &titleValue);
        title = CGSCStringValue(titleValue);
    }
    free(windows);
}

In AppleScript, it's really easy:

tell application "System Events" to get the title of every window of every process

You can call applescript from within an application using NSAppleScript or use appscript as an ObjC-AppleScript bridge. With Leopard, you can use the Scripting Bridge (more untested code):

SystemEventsApplication *systemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
SBElementArray *processes = [systemEvents processes];
for (SystemEventsProcess* process in processes) {
    NSArray *titles = [[process windows] arrayByApplyingSelector:@selector(title)];
}

You could even try it in one long call, if you don't care about readability.

SystemEventsApplication *systemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
NSArray *titles = [[[systemEvents processes] 
                     arrayByApplyingSelector:@selector(windows)] 
               arrayByApplyingSelector:@selector(arrayByApplyingSelector:) 
               withObject:@selector(title)];

The compiler will complain that @selector(title) is the wrong type, but it should work. Hand roll some delegation and you could turn the call into [[[systemEvents processes] windows] title].

outis
Note that AppleScript is using the accessibility interfaces, which are public and have C equivalents (see http://developer.apple.com/mac/library/documentation/Accessibility/Reference/AccessibilityLowlevel/). CGS* APIs are not only not documented, they may change at any time. (So, only use them if you're willing to test early and often on new OS versions and have no other choice.)
Nicholas Riley
Do you have a usage example for the Accessibility API? I had hoped to include it, but aren't familiar enough with it to provide how to use it.
outis
Also, it requires that Accessibility be enabled.
outis
You know what? I just tested the AppleScript solution, and getting the list of windows also requires enabling Accessibility.
outis
Sample Accessibility API code: http://developer.apple.com/mac/library/samplecode/UIElementInspector/index.html
outis