Activate a window using its Window ID

后端 未结 2 467
一向
一向 2021-02-07 08:30

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 grante

2条回答
  •  盖世英雄少女心
    2021-02-07 09:26

    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)
        }
    }
    

    It is probably usefull to switch by name as well:

    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)
        }
    }
    

    Example: switchToApp(named: "OpenOffice")

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

    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)

提交回复
热议问题