解決策は、(ウィンドウの階層化に関して) Dock の「下」にあるウィンドウのみにウィンドウ リストをフィルター処理することです。
以下のコードは私にとってはうまくいきました。画面上のすべてのウィンドウ (デスクトップ要素を除く) をフェッチします。リストから「Dock」ウィンドウのウィンドウ ID を抽出します。次に、画面ウィンドウを再度フェッチし、Dock ウィンドウの「下」にあるウィンドウのみにフィルタリングします。
// Fetch all on screen windows
CFArrayRef windowListArray = CGWindowListCreate(kCGWindowListOptionOnScreenOnly|kCGWindowListExcludeDesktopElements, kCGNullWindowID);
NSArray *windows = CFBridgingRelease(CGWindowListCreateDescriptionFromArray(windowListArray));
NSLog(@"All on screen windows: %@", windows);
// Find window ID of "Dock" window
NSNumber *dockWindowNumber = nil;
for (NSDictionary *window in windows) {
if ([(NSString *)window[(__bridge NSString *)kCGWindowName] isEqualToString:@"Dock"]) {
dockWindowNumber = window[(__bridge NSString *)kCGWindowNumber];
break;
}
}
NSLog(@"dockWindowNumber: %@", dockWindowNumber);
CFRelease(windowListArray);
if (dockWindowNumber) {
// Fetch on screen windows again, filtering to those "below" the Dock window
// This filters out all but the "standard" application windows
windowListArray = CGWindowListCreate(kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements, [dockWindowNumber unsignedIntValue]);
NSArray *windows = CFBridgingRelease(CGWindowListCreateDescriptionFromArray(windowListArray));
NSLog(@"On screen application windows: %@", windows);
}
else {
NSLog(@"Could not find Dock window description");
}