How do I get a list of the window titles on the Mac OSX?

前端 未结 2 1306
半阙折子戏
半阙折子戏 2020-12-23 18:02

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 XGetWindowPro

2条回答
  •  清酒与你
    2020-12-23 18:18

    A few potentially useful references:

    • NSWindowList()
    • NSWorkspace -launchedApplications and +runningApplications
    • CGWindowListCreate() and CGWindowListCopyWindowInfo() (requires 10.5)
    • CGSGetWindowProperty()

    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].

提交回复
热议问题