From eb768c8c4b5bf09e6b6598728333fb99d65486e7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 20 Apr 2021 16:47:09 +0400 Subject: [PATCH] Add IsOverlapped implementation for macOS. --- ui/platform/mac/ui_utility_mac.mm | 50 ++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/ui/platform/mac/ui_utility_mac.mm b/ui/platform/mac/ui_utility_mac.mm index 73b0c54..f6d8b55 100644 --- a/ui/platform/mac/ui_utility_mac.mm +++ b/ui/platform/mac/ui_utility_mac.mm @@ -103,7 +103,55 @@ void IgnoreAllActivation(not_null widget) { std::optional IsOverlapped( not_null widget, const QRect &rect) { - return std::nullopt; + NSWindow *window = [reinterpret_cast(widget->window()->winId()) window]; + Assert(window != nullptr); + + if (![window isOnActiveSpace]) { + return true; + } + + const auto nativeRect = CGRectMake( + rect.x(), + rect.y(), + rect.width(), + rect.height()); + + CGWindowID windowId = (CGWindowID)[window windowNumber]; + const CGWindowListOption options = kCGWindowListExcludeDesktopElements + | kCGWindowListOptionOnScreenAboveWindow; + CFArrayRef windows = CGWindowListCopyWindowInfo(options, windowId); + if (!windows) { + return std::nullopt; + } + const auto guard = gsl::finally([&] { + CFRelease(windows); + }); + NSMutableArray *list = (__bridge NSMutableArray*)windows; + for (NSDictionary *window in list) { + NSNumber *alphaValue = [window objectForKey:@"kCGWindowAlpha"]; + const auto alpha = alphaValue ? [alphaValue doubleValue] : 1.; + if (alpha == 0.) { + continue; + } + NSString *owner = [window objectForKey:@"kCGWindowOwnerName"]; + NSNumber *layerValue = [window objectForKey:@"kCGWindowLayer"]; + const auto layer = layerValue ? [layerValue intValue] : 0; + if (owner && [owner isEqualToString:@"Dock"] && layer == 20) { + // It is always full screen. + continue; + } + CFDictionaryRef bounds = (__bridge CFDictionaryRef)[window objectForKey:@"kCGWindowBounds"]; + if (!bounds) { + continue; + } + CGRect rect; + if (!CGRectMakeWithDictionaryRepresentation(bounds, &rect)) { + continue; + } else if (CGRectIntersectsRect(rect, nativeRect)) { + return true; + } + } + return false; } TitleControls::Layout TitleControlsLayout() {