使用辅助功能API设置最前面的窗口

时间:2010-01-22 01:14:49

标签: cocoa accessibility macos-carbon

我想设置一个特定的窗口,从外部应用程序(例如textedit)到最前面。

我可以使用GetFrontProcess成功获取对应用程序本身的引用,并检查它是否是最前面的。如果不是,我可以使用setFrontProcess使其聚焦。

然后我可以使用辅助功能API来检查该应用程序下的所有窗口。我正在检查某个窗口是否存在,如果存在,我将它与应用程序的最前面窗口进行比较:

//get the front window of textEditApp and store it in 'currentFrontWindow'
    AXUIElementCopyAttributeValue(textEditApp, kAXFocusedWindowAttribute, (CFTypeRef *)&currentFrontWindow);

如果我感兴趣的窗口不是最前面的,我需要设置它。我认为我可以使用AXUIElement 设置 AttributeValue来做到这一点,但我没有取得任何成功。以下是我尝试过的方法。

//set the front window of textEditApp to be desiredFrontWindow
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow);

我已检查窗口是否存在,并且应用程序已成功“切换到”。但是为什么这行代码没有将指定的窗口带到前面呢?

感谢。

3 个答案:

答案 0 :(得分:8)

  

但是为什么这行代码没有将指定的窗口带到前面?

因为您尝试设置只读属性。

为了使窗口最前面,您需要设置窗口的相应属性。应用程序也是如此:要使应用程序位于最前端,您需要设置应用程序的相应属性。

最前面窗口的Cocoa / Mac OS X名称是“主窗口”。 (例如,请参阅与此概念相关的NSApplication'sNSWindow's methods。)辅助功能使用相同的名称,因此要使单个窗口位于最前面,请将其kAXMainAttribute的值设置为{{ 1}}。

使应用程序最前端的方法类似:将kCFBooleanTrue的值设置为kAXFrontmostAttribute。您需要同时执行这两项操作以设置应用程序的最前面的窗口并使应用程序处于活动状态。

据我所知,没有办法只将应用程序的一个窗口放在最前面,并给予会话焦点。

答案 1 :(得分:3)

我可以通过将应用程序放到前面,然后将一个窗口放到前面,在应用程序I worked on中完成此操作。

首先将应用程序带到前面:

RewriteCond %{THE_REQUEST} \s/+artist\?a=([^&]+)&t=([^\s&]+) [NC]
RewriteRule ^ a/%2? [R=301,L,NE]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+)/([^/]+)/?$ artist.php?a=$1&t=$2 [L,QSA,NC]

然后将窗口发送到前面:

let currentPid = NSRunningApplication.currentApplication().processIdentifier
if let pid = (the pid of the app in question) where pid != currentPid {
  NSRunningApplication(processIdentifier: pid)?.activateWithOptions(.ActivateIgnoringOtherApps)
}

答案 2 :(得分:1)

我最近发现,如果您不介意使用某些Carbon,则可以使用SetFrontProcessWithOptions将窗口置于前面,并在将kSetFrontProcessFrontWindowOnly作为第二个参数传递时为其提供焦点。