Fullscreen Detection

Hi,

I want to detect if there is a fullscreen window on each screen.

_AXUIElementGetWindow and kAXFullscreenAttribute methods work, but I have to be in a non-sandbox environment to use them.

Is there any other way that also works? I don't think it's enough to judge if it's fullscreen by comparing the window size to the screen size, since it doesn't work on MacBook with notch, or the menu bar is set to 'auto-hide'.

Thanks.

Answered by DTS Engineer in 850155022

@Frameworks Engineer is correct.

There doesn't appear to be a way to get a handle to another process' NSWindow to check its styleMask.

You can obtain a lot of other information about all windows in the user session such as kCGWindowOwnerPID, kCGWindowOwnerName, kCGWindowNumber, kCGWindowIsOnscreen, kCGWindowBounds etc., however you there isn't API for getting an NSWindow handle using an kCGWindowNumber (or some other value).

All that said, you can likely get a reasonable approximation using a combination of kCGWindowIsOnscreen and kCGWindowBounds.

We also encourage you send us an enhancement request to improve existing API.

Here is the code I used for reference:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let windowList = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID)
    for (index, windowInfo) in (windowList as! [[String: Any]]).enumerated() {
        print("Window \(index): \(windowInfo)")
    }
}

For windows that belong to your app you can check the styleMask on the window list:


NSApplication.shared.windows

Hello, thanks for taking the time to write about this! I don't believe there is another way to achieve what you are asking.

Please feel free to file this into an enhancement request. You can file the feedback here: https://developer.apple.com/bug-reporting/

Hello,

On Mac you can determine whether a given window is fullscreen with:

func isFullScreenWindow(window: NSWindow) -> Bool { return window.styleMask.contains(.fullScreen) }

Have you explored CGWindowListCopyWindowInfo?

AFAIK it returns all the windows, with corrects bounds values, even if the app is sandboxed.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@struggling_with_accessbility_api thank you for the bug report.

I'll carry on our conversation here as the Comments feature can get a bit awkward.

We propose using CGWindowListCopyWindowInfo with the kCGWindowListOptionAll option to obtain an array of all windows in the current user session. This is an array of window "resource handles".

For each window in the array you would then check:

window.styleMask.contains(.fullScreen)

to determine if that window was fullscreen.

Using the styleMask avoids the need to compare window dimensions or check split view modes.

@DTS Engineer @DTS Engineer

The mapping of CGWindowID ↔︎ NSWindow seems to only work within the my app's process?

I want to check all windows including my app owns and from other applications.

My understanding of "current user session" w.r.t. CGWindowListCopyWindowInfo / kCGWindowListOptionAll, is that you're able to get an array of all windows, including those that don't belong to your app's process.

If that's not the case then please let us know.

@DTS Engineer @DTS Engineer

Yes. But how do I get window.styleMask.contains(.fullScreen) from them, doesn't that just work with NSWindow?

If it's possible, could you please provide the relevant code from CGWindowListCopyWindowInfo to fetch the results' styleMask

Thank you very much!

Give me a bit of time to write a function for you that fetches all windows, checks the style mask for fullscreen and returns an array of fullscreen windows.

Looks like I mixed Swift and Obj-C in my reply so I'll stick with Swift since I started with that.

@Frameworks Engineer is correct.

There doesn't appear to be a way to get a handle to another process' NSWindow to check its styleMask.

You can obtain a lot of other information about all windows in the user session such as kCGWindowOwnerPID, kCGWindowOwnerName, kCGWindowNumber, kCGWindowIsOnscreen, kCGWindowBounds etc., however you there isn't API for getting an NSWindow handle using an kCGWindowNumber (or some other value).

All that said, you can likely get a reasonable approximation using a combination of kCGWindowIsOnscreen and kCGWindowBounds.

We also encourage you send us an enhancement request to improve existing API.

Here is the code I used for reference:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let windowList = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID)
    for (index, windowInfo) in (windowList as! [[String: Any]]).enumerated() {
        print("Window \(index): \(windowInfo)")
    }
}

For windows that belong to your app you can check the styleMask on the window list:


NSApplication.shared.windows

@DTS Engineer @DTS Engineer @Frameworks Engineer

Oh, thanks for your effort!

That's the same as I already know. I've brought up a feedback FB18862047 (Can't tell if there is any window in fullscreen mode using ApplicationServices Constants and AXUIElement).

But I haven't get any reply yet.

Thank you for the feedback. I'm following.

@DTS Engineer @DTS Engineer Hi, is there any progress?

Nothing noteworthy yet.

In general we recommend requesting a status update using the Feedback Assistant. You can do so at any time.

It's a pity I didn't have any feedback there. Thanks.

Fullscreen Detection
 
 
Q