How do find out if there is a full-screen app running on a specific NSScreen
You can try the CGWindowList API, such as CGWindowListCopyWindowInfo()
.
If you just want to know if the menu bar is showing, you should be able to check -[NSApplication currentSystemPresentationOptions]
for NSApplicationPresentationAutoHideMenuBar
or NSApplicationPresentationHideMenuBar
. That method can also tell you if the active app is in Cocoa full-screen mode (NSApplicationPresentationFullScreen
).
Here's a solution based on CGWindowListCopyWindowInfo in Swift.
func fullScreenWindows(fullScreen: Bool) -> [CGWindowID] {
var winList: [CGWindowID] = []
// if you want to get the windows in full screen, you MUST make sure the option excluding 'optionOnScreenOnly'
let option: CGWindowListOption = fullScreen ? .excludeDesktopElements : [.excludeDesktopElements, .optionOnScreenOnly]
guard let winArray: CFArray = CGWindowListCopyWindowInfo(option, kCGNullWindowID) else {
return winList
}
for i in 0..<CFArrayGetCount(winArray) {
// current window's info
let winInfo = unsafeBitCast(CFArrayGetValueAtIndex(winArray, i), to: CFDictionary.self)
// current window's bounds
guard let boundsDict = (winInfo as NSDictionary)[kCGWindowBounds],
let bounds = CGRect.init(dictionaryRepresentation: boundsDict as! CFDictionary) else {
continue
}
// to check the window is in full screen or not
guard __CGSizeEqualToSize(NSScreen.main!.frame.size, bounds.size) else {
continue
}
// current window's id
guard let winId = (winInfo as NSDictionary)[kCGWindowNumber] as? CGWindowID,
winId == kCGNullWindowID else {
continue
}
winList.append(winId)
}
return winList
}
Here's a solution based on CGWindowListCopyWindowInfo
, as Ken Thomases suggested in his answer:
- (BOOL)fullScreenAppPresentOn:(NSScreen *)screen
{
// Get all of the visible windows (across all running applications)
NSArray<NSDictionary*> *windowInfoList = (__bridge_transfer id)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
// For each window, see if the bounds are the same size as the screen's frame
for (int windowInfoListIndex = 0; windowInfoListIndex < (int)windowsInfoList.count; windowInfoListIndex++)
{
NSDictionary *windowInfo = windowInfoList[windowInfoListIndex];
CFDictionaryRef windowInfoRef = (__bridge CFDictionaryRef) windowInfo[(__bridge NSString *)kCGWindowBounds];
CGRect windowBounds;
CGRectMakeWithDictionaryRepresentation(windowInfoRef, &windowBounds);
if (CGRectEqualToRect([screen frame], windowBounds))
{
return YES;
}
}
return NO;
}