|
36 | 36 | return path; |
37 | 37 | } |
38 | 38 |
|
| 39 | +// This method determines whether or not a system preferences security |
| 40 | +// authentication request is currently open on the user's screen and foregrounds |
| 41 | +// it if found |
| 42 | +bool HasOpenSystemPreferencesDialog() { |
| 43 | + int MAX_NUM_LIKELY_OPEN_WINDOWS = 4; |
| 44 | + bool isDialogOpen = false; |
| 45 | + CFArrayRef windowList; |
| 46 | + |
| 47 | + // loops for max 1 second, breaks if/when dialog is found |
| 48 | + for (int index = 0; index <= MAX_NUM_LIKELY_OPEN_WINDOWS; index++) { |
| 49 | + windowList = CGWindowListCopyWindowInfo( |
| 50 | + kCGWindowListOptionOnScreenAboveWindow, kCGNullWindowID); |
| 51 | + int numberOfWindows = CFArrayGetCount(windowList); |
| 52 | + |
| 53 | + for (int windowIndex = 0; windowIndex < numberOfWindows; windowIndex++) { |
| 54 | + NSDictionary *windowInfo = |
| 55 | + (NSDictionary *)CFArrayGetValueAtIndex(windowList, windowIndex); |
| 56 | + NSString *windowOwnerName = windowInfo[(id)kCGWindowOwnerName]; |
| 57 | + NSNumber *windowLayer = windowInfo[(id)kCGWindowLayer]; |
| 58 | + NSNumber *windowOwnerPID = windowInfo[(id)kCGWindowOwnerPID]; |
| 59 | + |
| 60 | + if ([windowLayer integerValue] == 0 && |
| 61 | + [windowOwnerName isEqual:@"universalAccessAuthWarn"]) { |
| 62 | + // make sure the auth window is in the foreground |
| 63 | + NSRunningApplication *authApplication = [NSRunningApplication |
| 64 | + runningApplicationWithProcessIdentifier:[windowOwnerPID |
| 65 | + integerValue]]; |
| 66 | + |
| 67 | + [NSRunningApplication.currentApplication |
| 68 | + activateWithOptions:NSApplicationActivateAllWindows]; |
| 69 | + [authApplication activateWithOptions:NSApplicationActivateAllWindows]; |
| 70 | + |
| 71 | + isDialogOpen = true; |
| 72 | + break; |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + CFRelease(windowList); |
| 77 | + |
| 78 | + if (isDialogOpen) { |
| 79 | + break; |
| 80 | + } |
| 81 | + |
| 82 | + usleep(250000); |
| 83 | + } |
| 84 | + |
| 85 | + return isDialogOpen; |
| 86 | +} |
| 87 | + |
39 | 88 | // Returns a status indicating whether the user has authorized Contacts |
40 | 89 | // access. |
41 | 90 | std::string ContactAuthStatus() { |
|
112 | 161 | NSNumber *ourProcessIdentifier = |
113 | 162 | [NSNumber numberWithInteger:runningApplication.processIdentifier]; |
114 | 163 |
|
115 | | - CFArrayRef windowList = CGWindowListCopyWindowInfo( |
116 | | - kCGWindowListOptionOnScreenOnly, kCGNullWindowID); |
| 164 | + CFArrayRef windowList = |
| 165 | + CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID); |
117 | 166 | int numberOfWindows = CFArrayGetCount(windowList); |
118 | 167 | for (int index = 0; index < numberOfWindows; index++) { |
119 | 168 | // get information for each window |
@@ -536,24 +585,28 @@ void AskForScreenCaptureAccess(const Napi::CallbackInfo &info) { |
536 | 585 | // to the list in sysprefs if the user previously denied. |
537 | 586 | // https://stackoverflow.com/questions/56597221/detecting-screen-recording-settings-on-macos-catalina |
538 | 587 | CGDisplayStreamRef stream = CGDisplayStreamCreate( |
539 | | - CGMainDisplayID(), 1, 1, kCVPixelFormatType_32BGRA, nil, |
| 588 | + CGMainDisplayID(), 1, 1, kCVPixelFormatType_32BGRA, NULL, |
540 | 589 | ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, |
541 | 590 | IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef){ |
542 | 591 | }); |
| 592 | + |
543 | 593 | if (stream) { |
544 | 594 | CFRelease(stream); |
545 | 595 | } else { |
546 | | - NSWorkspace *workspace = [[NSWorkspace alloc] init]; |
547 | | - NSString *pref_string = @"x-apple.systempreferences:com.apple.preference." |
548 | | - @"security?Privacy_ScreenCapture"; |
549 | | - [workspace openURL:[NSURL URLWithString:pref_string]]; |
| 596 | + if (!HasOpenSystemPreferencesDialog()) { |
| 597 | + NSWorkspace *workspace = [[NSWorkspace alloc] init]; |
| 598 | + NSString *pref_string = |
| 599 | + @"x-apple.systempreferences:com.apple.preference." |
| 600 | + @"security?Privacy_ScreenCapture"; |
| 601 | + [workspace openURL:[NSURL URLWithString:pref_string]]; |
| 602 | + } |
550 | 603 | } |
551 | 604 | } |
552 | 605 | } |
553 | 606 |
|
554 | 607 | // Request Accessibility Access. |
555 | 608 | void AskForAccessibilityAccess(const Napi::CallbackInfo &info) { |
556 | | - NSDictionary *options = @{(id)kAXTrustedCheckOptionPrompt : @(YES)}; |
| 609 | + NSDictionary *options = @{(id)kAXTrustedCheckOptionPrompt : @(NO)}; |
557 | 610 | bool trusted = AXIsProcessTrustedWithOptions((CFDictionaryRef)options); |
558 | 611 |
|
559 | 612 | if (!trusted) { |
|
0 commit comments