[ sharable url: bmn.io/s ]
Ever wanted to programmatically find out what OS X application you have running at any given time? This post will quickly detail how it is done.
Basically the crux of it is using Apple’s AppKit bindings in python, specifically the
NSWorkspace module of AppKit.
At the very least, this is how you read the application name, and get its associated icon.
from AppKit import NSWorkspace app = NSWorkspace.sharedWorkspace().activeApplication() if app: app_name = app['NSApplicationName'] icon = app['NSWorkspaceApplicationKey'].icon()
As a module
If you just want a simple module you can use in your app, you could dump this into a python file and import it. Essentially all it does is returns a dict with the app name and a PIL TIFF image object that you can do whatever you want with. It also raises a custom Exception if the app lookup failed for any reason.
"""Module to get the currently focused app in OS X.""" from AppKit import NSWorkspace from PIL import Image import StringIO class AppLoadFailedException(RuntimeError): """Custom exception for failing to load App information.""" pass def current_app(): """Fetch the currently focused app.""" app = NSWorkspace.sharedWorkspace().activeApplication() if app: app_name = app['NSApplicationName'] icon = app['NSWorkspaceApplicationKey'].icon() # convert the icon to tiff, then return PIL image tiffdata = icon.TIFFRepresentation() img = Image.open(StringIO.StringIO(tiffdata)) return dict(name=app_name, image=img) raise AppLoadFailedException('Failed to load app information.')
Putting it together
Save the module code into
currentapp.py, or whatver you want to call it, and then import it.
import currentapp try: print currentapp.current_app() except currentapp.AppLoadFailedException as error: # handle specific error here print error except Exception as error: # handle generic exception here print error
Saving the icon
Now that you are fetching the app data and icon from NSWorkspace, you most likely want to save the image somewhere. This is pretty straight forward, we simply just use PILs .save() call. Additionally you can also thumbnail it (as the original icon is 1024x1024) as I have done below. For the sake of brevity, I have removed the include & exception handling code.
ca = currentapp.current_app() size = 128,128 ca.image.thumbnail(size, Image.ANTIALIAS) ca.image.save('path/to/filename.png', 'PNG')
As always, hit me up on twitter if you have any questions/comments.