わざわざ Objective-C 覚えるの辛いので、まだちょっとかじった程度だけど Python (と PyObjC)使って書いてみた:
active_app_logger.py
from AppKit import *
from PyObjCTools import AppHelper
def main():
nc = NSWorkspace.sharedWorkspace().notificationCenter()
nc.addObserver_selector_name_object_(
Observer.new(),
"handle:",
NSWorkspaceDidActivateApplicationNotification,
None
)
AppHelper.runConsoleEventLoop(installInterrupt=True)
class Observer(NSObject):
def handle_(self, noti):
"""アクティブなアプリケーションが切り替わった時に呼ばれる処理"""
info = noti.userInfo().objectForKey_(NSWorkspaceApplicationKey)
for n in ["bundleIdentifier", "localizedName", "bundleURL",
"executableURL", "launchDate"]:
v = info.valueForKey_(n)
print("%s (%s):\t%s" % (n, v.className(), v))
print("--")
main()
端末で実行して、Google Chrome → iTerm の順にアプリケーションを切り替えてみる:
$ python cocoa_active_window.py
bundleIdentifier (__NSCFString): com.google.Chrome
localizedName (__NSCFString): Google Chrome
bundleURL (NSURL): file:///Applications/Google%20Chrome.app
executableURL (NSURL): file:///Applications/Google%20Chrome.app/Contents/MacOS/Google%20Chrome
launchDate (__NSDate): 2015-01-02 05:09:26 +0000
--
bundleIdentifier (__NSCFString): com.googlecode.iterm2
localizedName (NSTaggedPointerString): iTerm
bundleURL (NSURL): file:///Applications/iTerm.app
executableURL (NSURL): file:///Applications/iTerm.app/Contents/MacOS/iTerm
launchDate (__NSTaggedDate): 2015-01-02 05:59:29 +0000
--
このスクリプトを実行する場合は、PyObjC のインストールが必要:
$ sudo pip install pyobjc
スクリプトの動作環境は:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.10.1
BuildVersion: 14B25
$ xcodebuild -version
Xcode 6.1.1
Build version 6A2008a
$ python --version
Python 2.7.6
$ pip show 'pyobjc' | grep Version
Version: 3.0.4
多少使い慣れている Ruby(RubyCocoa) より資料も多そうだったので PyObjC を選んだけれど、Python も PyObjC も Objective-C もろくに使えず、Mac OS X アプリケーションも作ったことないなら素直に Objective-C から覚えたほうが楽だったかも。つらかった。
アクティブなウィンドウの情報を取るには NSAccessibility
を触る必要があるっぽいので諦め。NSAccessibility
はクリティカルな情報にアクセスできるポリシーが固めな API?また、PyObjC に見当たらなかったんだけどバインディングされてない?