Link frameworks used by recent macOS versions with -weak_framework

This allows FLTK apps to use the recent frameworks when they run on recent
macOS versions even if the minimum supported macOS version of these apps is more
ancient than the framework.
This commit is contained in:
ManoloFLTK 2024-06-16 19:48:55 +02:00
parent d137ddfa7d
commit 377ff11ec9
4 changed files with 64 additions and 80 deletions

View File

@ -123,31 +123,14 @@ if(APPLE)
endif(NOT(${CMAKE_SYSTEM_VERSION} VERSION_LESS 17.0.0)) endif(NOT(${CMAKE_SYSTEM_VERSION} VERSION_LESS 17.0.0))
else() else()
set(FLTK_COCOA_FRAMEWORKS "-framework Cocoa") set(FLTK_COCOA_FRAMEWORKS "-framework Cocoa")
set(UTI_CONDITION FALSE) # TRUE when framework UniformTypeIdentifiers is used if (NOT (CMAKE_OSX_ARCHITECTURES STREQUAL "ppc" OR CMAKE_OSX_ARCHITECTURES STREQUAL "i386"))
set(SCK_CONDITION FALSE) # TRUE when framework ScreenCaptureKit is used if(${CMAKE_SYSTEM_VERSION} VERSION_GREATER_EQUAL 20.0) # a.k.a. macOS version 11.0
string(LENGTH "${CMAKE_OSX_DEPLOYMENT_TARGET}" TARGET_LEN) list(APPEND FLTK_COCOA_FRAMEWORKS "-weak_framework UniformTypeIdentifiers")
string(LENGTH "${CMAKE_SYSTEM_VERSION}" SDK_LEN)
if(TARGET_LEN GREATER 0)
if( ${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_GREATER_EQUAL 11.0)
set(UTI_CONDITION TRUE)
endif() endif()
if( ${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_GREATER_EQUAL 15.0) if(${CMAKE_SYSTEM_VERSION} VERSION_GREATER_EQUAL 24.0) # a.k.a. macOS version 15.0
set(SCK_CONDITION TRUE) list(APPEND FLTK_COCOA_FRAMEWORKS "-weak_framework ScreenCaptureKit")
endif()
elseif(SDK_LEN GREATER 0)
if( ${CMAKE_SYSTEM_VERSION} VERSION_GREATER_EQUAL 20.0 )
set(UTI_CONDITION TRUE)
endif()
if( ${CMAKE_SYSTEM_VERSION} VERSION_GREATER_EQUAL 24.0 )
set(SCK_CONDITION TRUE)
endif() endif()
endif() endif()
if(UTI_CONDITION) # a.k.a. macOS version 11.0
list(APPEND FLTK_COCOA_FRAMEWORKS "-framework UniformTypeIdentifiers")
if(SCK_CONDITION) # a.k.a. macOS version 15.0
list(APPEND FLTK_COCOA_FRAMEWORKS "-framework ScreenCaptureKit")
endif(SCK_CONDITION)
endif(UTI_CONDITION)
endif(FLTK_BACKEND_X11) endif(FLTK_BACKEND_X11)
endif(APPLE) endif(APPLE)

View File

@ -1010,10 +1010,10 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [
LIBS="$LIBS -framework Cocoa" LIBS="$LIBS -framework Cocoa"
macosversion_maj=$(sw_vers -productVersion | cut -d. -f1) macosversion_maj=$(sw_vers -productVersion | cut -d. -f1)
AS_IF([test $macosversion_maj -ge 11], [ AS_IF([test $macosversion_maj -ge 11], [
LIBS="$LIBS -framework UniformTypeIdentifiers" LIBS="$LIBS -weak_framework UniformTypeIdentifiers"
]) ])
AS_IF([test $macosversion_maj -ge 15], [ AS_IF([test $macosversion_maj -ge 15], [
LIBS="$LIBS -framework ScreenCaptureKit" LIBS="$LIBS -weak_framework ScreenCaptureKit"
]) ])
AS_IF([test x$have_pthread = xyes], [ AS_IF([test x$have_pthread = xyes], [

View File

@ -532,11 +532,10 @@ static char *prepareMacFilter(int count, const char *filter, char **patterns) {
- (void)control_allowed_types:(const char *)p - (void)control_allowed_types:(const char *)p
{ {
NSString *ext = [NSString stringWithUTF8String:p]; NSString *ext = [NSString stringWithUTF8String:p];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0 && \ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0 if (@available(macOS 11.0, *)) {
if (fl_mac_os_version >= 110000) { UTType *type = [UTType typeWithFilenameExtension:ext]; // 11.0 + framework UniformTypeIdentifiers
UTType *type = [UTType typeWithFilenameExtension:ext]; // 11.0 + framework UniformTypeIdentifiers [dialog setAllowedContentTypes:[NSArray arrayWithObject:type]]; // 11.0
[dialog setAllowedContentTypes:[NSArray arrayWithObject:type]]; // 11.0
} }
else else
#endif #endif

View File

@ -49,7 +49,7 @@ extern "C" {
#include <pwd.h> #include <pwd.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_15_0 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
# import <ScreenCaptureKit/ScreenCaptureKit.h> # import <ScreenCaptureKit/ScreenCaptureKit.h>
#endif #endif
@ -4610,63 +4610,65 @@ int Fl_Cocoa_Window_Driver::decorated_h()
return h() + bt/s; return h() + bt/s;
} }
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_15_0 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
// Requires -framework ScreenCaptureKit and used by FLTK for macOS ≥ 15.0 // Requires -weak_framework ScreenCaptureKit and used by FLTK for macOS ≥ 15.0
static CGImageRef capture_titlebar_macOS15(NSWindow *nswin) { static CGImageRef capture_titlebar_macOS15(NSWindow *nswin) {
__block CGImageRef capture = NULL; if (@available(macOS 15.0, *)) {
__block BOOL capture_err = NO; __block CGImageRef capture = NULL;
void (^block_to_stop_main_loop)(void) = ^{ CFRunLoopStop(CFRunLoopGetMain()); }; __block BOOL capture_err = NO;
CGWindowID target_id = [nswin windowNumber]; void (^block_to_stop_main_loop)(void) = ^{ CFRunLoopStop(CFRunLoopGetMain()); };
NSRect r = [nswin frame]; CGWindowID target_id = [nswin windowNumber];
int W = r.size.width, H = r.size.height; NSRect r = [nswin frame];
[SCShareableContent getCurrentProcessShareableContentWithCompletionHandler: // macOS 14.4 int W = r.size.width, H = r.size.height;
^(SCShareableContent *shareableContent, NSError *error) { [SCShareableContent getCurrentProcessShareableContentWithCompletionHandler: // macOS 14.4
SCWindow *scwin = nil; ^(SCShareableContent *shareableContent, NSError *error) {
if (!error) { SCWindow *scwin = nil;
NSEnumerator *enumerator = [[shareableContent windows] objectEnumerator]; if (!error) {
while ((scwin = (SCWindow*)[enumerator nextObject]) != nil) { NSEnumerator *enumerator = [[shareableContent windows] objectEnumerator];
if ([scwin windowID] == target_id) { while ((scwin = (SCWindow*)[enumerator nextObject]) != nil) {
break; if ([scwin windowID] == target_id) {
break;
}
} }
} }
} if (!scwin) {
if (!scwin) { capture_err = YES;
capture_err = YES; dispatch_async(dispatch_get_main_queue(), block_to_stop_main_loop);
dispatch_async(dispatch_get_main_queue(), block_to_stop_main_loop); return;
return;
}
SCContentFilter *filter = [[[SCContentFilter alloc] initWithDesktopIndependentWindow:scwin] autorelease];
int s = (int)[filter pointPixelScale];
SCStreamConfiguration *config = [[[SCStreamConfiguration alloc] init] autorelease];
[config setIgnoreShadowsSingleWindow:YES];
[config setWidth:W*s];
[config setHeight:H*s];
[config setIncludeChildWindows:NO]; // macOS 14.2
[SCScreenshotManager captureImageWithFilter:filter
configuration:config
completionHandler:^(CGImageRef sampleBuffer, NSError *error) {
if (error) capture_err = YES;
else {
capture = sampleBuffer;
CGImageRetain(capture);
} }
dispatch_async(dispatch_get_main_queue(), block_to_stop_main_loop); SCContentFilter *filter = [[[SCContentFilter alloc] initWithDesktopIndependentWindow:scwin] autorelease];
int s = (int)[filter pointPixelScale];
SCStreamConfiguration *config = [[[SCStreamConfiguration alloc] init] autorelease];
[config setIgnoreShadowsSingleWindow:YES];
[config setWidth:W*s];
[config setHeight:H*s];
[config setIncludeChildWindows:NO]; // macOS 14.2
[SCScreenshotManager captureImageWithFilter:filter
configuration:config
completionHandler:^(CGImageRef sampleBuffer, NSError *error) {
if (error) capture_err = YES;
else {
capture = sampleBuffer;
CGImageRetain(capture);
}
dispatch_async(dispatch_get_main_queue(), block_to_stop_main_loop);
}
];
} }
]; ];
} // run the main loop until the 1 or 2 blocks above have finished and have stopped the loop
]; while (!capture_err && !capture) CFRunLoopRun();
// run the main loop until the 1 or 2 blocks above have finished and have stopped the loop if (capture_err) return NULL;
while (!capture_err && !capture) CFRunLoopRun(); int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
if (capture_err) return NULL; int s = CGImageGetWidth(capture) / W;
int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height; CGRect cgr = CGRectMake(0, 0, W * s, bt * s);
int s = CGImageGetWidth(capture) / W; CGImageRef title_bar = CGImageCreateWithImageInRect(capture, cgr);
CGRect cgr = CGRectMake(0, 0, W * s, bt * s); CGImageRelease(capture);
CGImageRef title_bar = CGImageCreateWithImageInRect(capture, cgr); return title_bar;
CGImageRelease(capture); } else return NULL;
return title_bar;
} }
#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_15_0 #endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
void Fl_Cocoa_Window_Driver::draw_titlebar_to_context(CGContextRef gc, int w, int h) void Fl_Cocoa_Window_Driver::draw_titlebar_to_context(CGContextRef gc, int w, int h)
@ -4676,7 +4678,7 @@ void Fl_Cocoa_Window_Driver::draw_titlebar_to_context(CGContextRef gc, int w, in
[NSApp nextEventMatchingMask:NSEventMaskAny untilDate:nil inMode:NSDefaultRunLoopMode dequeue:NO]; [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:nil inMode:NSDefaultRunLoopMode dequeue:NO];
CGImageRef img = NULL; CGImageRef img = NULL;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
# if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_15_0 # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
if (fl_mac_os_version >= 150000) img = capture_titlebar_macOS15(nswin); if (fl_mac_os_version >= 150000) img = capture_titlebar_macOS15(nswin);
else else
# endif # endif