如何使用ScriptingBridge(或AppleScript)确定具有活动键盘焦点的窗口?

时间:2016-05-09 03:19:27

标签: macos applescript focus accessibility appkit

从我可以找到的所有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进程,它不会以某种方式将自己报告为最前面的应用程序,即使它肯定有键盘焦点。

1 个答案:

答案 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