Finding the Current Active Window in Mac OS X using Python

Posted on

Question :

Finding the Current Active Window in Mac OS X using Python

Is there a way to find the application name of the current active window at a given time on Mac OS X using Python?

Asked By: Moiz

||

Answer #1:

This should work:

#!/usr/bin/python

from AppKit import NSWorkspace
activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
print activeAppName

Only works on Leopard, or on Tiger if you have PyObjC installed and happen to point at the right python binary in line one (not the case if you’ve installed universal MacPython, which you’d probably want to do on Tiger). But Peter’s answer with the Carbon way of doing this will probably be quite a bit faster, since importing anything from AppKit in Python takes a while, or more accurately, importing something from AppKit for the first time in a Python process takes a while.

If you need this inside a PyObjC app, what I describe will work great and fast, since you only experience the lag of importing AppKit once. If you need this to work as a command-line tool, you’ll notice the performance hit. If that’s relevant to you, you’re probably better off building a 10 line Foundation command line tool in Xcode using Peter’s code as a starting point.

Answered By: Dirk Stoop

Answer #2:

The method in the accepted answer was deprecated in OS X 10.7+. The current recommended version would be the following:

from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print(active_app_name)
Answered By: kmundnic

Answer #3:

First off, do you want the window or the application name? This isn’t Windows—an application process on Mac OS X can have multiple windows. (Furthermore, this has also been true of Windows for a few years now, although I have no idea what the API looks like for that.)

Second, Carbon or Cocoa?

To get the active window in Cocoa:

window = NSApp.mainWindow()

To get the name of your process in Cocoa:

appName = NSProcessInfo.processInfo().processName()

Edit: Oh, I think I know what you want. The name of the frontmost process, right?

I don’t think there’s a way to do it in Cocoa, but here’s how to do it in Carbon in C:

ProcessSerialNumber psn = { 0L, 0L };
OSStatus err = GetFrontProcess(&psn);
/*error check*/

CFStringRef processName = NULL;
err = CopyProcessName(&psn, &processName);
/*error check*/

Remember to CFRelease(processName) when you’re done with it.

I’m not sure what that will look like in Python, or if it’s even possible. Python doesn’t have pointers, which makes that tricky.

I know PyObjC would translate the latter argument to CopyProcessName into err, processName = CopyProcessName(…), but the Carbon bindings don’t rely on PyObjC (they’re part of core Python 2), and I’m not sure what you do about the PSN either way.

Answered By: Peter Hosey

Answer #4:

I needed the current frontmost application in a Python script that arranges the windows nicely on my screen (see move_window).

Of course, the complete credit goes to Peter! But here is the complete program:

#include <Carbon/Carbon.h>

int main(int, char) {
    ProcessSerialNumber psn = { 0L, 0L };
    OSStatus err = GetFrontProcess(&psn);

    CFStringRef processName = NULL;
    err = CopyProcessName(&psn, &processName);
    printf("%sn", CFStringGetCStringPtr(processName, NULL));
    CFRelease(processName);
}

Build with gcc -framework Carbon filename.c

Answered By: SirVer

Leave a Reply

Your email address will not be published. Required fields are marked *