Update Quick Look to support macOS 15

This commit is contained in:
Lior Halphon 2024-12-06 23:59:00 +02:00
parent 9df4f22873
commit ac54d5b7ec
10 changed files with 217 additions and 29 deletions

View File

@ -342,12 +342,6 @@ LDFLAGS += -mno-outline
endif
STRIP := strip
CODESIGN := true
ifeq ($(PLATFORM),Darwin)
LDFLAGS += -Wl,-exported_symbols_list,$(NULL)
STRIP := strip -x
CODESIGN := codesign -fs -
endif
LDFLAGS += -flto
CFLAGS += -flto
LDFLAGS += -Wno-lto-type-mismatch # For GCC's LTO
@ -356,6 +350,13 @@ else
$(error Invalid value for CONF: $(CONF). Use "debug", "release" or "native_release")
endif
CODESIGN := true
ifeq ($(PLATFORM),Darwin)
LDFLAGS += -Wl,-exported_symbols_list,$(NULL)
STRIP := strip -x
CODESIGN := codesign -fs -
endif
ifeq ($(PLATFORM),windows32)
LDFLAGS += -fuse-ld=lld
endif
@ -540,7 +541,9 @@ $(BIN)/SameBoy.app: $(BIN)/SameBoy.app/Contents/MacOS/SameBoy \
$(BIN)/SameBoy.app/Contents/Resources/sgb_boot.bin \
$(BIN)/SameBoy.app/Contents/Resources/sgb2_boot.bin \
$(patsubst %.xib,%.nib,$(addprefix $(BIN)/SameBoy.app/Contents/Resources/,$(shell cd Cocoa;ls *.xib))) \
$(BIN)/SameBoy.qlgenerator \
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator \
$(BIN)/SameBoy.app/Contents/PlugIns/Thumbnailer.appex \
$(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex \
Shaders
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Resources
cp Cocoa/*.icns Cocoa/*.png Misc/registers.sym $(BIN)/SameBoy.app/Contents/Resources/
@ -549,20 +552,19 @@ $(BIN)/SameBoy.app: $(BIN)/SameBoy.app/Contents/MacOS/SameBoy \
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Resources/Shaders
cp Shaders/*.fsh Shaders/*.metal $(BIN)/SameBoy.app/Contents/Resources/Shaders
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Library/QuickLook/
cp -rf $(BIN)/SameBoy.qlgenerator $(BIN)/SameBoy.app/Contents/Library/QuickLook/
ifeq ($(CONF), release)
$(CODESIGN) $@
endif
# We place the dylib inside the Quick Look plugin, because Quick Look plugins run in a very strict sandbox
$(BIN)/SameBoy.app/Contents/MacOS/SameBoy: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
$(BIN)/SameBoy.app/Contents/MacOS/SameBoy: $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
-@$(MKDIR) -p $(dir $@)
$(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) -rpath @executable_path/../Library/QuickLook/SameBoy.qlgenerator/ -Wl,-reexport_library,$^
$(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib: $(COCOA_OBJECTS) $(CORE_OBJECTS) $(QUICKLOOK_OBJECTS)
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib: $(COCOA_OBJECTS) $(CORE_OBJECTS) $(QUICKLOOK_OBJECTS)
-@$(MKDIR) -p $(dir $@)
$(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) -shared -install_name @rpath/Contents/MacOS/SameBoy.dylib -framework OpenGL -framework AudioUnit -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework IOKit -framework PreferencePanes -framework Carbon -framework QuartzCore -framework Security -framework WebKit -weak_framework Metal -weak_framework MetalKit -framework Quicklook -framework AppKit -Wl,-exported_symbols_list,QuickLook/exports.sym -Wl,-exported_symbol,_main
$(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) -shared -install_name @rpath/Contents/MacOS/SameBoy.dylib -framework OpenGL -framework AudioUnit -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework IOKit -framework PreferencePanes -framework Carbon -framework QuartzCore -framework Security -framework WebKit -weak_framework Metal -weak_framework MetalKit -weak_framework QuickLookThumbnailing -weak_framework QuickLookUI -framework Quicklook -framework AppKit -Wl,-exported_symbols_list,QuickLook/exports.sym -Wl,-exported_symbol,_main
ifeq ($(CONF), release)
$(STRIP) $@
$(CODESIGN) $@
@ -574,29 +576,55 @@ $(BIN)/SameBoy.app/Contents/Resources/%.nib: Cocoa/%.xib
$(BIN)/SameBoy-iOS.app/%.storyboardc: iOS/%.storyboard
ibtool --target-device iphone --target-device ipad --minimum-deployment-target $(IOS_MIN) --compile $@ $^ 2>&1 | cat -
# Quick Look generator
# Quick Look generators
$(BIN)/SameBoy.qlgenerator: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL \
$(shell ls QuickLook/*.png) \
QuickLook/Info.plist \
$(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin
$(MKDIR) -p $(BIN)/SameBoy.qlgenerator/Contents/Resources
cp QuickLook/*.png $(BIN)/SameBoy.qlgenerator/Contents/Resources/
sed "s/@VERSION/$(VERSION)/;s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < QuickLook/Info.plist > $(BIN)/SameBoy.qlgenerator/Contents/Info.plist
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator: $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL \
$(shell ls QuickLook/*.png) \
QuickLook/Info.plist \
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/Resources
cp QuickLook/*.png $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/Resources/
sed "s/@VERSION/$(VERSION)/;s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < QuickLook/Info.plist > $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/Info.plist
ifeq ($(CONF), release)
$(CODESIGN) $@
endif
$(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL: $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
-@$(MKDIR) -p $(dir $@)
$(CC) -o $@ $(LDFLAGS) $(FAT_FLAGS) -bundle -Wl,-reexport_library,$^ -rpath @loader_path/../../
ifeq ($(CONF), release)
$(STRIP) $@
endif
$(BIN)/SameBoy.app/Contents/PlugIns/Thumbnailer.appex: $(BIN)/SameBoy.app/Contents/PlugIns/Thumbnailer.appex/Contents/MacOS/Thumbnailer \
QuickLook/Thumbnailer.plist \
QuickLook/plugin.entitlements
sed "s/@VERSION/$(VERSION)/;s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < QuickLook/Thumbnailer.plist > $(BIN)/SameBoy.app/Contents/PlugIns/Thumbnailer.appex/Contents/Info.plist
$(CODESIGN) --entitlements QuickLook/plugin.entitlements $@
$(BIN)/SameBoy.app/Contents/PlugIns/Thumbnailer.appex/Contents/MacOS/Thumbnailer: $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
-@$(MKDIR) -p $(dir $@)
$(CC) -o $@ $(LDFLAGS) $(FAT_FLAGS) -e _NSExtensionMain -framework Foundation -Wl,-reexport_library,$^ -rpath @loader_path/../../../../Library/QuickLook/SameBoy.qlgenerator/
ifeq ($(CONF), release)
$(STRIP) $@
endif
$(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex: $(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex/Contents/MacOS/Previewer \
QuickLook/Previewer.plist \
QuickLook/plugin.entitlements
sed "s/@VERSION/$(VERSION)/;s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < QuickLook/Previewer.plist > $(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex/Contents/Info.plist
$(CODESIGN) --entitlements QuickLook/plugin.entitlements $@
$(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex/Contents/MacOS/Previewer: $(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/MacOS/SameBoy.dylib
-@$(MKDIR) -p $(dir $@)
$(CC) -o $@ $(LDFLAGS) $(FAT_FLAGS) -e _NSExtensionMain -framework Foundation -Wl,-reexport_library,$^ -rpath @loader_path/../../../../Library/QuickLook/SameBoy.qlgenerator/
ifeq ($(CONF), release)
$(STRIP) $@
endif
# cgb_boot_fast.bin is not a standard boot ROM, we don't expect it to exist in the user-provided
# boot ROM directory.
$(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs/cgb_boot_fast.bin
$(BIN)/SameBoy.app/Contents/Library/QuickLook/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs/cgb_boot_fast.bin
-@$(MKDIR) -p $(dir $@)
cp -f $^ $@

View File

@ -0,0 +1,6 @@
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
API_AVAILABLE(macos(12.0))
@interface GBPreviewProvider : QLPreviewProvider <QLPreviewingController>
@end

View File

@ -0,0 +1,20 @@
#import "GBPreviewProvider.h"
extern OSStatus GBQuickLookRender(CGContextRef cgContext, CFURLRef url, bool showBorder);
@implementation GBPreviewProvider
- (void)providePreviewForFileRequest:(QLFilePreviewRequest *)request completionHandler:(void (^)(QLPreviewReply *reply, NSError *error))handler
{
QLPreviewReply* reply = [[QLPreviewReply alloc] initWithContextSize:CGSizeMake(640, 576)
isBitmap:true
drawingBlock:^BOOL (CGContextRef context, QLPreviewReply *reply, NSError **error) {
return !GBQuickLookRender(context, (__bridge CFURLRef)request.fileURL, false);
}];
handler(reply, nil);
}
@end

View File

@ -0,0 +1,5 @@
#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
API_AVAILABLE(macos(10.15))
@interface GBThumbnailProvider : QLThumbnailProvider
@end

View File

@ -0,0 +1,27 @@
#import "GBThumbnailProvider.h"
extern OSStatus GBQuickLookRender(CGContextRef cgContext, CFURLRef url, bool showBorder);
@interface QLThumbnailReply (private)
@property unsigned iconFlavor;
@end
@implementation GBThumbnailProvider
- (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request completionHandler:(void (^)(QLThumbnailReply *, NSError *))handler
{
CGSize size = {64, 64};
CGSize maximumSize = request.maximumSize;
while (size.width < maximumSize.width / 2 &&
size.width < maximumSize.height / 2) {
size.width *= 2;
}
size.height = size.width;
QLThumbnailReply *reply = [QLThumbnailReply replyWithContextSize:size drawingBlock: ^BOOL(CGContextRef context) {
return !GBQuickLookRender(context, (__bridge CFURLRef)request.fileURL, true);
}];
reply.iconFlavor = 0;
handler(reply, nil);
}
@end

View File

@ -14,7 +14,7 @@
<string>com.github.liji32.sameboy.gb</string>
<string>com.github.liji32.sameboy.gbc</string>
<string>com.github.liji32.sameboy.isx</string>
<string>public.gbrom</string>
<string>public.gbrom</string>
</array>
</dict>
</array>
@ -27,7 +27,7 @@
<key>CFBundleName</key>
<string>SameBoy</string>
<key>CFBundleShortVersionString</key>
<string>Version @VERSION</string>
<string>@VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFPlugInDynamicRegisterFunction</key>

45
QuickLook/Previewer.plist Normal file
View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>Previewer</string>
<key>CFBundleExecutable</key>
<string>Previewer</string>
<key>CFBundleIdentifier</key>
<string>com.github.liji32.sameboy.ios.Previewer</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Previewer</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportedContentTypes</key>
<array>
<string>com.github.liji32.sameboy.gb</string>
<string>com.github.liji32.sameboy.gbc</string>
<string>com.github.liji32.sameboy.isx</string>
<string>public.gbrom</string>
</array>
<key>QLIsDataBasedPreview</key>
<true/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.preview</string>
<key>NSExtensionPrincipalClass</key>
<string>GBPreviewProvider</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>Thumbnailer</string>
<key>CFBundleExecutable</key>
<string>Thumbnailer</string>
<key>CFBundleIdentifier</key>
<string>com.github.liji32.sameboy.ios.Thumbnailer</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Thumbnailer</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportedContentTypes</key>
<array>
<string>com.github.liji32.sameboy.gb</string>
<string>com.github.liji32.sameboy.gbc</string>
<string>com.github.liji32.sameboy.isx</string>
<string>public.gbrom</string>
</array>
<key>QLThumbnailMinimumDimension</key>
<integer>64</integer>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.thumbnail</string>
<key>NSExtensionPrincipalClass</key>
<string>GBThumbnailProvider</string>
</dict>
</dict>
</plist>

View File

@ -2,7 +2,7 @@
#include <Cocoa/Cocoa.h>
#include "get_image_for_rom.h"
static OSStatus render(CGContextRef cgContext, CFURLRef url, bool showBorder)
OSStatus GBQuickLookRender(CGContextRef cgContext, CFURLRef url, bool showBorder)
{
/* Load the template NSImages when generating the first thumbnail */
static NSImage *template = nil;
@ -11,7 +11,7 @@ static OSStatus render(CGContextRef cgContext, CFURLRef url, bool showBorder)
static NSBundle *bundle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
bundle = [NSBundle bundleWithIdentifier:@"com.github.liji32.sameboy.previewer"];
bundle = [NSBundle bundleForClass:NSClassFromString(@"GBPanel")];
});
if (showBorder) {
static dispatch_once_t onceToken;
@ -53,11 +53,13 @@ static OSStatus render(CGContextRef cgContext, CFURLRef url, bool showBorder)
[NSGraphicsContext setCurrentContext:context];
double ratio = CGBitmapContextGetWidth(cgContext) / 1024.0;
/* Convert the screenshot to a magnified NSImage */
NSImage *screenshot = [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(160, 144)];
/* Draw the screenshot */
if (showBorder) {
[screenshot drawInRect:NSMakeRect(192, 150, 640, 576)];
[screenshot drawInRect:NSMakeRect(192 * ratio, 150 * ratio, 640 * ratio, 576 * ratio)];
}
else {
[screenshot drawInRect:NSMakeRect(0, 0, 640, 576)];
@ -82,7 +84,7 @@ static OSStatus render(CGContextRef cgContext, CFURLRef url, bool showBorder)
}
/* Mask it with the template (The middle part of the template image is transparent) */
[effectiveTemplate drawInRect:(NSRect){{0, 0}, template.size}];
[effectiveTemplate drawInRect:(NSRect){{0, 0}, {CGBitmapContextGetWidth(cgContext), CGBitmapContextGetHeight(cgContext)}}];
}
CGColorSpaceRelease(colorSpaceRef);
@ -96,7 +98,7 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
{
@autoreleasepool {
CGContextRef cgContext = QLPreviewRequestCreateContext(preview, ((NSSize){640, 576}), true, nil);
if (render(cgContext, url, false) == noErr) {
if (GBQuickLookRender(cgContext, url, false) == noErr) {
QLPreviewRequestFlushContext(preview, cgContext);
CGContextRelease(cgContext);
return noErr;
@ -111,7 +113,7 @@ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thum
extern NSString *kQLThumbnailPropertyIconFlavorKey;
@autoreleasepool {
CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, ((NSSize){1024, 1024}), true, (__bridge CFDictionaryRef)(@{kQLThumbnailPropertyIconFlavorKey : @(0)}));
if (render(cgContext, url, true) == noErr) {
if (GBQuickLookRender(cgContext, url, true) == noErr) {
QLThumbnailRequestFlushContext(thumbnail, cgContext);
CGContextRelease(cgContext);
return noErr;

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>