Currently I am work on an app that can display video as wallpaper. The target platform is macOS. When the user can't see desktop, it seems the video that plays on desktop can be paused to save the energy. But I can't found the API about whether the window is invisible(hide by other window). So is there any solutions for me to know the desktop is covered completely by other windows ?
Question about NSWindow exposed or hide
desktop is covered completely by other windows ?
Not sure of my interpretation of "completely" ?
What you could do is get all the rect of visible windows:
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 }
let rect = infoList[0]["kCGWindowBounds"]!
print("rect", rect)
var framesRects = [CGRect]()
for wind in infoList {
let wBounds = wind["kCGWindowBounds"]
if wBounds != nil {
let x = wBounds!["X"] as? Int ?? 0
let y = wBounds!["Y"] as? Int ?? 0
let width = wBounds!["Width"] as? Int ?? 0
let height = wBounds!["Height"] as? Int ?? 0
let rect = CGRect(x: x, y: y, width: width, height: height)
framesRects.append(rect)
}
}
You will get an array such as:
frames [(446.0, 648.0, 17.0, 23.0), (1407.0, 0.0, 32.0, 24.0), (3967.0, 0.0, 32.0, 24.0), (3819.0, 0.0, 38.0, 24.0), (3783.0, 0.0, 36.0, 24.0), (4031.0, 0.0, 30.0, 24.0), (3857.0, 0.0, 32.0, 24.0), (3889.0, 0.0, 42.0, 24.0), (3931.0, 0.0, 36.0, 24.0), (3999.0, 0.0, 32.0, 24.0), (4061.0, 0.0, 179.0, 24.0), (1371.0, 0.0, 36.0, 24.0), (1297.0, 0.0, 32.0, 24.0), (1259.0, 0.0, 38.0, 24.0), (1223.0, 0.0, 36.0, 24.0), (1329.0, 0.0, 42.0, 24.0), (1439.0, 0.0, 32.0, 24.0), (1471.0, 0.0, 30.0, 24.0), (1501.0, 0.0, 179.0, 24.0), (1680.0, 0.0, 2560.0, 24.0), (0.0, 0.0, 1680.0, 24.0), (1372.0, 25.0, 0.0, 0.0), (196.0, 513.0, 480.0, 350.0), (64.0, 114.0, 1599.0, 900.0), (1988.0, 79.0, 1566.0, 1025.0), (1959.0, 168.0, 770.0, 753.0), (2663.0, 564.0, 1511.0, 745.0), (90.0, 41.0, 1627.0, 950.0), (1680.0, 25.0, 1344.0, 846.0), (1891.0, 26.0, 1354.0, 808.0), (175.0, 180.0, 1187.0, 836.0), (487.0, 195.0, 1193.0, 855.0), (328.0, 111.0, 1024.0, 820.0)]
Then, you have to find the points which are not in one of them.
Unfortunately, union of rect is not OK. So you may have to test each point on screen, whether it is in one of those rect. And if there is some out.
There may be a better option, but not found so far.
Don't you care if it the screen is complete occupied by a group of windows ?
Or do you just want to know if a single window fully covers screen ? But not necessarily a window from your app ?
If so, I see 2 options at least:
- use Accessibility API, which can give you access to frame change notifications for all windows, not just your app's.
Read here: https://stackoverflow.com/questions/3017636/detect-when-a-mac-os-x-window-is-resized-or-moved
- Or test regularly (using the code posted in previous answer) if any window is masking the whole screen.
PS: for the fun, I managed to compute exactly all the unhidden parts of screen…