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

6

我希望能够设置一个从外部应用程序(例如TextEdit)打开的窗口成为最前面的窗口。

我可以成功地使用GetFrontProcess获取应用程序自身的引用,并检查它是否是最前面的窗口。如果不是,我可以使用setFrontProcess使其获得焦点。

然后,我可以使用可访问性API来检查该应用程序下的所有窗口。我正在检查某个特定的窗口是否存在,如果存在,我会将其与该应用程序的最前面的窗口进行比较:

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

如果我感兴趣的窗口不是最前面的,我需要将其设置为最前面的。我认为我可以使用AXUIElement Set AttributeValue来实现这一点,但是我没有成功。以下是我的尝试方式。
//set the front window of textEditApp to be desiredFrontWindow
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow);

我已检查到窗口存在,并且应用程序成功地进行了“切换到”。但为什么这行代码不能将指定的窗口置于最前面呢?
谢谢。
3个回答

8

我在一款应用程序上工作时,通过将应用程序置于前台,然后将单个窗口置于前台,实现了这一目标。

首先将应用程序置于前台:

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

然后将窗口发送到前面:

let window = (window AXUIElement)
AXUIElementSetAttributeValue(window, NSAccessibilityMainAttribute, true)

1
可以用。谢谢。 - John Wheeler
2
我认为在现代的Swift中,这段代码应该是这样的:AXUIElementSetAttributeValue(window, kAXMainWindowAttribute as CFString, true as CFTypeRef)。 - aferriss

8
这行代码为什么不能将指定的窗口置于最前面呢?因为您试图设置只读属性。要使窗口置于最前面,您需要设置窗口的相应属性。同样适用于应用程序:要使应用程序置于最前面,您需要设置应用程序的相应属性。Cocoa/Mac OS X中前置窗口的名称为“主窗口”。(例如,请参见与该概念相关的NSApplication'sNSWindow's methods。)辅助功能使用相同的名称,因此要使单个窗口置于最前面,请将其kAXMainAttribute的值设置为kCFBooleanTrue
将应用程序置于最前面的方法类似:将其kAXFrontmostAttribute的值设置为kCFBooleanTrue。您需要执行这两个操作来设置应用程序的最前窗口并使应用程序处于活动状态。 据我所知,没有办法只将应用程序的单个窗口置于最前面并赋予它会话焦点。

谢谢Peter,这个方法非常有效。至于应用程序,我一直在使用setFrontProcess而不是kAXFrontMostAttribute - 这是一个坏主意吗?在浏览完应用程序和窗口后,我对某个AXUIElementRef感兴趣(即使它获得键盘焦点)。我可以通过元素的层级结构来引用它,但是如何将其设置为焦点?是否有类似于元素的kAXMainAttribute的等效项?也许我应该发布(另一个)问题。 - Ben Packard

1

最近我发现,如果你不介意使用Carbon,你可以使用SetFrontProcessWithOptions将一个窗口置于前台并使其获得焦点,只需将kSetFrontProcessFrontWindowOnly作为第二个参数传递即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接