Я провел несколько тестов с этим, и я думаю, что ваша проблема может заключаться в том, как вы демонизируете этот инструмент, а затем пытаетесь сделать вызов, для которого требуются службы Windows, которые могут быть недоступны. Эта ссылка здесь намекает на такую ситуацию: http://grokbase.com/t/python/pythonmac-sig/08axst378p/appscript-and-launching-apps-from-background-only-python-processes
Я впервые проверил эту теорию, используя ваш скрипт демона, и сделал osascript
вызов, чтобы найти активное приложение через AppleScript:
from subprocess import Popen, PIPE
cmd = """osascript \
-e 'tell application "System Events"' \
-e 'set app_name to name of the first process whose frontmost is true' \
-e 'end tell' """
v = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
Popen - это способ запуска системной команды в подпроцессе и возможность проверки его кода возврата или считывания его вывода (или отправки ввода) http://docs.python.org/library/subprocess.html.. Osascript - это инструмент командной строки для вызова сценариев Apple.
Для меня это работает, потому что он запускает новый подпроцесс, который, я думаю, имеет ли доступ к серверу окон?
Затем я создал plist launchd вместо того, чтобы использовать ваш скрипт демона. Это работает:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.company.test</string>
<key>Nice</key>
<integer>1</integer>
<key>OnDemand</key>
<false/>
<key>Program</key>
<string>/path/to/script.py</string>
</dict>
</plist>
Launchd - это менеджер процессов демона OSX, который, похоже, запускает программы таким образом, что они имеют полный доступ к серверу окон.
Для script.py
у меня просто был цикл, запись имени файла переднего приложения в спящий режим.
Обновление
Поскольку вы упомянули, что ваш подход к pyobjc устарел, и вам, похоже, нравится подход appleScript, я подумал, что воспользуюсь питонским подходом, используя appscript - привязки python к сценарию apple
from appscript import app, its
activeApp = app('System Events').processes[its.frontmost == True].first()
print activeApp
#result
app(u'/System/Library/CoreServices/System Events.app').application_processes[u'Terminal']
activeApp
- это объект, представляющий самое переднее приложение, о котором сообщает приложение System Events.