OK, I've found a way. This is the code in Python (taken from here). It could use some cleaning and some error handling, but it works. The key is the undocumented CPSSetProcessName from ApplicationServices.
def _osx_set_process_name(app_title):
""" Change OSX application title """
from ctypes import cdll, c_int, pointer, Structure
from ctypes.util import find_library
app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
if app_services.CGMainDisplayID() == 0:
print "cannot run without OS X window manager"
else:
class ProcessSerialNumber(Structure):
_fields_ = [("highLongOfPSN", c_int),
("lowLongOfPSN", c_int)]
psn = ProcessSerialNumber()
psn_p = pointer(psn)
if ( (app_services.GetCurrentProcess(psn_p) < 0) or
(app_services.SetFrontProcess(psn_p) < 0) ):
print "cannot run without OS X gui process"
print "setting process name"
app_services.CPSSetProcessName(psn_p, app_title)
return False
If you call it right away, it changes the process name in the Activity Monitor. I had to call it after a small timeout for some reason to also change the Menubar name:
import gobject
gobject.timeout_add(100, _osx_set_process_name, "MyTitle")
Note that if you combine this with an .app package you can get a really nice system integration of a python app. While you can change the Icon, the Finder display name, ..., all methods I tried leave the CFBundleName (the one in the Menu bar) to "Python". (This answer for example only changes the long name (displayed over dock icons). There are plenty others that almost work.)
While this answer gives the intended result, it's not very elegant. I'd appreciate some insight into why I need the timeout... I think Python or pygtk changes the process name itself when I first import gtk or run the main loop.