b2cloud

7th February 2012

Monitoring Any Window in OS X

Guides | Tutorial By 5 years ago

In a project I’ve been working on recently I need to interact with other process’ windows on the Mac. The application lets you drag windows around that will ‘bolt-on’ to another application’s window and follow it around the screen.

Unfortunately unless you know how to do this, finding out information on how it’s done can be difficult (like most things). Initially my solution was to use Applescript. It worked ok, but was slow and wouldn’t tell me when a window was actively moving (if you were dragging it around the screen), only when the window was stationary. My Applescript solution was only compatible with Cocoa applicataions as well. On my quest to find a better solution I came across the very primitive CGWindowListCopyWindowInfo method. This will give you a massive list of all windows (including menu bars, the dock, etc etc) and a lot of information about them.

NSArray* windows = (id)CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
NSLog(@"%@", windows);
[windows release];
windows = nil;

Output:

{
    kCGWindowAlpha = 1;
    kCGWindowBounds =         {
        Height = 1024;
        Width = 1680;
        X = 4;
        Y = 22;
    };
    kCGWindowLayer = 0;
    kCGWindowMemoryUsage = 976400;
    kCGWindowName = iTunes;
    kCGWindowNumber = 309;
    kCGWindowOwnerName = iTunes;
    kCGWindowOwnerPID = 3588;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 2;
},
    {
    kCGWindowAlpha = 1;
    kCGWindowBounds =         {
        Height = 109;
        Width = 240;
        X = 1440;
        Y = 70;
    };
    kCGWindowLayer = 0;
    kCGWindowMemoryUsage = 75280;
    kCGWindowName = "";
    kCGWindowNumber = 199;
    kCGWindowOwnerName = Safari;
    kCGWindowOwnerPID = 446;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 2;
},
    {
    kCGWindowAlpha = 1;
    kCGWindowBounds =         {
        Height = 22;
        Width = 1680;
        X = 0;
        Y = 0;
    };
    kCGWindowLayer = 24;
    kCGWindowMemoryUsage = 5648;
    kCGWindowNumber = 194;
    kCGWindowOwnerName = SystemUIServer;
    kCGWindowOwnerPID = 363;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 2;
},

Note that unlike the lower-left origin that you use when positioning NSWindow‘s, this user upper-left coordinates.

From the list above you can obtain the kCGWindowNumber (datatype: CGWindowID) and use the same function above specifying the window id to obtain information for just one window.

CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, windowID);

This will give back an array with one element, being the window’s information

Recommended Posts

Using ScriptingBridge

Post by 5 years ago

When interacting with other applications on the Mac, AppleScript is the main option to use. Writing AppleScript to run within an application can be pretty annoying, and there's no syntax checking unless you write it...

Got an idea?

We help entrepreneurs, organizations and established brands from around
the country bring ideas to life. We would love to hear from you!