diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 67aada93f..ee83fac32 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -386,7 +386,7 @@ target_link_libraries(keepassxc_gui ${sshagent_LIB}) if(APPLE) - target_link_libraries(keepassxc_gui "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication") + target_link_libraries(keepassxc_gui "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication -framework ScreenCaptureKit") if(Qt5MacExtras_FOUND) target_link_libraries(keepassxc_gui Qt5::MacExtras) endif() diff --git a/src/autotype/mac/CMakeLists.txt b/src/autotype/mac/CMakeLists.txt index e0df901fd..ae1f5187f 100644 --- a/src/autotype/mac/CMakeLists.txt +++ b/src/autotype/mac/CMakeLists.txt @@ -1,7 +1,7 @@ set(autotype_mac_SOURCES AutoTypeMac.cpp) add_library(keepassxc-autotype-cocoa MODULE ${autotype_mac_SOURCES}) -set_target_properties(keepassxc-autotype-cocoa PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit -framework Carbon") +set_target_properties(keepassxc-autotype-cocoa PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit -framework Carbon -framework ScreenCaptureKit") target_link_libraries(keepassxc-autotype-cocoa ${PROGNAME} Qt5::Core Qt5::Widgets) install(TARGETS keepassxc-autotype-cocoa diff --git a/src/gui/osutils/macutils/AppKitImpl.mm b/src/gui/osutils/macutils/AppKitImpl.mm index f2692bd6e..a2b30e553 100644 --- a/src/gui/osutils/macutils/AppKitImpl.mm +++ b/src/gui/osutils/macutils/AppKitImpl.mm @@ -19,6 +19,9 @@ #import "AppKitImpl.h" #import #import +#if __clang_major__ >= 13 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_12_3 +#import +#endif @implementation AppKitImpl @@ -181,28 +184,37 @@ // // Check if screen recording is enabled, may show an popup asking for permissions // -- (bool) enableScreenRecording +- (bool) enableScreenRecording { -#if __clang_major__ >= 9 && MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 - if (@available(macOS 10.15, *)) { - // Request screen recording permission on macOS 10.15+ - // This is necessary to get the current window title - CGDisplayStreamRef stream = CGDisplayStreamCreate(CGMainDisplayID(), 1, 1, kCVPixelFormatType_32BGRA, nil, - ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, - IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) { - Q_UNUSED(status); - Q_UNUSED(displayTime); - Q_UNUSED(frameSurface); - Q_UNUSED(updateRef); - }); - if (stream) { - CFRelease(stream); - } else { - return NO; - } +#if __clang_major__ >= 13 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_12_3 + if (@available(macOS 12.3, *)) { + __block BOOL hasPermission = NO; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + // Attempt to use SCShareableContent to check for screen recording permission + [SCShareableContent getShareableContentWithCompletionHandler:^(SCShareableContent * _Nullable content, + NSError * _Nullable error) { + Q_UNUSED(error); + if (content) { + // Successfully obtained content, indicating permission is granted + hasPermission = YES; + } else { + // No permission or other error occurred + hasPermission = NO; + } + // Notify the semaphore that the asynchronous task is complete + dispatch_semaphore_signal(sema); + }]; + + // Wait for the asynchronous callback to complete + dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC); + dispatch_semaphore_wait(sema, timeout); + + // Return the final result + return hasPermission; } #endif - return YES; + return YES; // Return YES for macOS versions that do not support ScreenCaptureKit } - (void) toggleForegroundApp:(bool) foreground