tutorial - swift macos preferences window



Activate a window using its Window ID (1)

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.

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

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

EDIT:

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

Edit:

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

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)





quartz-graphics