CGWindowListCopyWindowInfo, kCGWindowLayer and win

2020-07-16 09:21发布

问题:

The CGWindowLevel.h file defines the constants that are used to set the window level and the largest value that can be used as window level is 20. But, if you retrieve the window list using the call CGWindowListCopyWindowInfo, you can observe that the value of kCGWindowLayer is more than 20 (25, 103 etc).

Aren't kCGWindowLayer and window level same? If they are not same, how do I get the window level for the windows that are obtained using CGWindowListCopyWindowInfo? If they are same, why do we get value >20?

回答1:

It appears that kCGWindowLayer does refer to a window level, though I haven't found any documentation saying that.

You seem to think that window levels can be at most 20 because of the enumeration from kCGBaseWindowLevelKey to kCGAssistiveTechHighWindowLevelKey, that last one having the value 20. But these are not window levels, they are keys that can be used to look up window levels using CGWindowLevelForKey. For example, kCGStatusWindowLevelKey has the value 9, but kCGStatusWindowLevel is defined as CGWindowLevelForKey(kCGStatusWindowLevelKey), and the value of that turns out to be 25.



回答2:

No. kCGWindowLayer and window level are not same. You cannot get window level directly. But you can do a trick as below.

        CFArrayRef windowArray = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
        NSMutableArray *windowsInMap = [NSMutableArray arrayWithCapacity:64];
        NSArray*  windows = (NSArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
        NSUInteger count = [windows count];
        for (NSUInteger i = 0; i < count; i++)
        {
            NSDictionary*   nswindowsdescription = [windows objectAtIndex:i];
            NSNumber* windowid = (NSNumber*)[nswindowsdescription objectForKey:@"kCGWindowNumber"];
            if(windowid)
            {
                       // Entried will be in front to back order.
            }
        }
        CFRelease(windowArray);