From bfc2c0180e840aa148e2805d85c2a03823cd9848 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sat, 16 May 2026 16:46:25 +0800 Subject: [PATCH] Add safe NSValue geometry wrappers --- .../DisplayList/DisplayListAsyncLayer.swift | 5 +- .../OpenSwiftUICore/Shape/ShapeLayer.swift | 3 +- .../Shims/UIFoundation/UIGeometry.h | 26 +++++++++ .../Shims/UIFoundation/UIGeometry.m | 55 +++++++++++++++++++ 4 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.h create mode 100644 Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.m diff --git a/Sources/OpenSwiftUICore/Render/DisplayList/DisplayListAsyncLayer.swift b/Sources/OpenSwiftUICore/Render/DisplayList/DisplayListAsyncLayer.swift index b1e2e64bd..db32ca926 100644 --- a/Sources/OpenSwiftUICore/Render/DisplayList/DisplayListAsyncLayer.swift +++ b/Sources/OpenSwiftUICore/Render/DisplayList/DisplayListAsyncLayer.swift @@ -7,6 +7,7 @@ import Foundation import OpenQuartzCoreShims +import UIFoundation_Private protocol _DisplayList_ViewUpdater_AsyncLayerProperty { associatedtype Value @@ -106,7 +107,7 @@ extension DisplayList.ViewUpdater { static func boxValue(_ value: CGPoint) -> NSObject { #if canImport(QuartzCore) - NSValue(point: value) + NSValue(cgPoint: value) #else _openSwiftUIPlatformUnimplementedFailure() #endif @@ -118,7 +119,7 @@ extension DisplayList.ViewUpdater { static func boxValue(_ value: CGRect) -> NSObject { #if canImport(QuartzCore) - NSValue(rect: value) + NSValue(cgRect: value) #else _openSwiftUIPlatformUnimplementedFailure() #endif diff --git a/Sources/OpenSwiftUICore/Shape/ShapeLayer.swift b/Sources/OpenSwiftUICore/Shape/ShapeLayer.swift index a7c318833..c1f28fcf2 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeLayer.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeLayer.swift @@ -9,6 +9,7 @@ import Foundation import OpenQuartzCoreShims import OpenSwiftUI_SPI +import UIFoundation_Private // import OpenRenderBoxShims // MARK: - ShapeLayerHelper [WIP] @@ -175,7 +176,7 @@ extension DisplayList.ViewUpdater { static func boxValue(_ value: CGSize) -> NSObject { #if canImport(Darwin) - NSValue(size: value) + NSValue(cgSize: value) #else _openSwiftUIPlatformUnimplementedFailure() #endif diff --git a/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.h b/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.h new file mode 100644 index 000000000..2fda4681a --- /dev/null +++ b/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.h @@ -0,0 +1,26 @@ +// +// UIGeometry.h +// OpenSwiftUI_SPI + +#pragma once + +#include "OpenSwiftUIBase.h" + +#if OPENSWIFTUI_TARGET_OS_DARWIN + +#import +#import + +OPENSWIFTUI_ASSUME_NONNULL_BEGIN + +@interface NSValue (OpenSwiftUI_UIGeometry) + ++ (NSValue *)valueWithCGPoint_openswiftui_safe_wrapper:(CGPoint)point OPENSWIFTUI_SWIFT_NAME(init(cgPoint:)); ++ (NSValue *)valueWithCGSize_openswiftui_safe_wrapper:(CGSize)size OPENSWIFTUI_SWIFT_NAME(init(cgSize:)); ++ (NSValue *)valueWithCGRect_openswiftui_safe_wrapper:(CGRect)rect OPENSWIFTUI_SWIFT_NAME(init(cgRect:)); + +@end + +OPENSWIFTUI_ASSUME_NONNULL_END + +#endif /* OPENSWIFTUI_TARGET_OS_DARWIN */ diff --git a/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.m b/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.m new file mode 100644 index 000000000..7e388566b --- /dev/null +++ b/Sources/OpenSwiftUI_SPI/Shims/UIFoundation/UIGeometry.m @@ -0,0 +1,55 @@ +// +// UIGeometry.m +// OpenSwiftUI_SPI + +#import "UIGeometry.h" + +#if OPENSWIFTUI_TARGET_OS_DARWIN + +#import + +OPENSWIFTUI_ASSUME_NONNULL_BEGIN + +@implementation NSValue (OpenSwiftUI_UIGeometry) + ++ (NSValue *)valueWithCGPoint_openswiftui_safe_wrapper:(CGPoint)point { + SEL selector = NSSelectorFromString(@"valueWithCGPoint:"); + if ([self respondsToSelector:selector]) { + typedef NSValue *(*Func)(id, SEL, CGPoint); + Func func = (Func)class_getMethodImplementation(object_getClass(self), selector); + if (func != nil) { + return func(self, selector, point); + } + } + return [self valueWithBytes:&point objCType:@encode(CGPoint)]; +} + ++ (NSValue *)valueWithCGSize_openswiftui_safe_wrapper:(CGSize)size { + SEL selector = NSSelectorFromString(@"valueWithCGSize:"); + if ([self respondsToSelector:selector]) { + typedef NSValue *(*Func)(id, SEL, CGSize); + Func func = (Func)class_getMethodImplementation(object_getClass(self), selector); + if (func != nil) { + return func(self, selector, size); + } + } + return [self valueWithBytes:&size objCType:@encode(CGSize)]; +} + ++ (NSValue *)valueWithCGRect_openswiftui_safe_wrapper:(CGRect)rect { + SEL selector = NSSelectorFromString(@"valueWithCGRect:"); + if ([self respondsToSelector:selector]) { + typedef NSValue *(*Func)(id, SEL, CGRect); + Func func = (Func)class_getMethodImplementation(object_getClass(self), selector); + if (func != nil) { + return func(self, selector, rect); + } + } + return [self valueWithBytes:&rect objCType:@encode(CGRect)]; +} + +@end + +OPENSWIFTUI_ASSUME_NONNULL_END + +#endif /* OPENSWIFTUI_TARGET_OS_DARWIN */