Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 477
Phil Hannent Avatar asked Oct 22 '09 10:10

Phil Hannent


People also ask

How do I see all windows apps on Mac?

Show or move all open windows Show all open windows for the current app: Press Control-Down Arrow. If App Exposé is selected in Trackpad preferences, you can also swipe down with three fingers. To return to the desktop, press the keys again or swipe up.

How do you organize windows on a Mac?

Click and hold the full-screen button in the upper-left corner of a window. As you hold the button, the window shrinks and you can drag it to the left or right side of the screen. Release the button, then click a window on the other side of the screen to begin using both windows side by side.

How do I find hidden tabs on my Mac?

Press ⌘ + H to Hide while the ⌘ + Tab has the highlight on the desired app icon. Pressing ⌘ + H also unhides (or brings it back).

What is the title bar on Mac?

A title bar is a small strip that extends across the top of a window. It displays the title of the window and typically includes the close, minimize, and maximize buttons. In macOS, these buttons are on the left side of the title bar, while in Windows, they are on the right.


1 Answers

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

like image 173
outis Avatar answered Oct 19 '22 23:10

outis