【问题标题】:How do I determine the window with the active keyboard focus using ScriptingBridge (or AppleScript)?如何使用 ScriptingBridge(或 AppleScript)确定具有活动键盘焦点的窗口?
【发布时间】:2016-05-09 03:19:26
【问题描述】:

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

【问题讨论】:

  • 询问用户名和密码的对话窗口属于进程SecurityAgent
  • Winfo.app - 来自irradiatedsoftware.com/labs - 告诉我我正在查看的对话框来自UserNotificationCenter

标签: macos applescript focus accessibility appkit


【解决方案1】:

UserNotificationCenter”和“UserNotificationCenter”是后台应用程序(NSUIElement 键在 info.plist 中为 1)。

proc.frontmost() 在后台进程(无菜单且不在 Dock 中)上始终为 false

NSWorkspace.sharedWorkspace().frontmostApplication() 在后台应用程序中不起作用。


要获取活动应用程序,请使用NSWorkspace 类中的activeApplication 方法

这是 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

【讨论】:

  • activeApplication 从 10.7 开始似乎已被弃用。
  • 不,activeApplicationOS X v10.11 起已弃用,但仍可在 10.11.4 上使用。我在答案中添加了另一种方法(不推荐使用)。
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
相关资源
最近更新 更多