从我可以找到的所有API文档中,似乎正确的做法是检查系统事件或辅助功能API返回的“最前面”窗口,就像这样(Python中的示例,但这是相同的ObjC或swift或ruby或其他):
#!/usr/bin/env python
from ScriptingBridge import SBApplication
events = SBApplication.applicationWithBundleIdentifier_(
"com.apple.systemevents")
for proc in events.applicationProcesses():
if proc.frontmost():
print(proc.name())
我从中获得的价值与NSWorkspace.sharedWorkspace().frontmostApplication()
相同。而通常正确。除非提示对话框(尤其是来自系统的对话框)实际具有键盘焦点。例如,如果Messages.app想要我的Jabber帐户的密码,或者我的iCloud密码更改;这些对话框似乎来自UserNotificationCenter
进程,它不会以某种方式将自己报告为最前面的应用程序,即使它肯定有键盘焦点。
答案 0 :(得分:1)
"的 UserNotificationCenter 强>"和" UserNotificationCenter "是后台应用程序(info.plist中NSUIElement
键为1)。
proc.frontmost()
在后台进程中总是 false (没有菜单,也没有在Dock中)。
NSWorkspace.sharedWorkspace().frontmostApplication()
并不适用于后台应用程序。
要获取活动应用程序,请使用activeApplication
类
NSWorkspace
方法
这是AppleScript:
set pyScript to "from AppKit import NSWorkspace
activeApp = NSWorkspace.sharedWorkspace().activeApplication()
print activeApp['NSApplicationName'].encode('utf-8')
print activeApp['NSApplicationProcessIdentifier']"
set r to do shell script "/usr/bin/python -c " & quoted form of pyScript
set {localizedAppName, procID} to paragraphs of r -- procID is the unix id
使用未弃用的方法更新:
set pyScript to "from AppKit import NSWorkspace
for app in NSWorkspace.sharedWorkspace().runningApplications():
if app.isActive():
print app.localizedName().encode('utf-8')
print app.processIdentifier()
break"
set r to do shell script "/usr/bin/python -c " & quoted form of pyScript
set {localizedAppName, procID} to paragraphs of r -- procID is the unix id
要从进程ID获取前窗,请使用procID
变量,如下所示:
tell application "System Events"
tell (first process whose unix id = procID)
log (get properties) -- properties of this process
tell window 1 to if exists then log (get properties) -- properties of the front window of this process
end tell
end tell