Abandoned: macOS: support QuickLook preview #107014

Closed
Ankit Meel wants to merge 8 commits from ankitm:ankitm/quicklook into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
10 changed files with 276 additions and 8 deletions

View File

@ -11,8 +11,6 @@
<array>
<string>blend</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>Blender_Legacy_Document_Icon.icns</string>
<key>CFBundleTypeName</key>
<string>Blender File</string>
<key>CFBundleTypeOSTypes</key>

View File

@ -21,6 +21,10 @@ set(SRC
src/blendthumb_png.cc
)
set(LIB
bf_blenlib
)
if(WIN32)
# -----------------------------------------------------------------------------
# Build `BlendThumb.dll`
@ -36,10 +40,14 @@ if(WIN32)
add_library(BlendThumb SHARED ${SRC} ${SRC_WIN32})
target_link_libraries(BlendThumb bf_blenlib dbghelp.lib Version.lib)
list(APPEND LIB
dbghelp.lib
Version.lib
)
target_link_libraries(BlendThumb ${LIB})
set_target_properties(BlendThumb PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB:msvcrt")
else()
endif()
if(UNIX AND NOT APPLE)
# -----------------------------------------------------------------------------
# Build `blender-thumbnailer` executable
@ -49,7 +57,42 @@ else()
add_executable(blender-thumbnailer ${SRC} ${SRC_CMD})
setup_platform_linker_flags(blender-thumbnailer)
target_link_libraries(blender-thumbnailer bf_blenlib)
target_link_libraries(blender-thumbnailer ${LIB})
if(DEFINED PTHREADS_LIBRARIES)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
endif()
endif()
if(APPLE)
# -----------------------------------------------------------------------------
# Build `blender-thumbnailer` appex
set(SRC_CMD
src/ThumbnailProvider.mm
src/ThumbnailProvider.hh
src/Info.plist
)
add_executable(blender-thumbnailer MACOSX_BUNDLE ${SRC} ${SRC_CMD})
set_target_properties(blender-thumbnailer PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/Info.plist
MACOSX_FRAMEWORK_IDENTIFIER org.blenderfoundation.blender.thumbnailer)
# set_target_properties(blender-thumbnailer PROPERTIES
# XIB_RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/src/Base.lproj")
# Doesn't affect other generators. So need to specify extension for others.
set_target_properties(blender-thumbnailer PROPERTIES
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension)
set_target_properties(blender-thumbnailer PROPERTIES
BUNDLE_EXTENSION appex
BL_CODESIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/src/ThumbnailExtensionMacOS.entitlements)
setup_platform_linker_flags(blender-thumbnailer)
set_target_properties(blender-thumbnailer PROPERTIES BUILD_WITH_INSTALL_RPATH true)
list(APPEND LIB
"-framework QuickLookThumbnailing"
"-fobjc-link-runtime"
"-fapplication-extension"
"-e _NSExtensionMain"
)
target_link_libraries(blender-thumbnailer ${LIB})
if(DEFINED PTHREADS_LIBRARIES)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
endif()

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="PreviewViewController" customModuleProvider="">
<connections>
<outlet property="view" destination="c22-O7-iKe" id="NRM-P4-wb6"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe" userLabel="Preview View">
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,48 @@
<?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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>blender_thumbnailer</string>
<key>CFBundleExecutable</key>
<string>blender-thumbnailer</string>
<key>CFBundleIdentifier</key>
<string>org.blenderfoundation.blender.thumbnailer</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>blender-thumbnailer</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>3.6.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>3.6.0 2023-04-18</string>
<key>LSMinimumSystemVersion</key>
<string>11.3</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportedContentTypes</key>
<array>
<string>org.blenderfoundation.blender.file</string>
</array>
<key>QLThumbnailMinimumDimension</key>
<integer>0</integer>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.thumbnail</string>
<key>NSExtensionPrincipalClass</key>
<string>ThumbnailProvider</string>
<key>com.apple.showsInExtensionsManager</key>
<true/>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,42 @@
lsregister and its listing and detection
more logs in lldb
more logs in console: look for anything qlmanage
must sign the appex bundle with sandbox
must launch the app
appex cannot write at all : inferred from
error 17:53:57.863578+0530 kernel Sandbox: qlmanage(37213) deny(1) file-write-data /dev/dtracehelper
error 17:53:58.033957+0530 kernel Sandbox: qlmanage(37213) deny(1) mach-register com.apple.axserver (per-pid)
error 17:53:58.071424+0530 kernel Sandbox: qlmanage(37213) deny(1) mach-register com.apple.tsm.portname (per-pid)
error 17:53:58.164827+0530 kernel Sandbox: qlmanage(37213) deny(1) user-preference-read com.apple.HIToolbox
error 17:54:00.837220+0530 kernel Sandbox: qlmanage(37213) deny(1) file-write-data /dev/dtracehelper
error 17:54:00.904484+0530 kernel Sandbox: qlmanage(37213) deny(1) file-write-create /Users/ankitkumar/Library/Saved Application State/com.apple.quicklook.qlmanage.savedState
https://eclecticlight.co/2018/04/05/inside-quicklook-previews-with-qlmanage/
in info.plist, add NSExtensionPrincipalClass, add QLThumbnailMinimumDimension
Try removing blend file thumbnail specificaion from blender.app info.plist
Expect
lender-thumbnailer __extensionPrincipalClass != nil - /AppleInternal/Library/BuildRoots/a0876c02-1788-11ed-b9c4-96898e02b808/Library/Caches/com.apple.xbs/Sources/ExtensionFoundation/ExtensionFoundation/Source/NSExtension/NSExtensionSupport/EXConcreteExtensionContextVendor.m:108: Unable to find NSExtensionPrincipalClass (<private>) in extension bundle! Please verify that the extension links the required frameworks and that the value for NSExtensionPrincipalClass is prefixed with '$(PRODUCT_MODULE_NAME).' if the class is implemented in Swift.
fault 00:55:16.449383+0530 blender-thumbnailer [__extensionPrincipalClass conformsToProtocol:@protocol(NSExtensionRequestHandling)] - /AppleInternal/Library/BuildRoots/a0876c02-1788-11ed-b9c4-96898e02b808/Library/Caches/com.apple.xbs/Sources/ExtensionFoundation/ExtensionFoundation/Source/NSExtension/NSExtensionSupport/EXConcreteExtensionContextVendor.m:109: NSExtensionPrincipalClass does not conform to NSExtensionRequestHandling protocol!
Signing blender.app
move blender.app to /Applications or launch it at least once
Don't access files outside sandbox or kernel denies:
default 03:07:03.525360+0530 blender-thumbnailer hello world from blender
error 03:07:03.527837+0530 blender-thumbnailer Couldn't issue file extension for url: <private>
error 03:07:03.531152+0530 kernel Sandbox: com.apple.quickl(476) deny(1) file-read-data /Users/ankitkumar/Pictures/IMG_3158.JPG
restart ?

View File

@ -0,0 +1,12 @@
<?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/>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,12 @@
#pragma once
#import <Quartz/Quartz.h>
#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
NS_ASSUME_NONNULL_BEGIN
@interface ThumbnailProvider : QLThumbnailProvider
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,85 @@
#include <cstdio>
#include <fstream>
#include <unistd.h>
#import <Foundation/Foundation.h>
#import <QuickLook/QLBase.h>
#import <QuickLook/QuickLook.h>
#import "ThumbnailProvider.hh"
#include "BLI_fileops.h"
#include "BLI_filereader.h"
#include "blendthumb.hh"
class FileReaderRAII {
int src_file_ = -1;
public:
explicit FileReaderRAII(int src_file) : src_file_(src_file) {}
~FileReaderRAII()
{
if (src_file_ != -1) {
close(src_file_);
}
}
bool good()
{
return src_file_ != -1;
}
int get()
{
return src_file_;
}
};
static eThumbStatus creator_impl(const char *src_blend_path)
{
eThumbStatus err;
/* Open source file `src_blend`. */
FileReaderRAII src_file_fd = FileReaderRAII(BLI_open(src_blend_path, O_BINARY | O_RDONLY, 0));
if (!src_file_fd.good()) {
return BT_FILE_ERR;
}
/* Thumbnail reading is responsible for freeing `file` and closing `src_file`. */
FileReader *file_content = BLI_filereader_new_file(src_file_fd.get());
if (file_content == nullptr) {
return BT_FILE_ERR;
}
/* Extract thumbnail from file. */
Thumbnail thumb;
err = blendthumb_create_thumb_from_file(file_content, &thumb);
if (err != BT_OK) {
return err;
}
return err;
}
@implementation ThumbnailProvider
- (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request
completionHandler:(void (^)(QLThumbnailReply *_Nullable reply,
NSError *_Nullable error))handler
{
// Add the supported content types to the QLSupportedContentTypes array in
// the Info.plist of the
// extension.
NSLog(@"hello world from blender");
// NSLog(@"%s", request.fileURL.path.UTF8String);
NSURL *foo = [[NSURL alloc]
initFileURLWithFileSystemRepresentation:"/Users/ankitkumar/Pictures/IMG_3158.JPG"
isDirectory:NO
relativeToURL:nil];
QLThumbnailReply *reply = [QLThumbnailReply replyWithImageFileURL:foo];
handler(reply, nil);
}
@end

View File

@ -1352,8 +1352,16 @@ elseif(APPLE)
if(WITH_BLENDER_THUMBNAILER)
install(
TARGETS blender-thumbnailer
DESTINATION Blender.app/Contents/MacOS/
DESTINATION Blender.app/Contents/Plugins
)
get_target_property(BL_CODESIGN_ENTITLEMENTS blender-thumbnailer BL_CODESIGN_ENTITLEMENTS)
install(CODE
"execute_process(
COMMAND codesign
--entitlements \"${BL_CODESIGN_ENTITLEMENTS}\"
--force --deep --sign -
\"${EXECUTABLE_OUTPUT_PATH}/Blender.app/Contents/Plugins/blender-thumbnailer.appex\"
)")
endif()
if(PLATFORM_BUNDLED_LIBRARIES AND TARGETDIR_LIB)

View File

@ -34,7 +34,6 @@ endif()
blender_src_gtest_ex(
NAME blender
SRC "${SRC}"
EXTRA_LIBS "${TEST_LIBS}"
SKIP_ADD_TEST
)
setup_platform_linker_libs(blender_test)