使用其窗口ID激活窗口 [英] Activate a window using its Window ID

查看:124
本文介绍了使用其窗口ID激活窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在给定Window ID的macOS(不属于我的应用程序)上,我将如何以编程方式激活,即向前移动窗口并在macOS上聚焦窗口.我的应用程序将在用户授予无障碍权限等的情况下运行.

How would I programmatically activate i.e move-to-front-and-focus a window on macOS (not belonging to my app) given its Window ID. My app would run with user granted Accessibility permissions etc.

令人惊讶的是, Quartz Window Services页面中描述的功能似乎都没有那个.

Surprisingly, none of the functions described on the Quartz Window Services page seem to do that.

目前正在使用Swift,但可以使用Objective-C,AppleScript或其他任何工具.

Am using Swift currently, but am open to using Objective-C, AppleScript or whatever.

我不想让父应用程序的所有窗口都显示在前面-仅与窗口ID匹配的特定窗口.

I don't want to bring to front all windows of the parent app - only the specific that matches the window ID.

我知道NSWindow类型仅用于引用当前进程的窗口,但是没有类代表外部应用程序拥有的窗口吗?就像我们有NSRunningApplication来指代任何正在运行的应用程序(包括外部应用程序)一样,我期望API能够处理所有打开的窗口(假设具有正确的权限).是否有某个类,例如NSOpenWindowCGWindow埋在某个地方?

I know that the NSWindow type is only meant to refer to windows of the current process, but is there no class that represents windows owned by external apps? Like we have NSRunningApplication to refer to any running app including external ones, I was expecting an API to deal all open windows (assuming the right permissions). Is there some class like NSOpenWindow or CGWindow buried somewhere?

推荐答案

我还没有找到切换到特定窗口的方法,但是您可以使用此功能切换到包含特定窗口的应用程序:

I didn't find a way to switch to a specific window yet, but you can switch to the app that contains a specific window using this function:

func switchToApp(withWindow windowNumber: Int32) {
    let options = CGWindowListOption(arrayLiteral: CGWindowListOption.excludeDesktopElements, CGWindowListOption.optionOnScreenOnly)
    let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
    guard let infoList = windowListInfo as NSArray? as? [[String: AnyObject]] else { return }
    if let window = infoList.first(where: { ($0["kCGWindowNumber"] as? Int32) == windowNumber}), let pid = window["kCGWindowOwnerPID"] as? Int32 {
        let app = NSRunningApplication(processIdentifier: pid)
        app?.activate(options: .activateIgnoringOtherApps)
    }
}

也可以按名称切换:

func switchToApp(named windowOwnerName: String) {
    let options = CGWindowListOption(arrayLiteral: CGWindowListOption.excludeDesktopElements, CGWindowListOption.optionOnScreenOnly)
    let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
    guard let infoList = windowListInfo as NSArray? as? [[String: AnyObject]] else { return }

    if let window = infoList.first(where: { ($0["kCGWindowOwnerName"] as? String) == windowOwnerName}), let pid = window["kCGWindowOwnerPID"] as? Int32 {
        let app = NSRunningApplication(processIdentifier: pid)
        app?.activate(options: .activateIgnoringOtherApps)
    }
}

示例:switchToApp(named: "OpenOffice")

在我的Mac上,OpenOffice是使用带有kCGWindowNumber = 599的窗口启动的,因此具有相同的效果:switchToApp(withWindow: 599)

On my mac OpenOffice was started with a window with kCGWindowNumber = 599, so this has the same effect: switchToApp(withWindow: 599)

据我到目前为止发现,您的选择似乎是显示应用程序当前活动的窗口,或显示所有窗口(使用.activateAllWindows作为激活选项)

As far as I found out so far, your options seem to be to show the currently active window of the app, or to show all windows (using .activateAllWindows as activation option)

这篇关于使用其窗口ID激活窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆