From b732623bb52295d791c0fb4b1277235cf6287b8d Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Fri, 30 Aug 2024 14:38:17 -0700 Subject: [PATCH 01/14] [react-native-macos-init] Push change files for a new version #2177 --- ...ve-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json diff --git a/change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json b/change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json new file mode 100644 index 00000000000000..0e16b789592906 --- /dev/null +++ b/change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Update for Yarn 3+", + "packageName": "react-native-macos-init", + "email": "sanajmi@microsoft.com", + "dependentChangeType": "patch" +} From b86ac5239832d7d72e22cb84b1878ce2f73138fe Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Fri, 30 Aug 2024 16:46:24 -0700 Subject: [PATCH 02/14] fix: Properly import `npm-registry-fetch` in `react-native-macos-init` (#2186) * fix: Properly import `npm-registry-fetch` in `react-native-macos-init` * Change files --- ...ative-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json} | 2 +- packages/react-native-macos-init/src/cli.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename change/{react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json => react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json} (60%) diff --git a/change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json b/change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json similarity index 60% rename from change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json rename to change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json index 0e16b789592906..bd1fdf8776a767 100644 --- a/change/react-native-macos-init-27af1077-e8dd-498f-9813-622bd400487c.json +++ b/change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json @@ -1,6 +1,6 @@ { "type": "patch", - "comment": "Update for Yarn 3+", + "comment": "fix: Properly import `npm-registry-fetch` in `react-native-macos-init`", "packageName": "react-native-macos-init", "email": "sanajmi@microsoft.com", "dependentChangeType": "patch" diff --git a/packages/react-native-macos-init/src/cli.ts b/packages/react-native-macos-init/src/cli.ts index ee62a8a80c80c3..7ff3717322af56 100644 --- a/packages/react-native-macos-init/src/cli.ts +++ b/packages/react-native-macos-init/src/cli.ts @@ -13,8 +13,7 @@ import * as validUrl from 'valid-url'; import * as prompts from 'prompts'; import * as findUp from 'find-up'; import * as chalk from 'chalk'; -// @ts-ignore -import npmFetch from 'npm-registry'; +import * as npmFetch from 'npm-registry-fetch'; const npmConfReg = execSync('npm config get registry').toString().trim(); const NPM_REGISTRY_URL = validUrl.isUri(npmConfReg) From db3f8e7f8758d823b2cbfb812e7a5c6d50e8ce7b Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Fri, 30 Aug 2024 17:02:16 -0700 Subject: [PATCH 03/14] Sync `react-native-macos-init` vesrion with NPM registry using beachball (#2187) --- packages/react-native-macos-init/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-macos-init/package.json b/packages/react-native-macos-init/package.json index f9c073c24b0f07..8d45c1883c5a75 100644 --- a/packages/react-native-macos-init/package.json +++ b/packages/react-native-macos-init/package.json @@ -1,6 +1,6 @@ { "name": "react-native-macos-init", - "version": "2.1.0", + "version": "2.1.1", "description": "CLI to add react-native-macos to an existing react-native project", "main": "index.js", "repository": "https://github.com/microsoft/react-native-macos", From b0111c0d3cc6aeb852d6bfa8776ba73411fe3226 Mon Sep 17 00:00:00 2001 From: Nahuel Veron Date: Fri, 20 Sep 2024 12:20:27 -0300 Subject: [PATCH 04/14] fix: Remove flipper config from the Podfile template (#2195) --- .../local-cli/generator-macos/templates/macos/Podfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native/local-cli/generator-macos/templates/macos/Podfile b/packages/react-native/local-cli/generator-macos/templates/macos/Podfile index b246e1e283dce2..cc3684c055c0a8 100644 --- a/packages/react-native/local-cli/generator-macos/templates/macos/Podfile +++ b/packages/react-native/local-cli/generator-macos/templates/macos/Podfile @@ -14,8 +14,6 @@ target 'HelloWorld-macOS' do :path => '../node_modules/react-native-macos', :hermes_enabled => false, :fabric_enabled => ENV['RCT_NEW_ARCH_ENABLED'] == '1', - # Flipper is not compatible w/ macOS - :flipper_configuration => FlipperConfiguration.disabled, # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) From a87ddb59533d990593b04bab3ad8b7dc553b34e1 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Fri, 20 Sep 2024 08:21:31 -0700 Subject: [PATCH 05/14] fix: Allow viewRegistry to accept subclasses of NSView (#2196) --- packages/react-native/React/Views/RCTShadowView.h | 2 +- packages/react-native/React/Views/RCTViewManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native/React/Views/RCTShadowView.h b/packages/react-native/React/Views/RCTShadowView.h index bb979ec592ae24..7009685257f22a 100644 --- a/packages/react-native/React/Views/RCTShadowView.h +++ b/packages/react-native/React/Views/RCTShadowView.h @@ -17,7 +17,7 @@ @class RCTRootShadowView; @class RCTSparseArray; -typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry); // [macOS] +typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry); // [macOS] /** * ShadowView tree mirrors RCT view tree. Every node is highly stateful. diff --git a/packages/react-native/React/Views/RCTViewManager.h b/packages/react-native/React/Views/RCTViewManager.h index be6c6baf53cdf8..56a80f9830fb8e 100644 --- a/packages/react-native/React/Views/RCTViewManager.h +++ b/packages/react-native/React/Views/RCTViewManager.h @@ -19,7 +19,7 @@ @class RCTSparseArray; @class RCTUIManager; -typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary *viewRegistry); // [macOS] +typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary *viewRegistry); // [macOS] @interface RCTViewManager : NSObject From 704b60c62d09b19b84a779206a6abad2ad6e0b69 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Thu, 26 Sep 2024 06:20:06 -0700 Subject: [PATCH 06/14] fix: Properly clean up RCTDevLoadingView on hide (#2201) --- packages/react-native/React/CoreModules/RCTDevLoadingView.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm index 0ea90573687e4f..b8880b08952857 100644 --- a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm +++ b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm @@ -138,7 +138,7 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo self->_label.font = [UIFont monospacedDigitSystemFontOfSize:12.0 weight:UIFontWeightRegular]; self->_label.textAlignment = NSTextAlignmentCenter; #else // [macOS - self->_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 375, 20) + self->_window = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 375, 20) styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]; @@ -214,6 +214,8 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo }]; #else // [macOS] [RCTKeyWindow() endSheet:self->_window]; + self->_window = nil; + self->_hiding = false; #endif // macOS] }); } From c361308b2fb50d606fd8a04bd7a0978f0fd6f989 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Sat, 28 Sep 2024 06:45:05 -0700 Subject: [PATCH 07/14] fix(CI): Download visionOS if necessary (#2204) --- .ado/jobs/build-test-rntester.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.ado/jobs/build-test-rntester.yml b/.ado/jobs/build-test-rntester.yml index bfee842fac2946..33e5ede15fab85 100644 --- a/.ado/jobs/build-test-rntester.yml +++ b/.ado/jobs/build-test-rntester.yml @@ -98,6 +98,18 @@ jobs: steps: - template: /.ado/templates/apple-tools-setup.yml@self + - ${{ if in(slice.sdk, 'xros', 'xrsimulator') }}: + - task: CmdLine@2 + displayName: Download visionOS SDDK + inputs: + script: | + set -eox + # https://github.com/actions/runner-images/issues/10559 + sudo xcodebuild -runFirstLaunch + sudo xcrun simctl list + sudo xcodebuild -downloadPlatform visionOS + sudo xcodebuild -runFirstLaunch + - task: CmdLine@2 displayName: yarn install inputs: From bb565371e782449d5139a49c4727a98f6df366b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:27:45 -0700 Subject: [PATCH 08/14] Bump rexml from 3.2.6 to 3.3.6 in /packages/helloworld (#2175) Bumps [rexml](https://github.com/ruby/rexml) from 3.2.6 to 3.3.6. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.3.6) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Saad Najmi --- packages/helloworld/Gemfile.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/helloworld/Gemfile.lock b/packages/helloworld/Gemfile.lock index 47123c6dba7775..b1577ea5175b58 100644 --- a/packages/helloworld/Gemfile.lock +++ b/packages/helloworld/Gemfile.lock @@ -76,19 +76,21 @@ GEM netrc (0.11.0) nkf (0.2.0) public_suffix (4.0.7) - rexml (3.2.6) + rexml (3.3.6) + strscan ruby-macho (2.5.1) + strscan (3.1.0) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - xcodeproj (1.24.0) + xcodeproj (1.25.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) nanaimo (~> 0.3.0) - rexml (~> 3.2.4) + rexml (>= 3.3.2, < 4.0) zeitwerk (2.6.13) PLATFORMS From 3ebf897664b8847e9f567453c6f16f5e2fad47f5 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Thu, 3 Oct 2024 18:55:20 -0500 Subject: [PATCH 09/14] fix: Properly dismiss RCTDevLoadingView (#2211) --- .../react-native/React/CoreModules/RCTDevLoadingView.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm index b8880b08952857..c4a1579d1741e1 100644 --- a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm +++ b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm @@ -142,10 +142,10 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]; - self->_window.releasedWhenClosed = NO; self->_window.backgroundColor = [NSColor clearColor]; NSTextField *label = [[NSTextField alloc] initWithFrame:self->_window.contentView.bounds]; + label.font = [NSFont monospacedDigitSystemFontOfSize:12.0 weight:NSFontWeightRegular]; label.alignment = NSTextAlignmentCenter; label.bezeled = NO; label.editable = NO; @@ -169,7 +169,11 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo self->_label.textColor = color; self->_label.backgroundColor = backgroundColor; - [RCTKeyWindow() beginSheet:self->_window completionHandler:nil]; + if (![[RCTKeyWindow() sheets] doesContain:self->_window]) { + [RCTKeyWindow() beginSheet:self->_window completionHandler:^(NSModalResponse returnCode) { + [self->_window orderOut:self]; + }]; + } #endif // macOS] }); From 2d866c826b0987d3b8a6e5435ecd8ed24d1b34bf Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Thu, 3 Oct 2024 18:56:07 -0500 Subject: [PATCH 10/14] feat(RCTUIKit): Shim RCTUIGraphicsImageRenderer (#2209) * feat(RCTUIKit): Shim RCTUIGraphicsImageRenderer * Update RCTBorderDrawing.m * `[RCTUIGraphicsImageRendererFormat defaultFormat]` doesn't return a singleton * `[NSImage lockFocus]` is deprecated. Use a newer API. * fix typo * Implement `format.opaque` --- .../Libraries/Image/RCTImageBlurUtils.mm | 19 +++-- .../Libraries/Image/RCTImageUtils.mm | 18 ++--- packages/react-native/React/Base/RCTUIKit.h | 31 +++++++- .../react-native/React/Base/macOS/RCTUIKit.m | 78 ++++++++++--------- .../React/Views/RCTBorderDrawing.m | 58 +++----------- .../RCTTest/FBSnapshotTestCase/UIImage+Diff.m | 22 +----- 6 files changed, 100 insertions(+), 126 deletions(-) diff --git a/packages/react-native/Libraries/Image/RCTImageBlurUtils.mm b/packages/react-native/Libraries/Image/RCTImageBlurUtils.mm index 889cb5ae629c1b..d4c31a96e2a6c4 100644 --- a/packages/react-native/Libraries/Image/RCTImageBlurUtils.mm +++ b/packages/react-native/Libraries/Image/RCTImageBlurUtils.mm @@ -25,23 +25,22 @@ // convert to ARGB if it isn't if (CGImageGetBitsPerPixel(imageRef) != 32 || !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) { -#if !TARGET_OS_OSX // [macOS] - UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat]; - rendererFormat.scale = inputImage.scale; - UIGraphicsImageRenderer *const renderer = [[UIGraphicsImageRenderer alloc] initWithSize:inputImage.size - format:rendererFormat]; + RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] + rendererFormat.scale = UIImageGetScale(inputImage); // [macOS] + RCTUIGraphicsImageRenderer *const renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:inputImage.size // [macOS] + format:rendererFormat]; +#if !TARGET_OS_OSX // [macOS] imageRef = [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) { [inputImage drawAtPoint:CGPointZero]; }].CGImage; #else // [macOS - UIGraphicsBeginImageContextWithOptions(inputImage.size, NO, imageScale); - [inputImage drawAtPoint:CGPointZero fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - imageRef = (CGImageRef)CFAutorelease(CGBitmapContextCreateImage(UIGraphicsGetCurrentContext())); - UIGraphicsEndImageContext(); + NSImage *image = [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull context) { + [inputImage drawAtPoint:CGPointZero fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + }]; + imageRef = UIImageGetCGImageRef(image); #endif // macOS] } - vImage_Buffer buffer1, buffer2; buffer1.width = buffer2.width = CGImageGetWidth(imageRef); buffer1.height = buffer2.height = CGImageGetHeight(imageRef); diff --git a/packages/react-native/Libraries/Image/RCTImageUtils.mm b/packages/react-native/Libraries/Image/RCTImageUtils.mm index 1a80c1e652498e..9945220e9a1028 100644 --- a/packages/react-native/Libraries/Image/RCTImageUtils.mm +++ b/packages/react-native/Libraries/Image/RCTImageUtils.mm @@ -382,25 +382,19 @@ BOOL RCTUpscalingRequired( } BOOL opaque = !RCTUIImageHasAlpha(image); // [macOS] -#if !TARGET_OS_OSX // [macOS] - UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat]; + RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] rendererFormat.opaque = opaque; rendererFormat.scale = destScale; - UIGraphicsImageRenderer *const renderer = [[UIGraphicsImageRenderer alloc] initWithSize:destSize + RCTUIGraphicsImageRenderer *const renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:destSize // [macOS] format:rendererFormat]; - return [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) { + return [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull context) { // [macOS] CGContextConcatCTM(context.CGContext, transform); +#if !TARGET_OS_OSX // [macOS] [image drawAtPoint:CGPointZero]; - }]; #else // [macOS - UIGraphicsBeginImageContextWithOptions(destSize, opaque, destScale); - CGContextRef currentContext = UIGraphicsGetCurrentContext(); - CGContextConcatCTM(currentContext, transform); - [image drawAtPoint:CGPointZero fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return result; + [image drawAtPoint:CGPointZero fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; #endif // macOS] + }]; } BOOL RCTImageHasAlpha(CGImageRef image) diff --git a/packages/react-native/React/Base/RCTUIKit.h b/packages/react-native/React/Base/RCTUIKit.h index 4ea338501cd67b..8cd17e29b3ca41 100644 --- a/packages/react-native/React/Base/RCTUIKit.h +++ b/packages/react-native/React/Base/RCTUIKit.h @@ -269,9 +269,6 @@ extern "C" { // UIGraphics.h CGContextRef UIGraphicsGetCurrentContext(void); -void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); -NSImage *UIGraphicsGetImageFromCurrentImageContext(void); -void UIGraphicsEndImageContext(void); CGImageRef UIImageGetCGImageRef(NSImage *image); #ifdef __cplusplus @@ -641,3 +638,31 @@ NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END @end #endif + +#if !TARGET_OS_OSX +typedef UIGraphicsImageRendererContext RCTUIGraphicsImageRendererContext; +typedef UIGraphicsImageDrawingActions RCTUIGraphicsImageDrawingActions; +typedef UIGraphicsImageRendererFormat RCTUIGraphicsImageRendererFormat; +typedef UIGraphicsImageRenderer RCTUIGraphicsImageRenderer; +#else +NS_ASSUME_NONNULL_BEGIN +typedef NSGraphicsContext RCTUIGraphicsImageRendererContext; +typedef void (^RCTUIGraphicsImageDrawingActions)(RCTUIGraphicsImageRendererContext *rendererContext); + +@interface RCTUIGraphicsImageRendererFormat : NSObject + ++ (instancetype)defaultFormat; + +@property (nonatomic) CGFloat scale; +@property (nonatomic) BOOL opaque; + +@end + +@interface RCTUIGraphicsImageRenderer : NSObject + +- (instancetype)initWithSize:(CGSize)size format:(RCTUIGraphicsImageRendererFormat *)format; +- (NSImage *)imageWithActions:(NS_NOESCAPE RCTUIGraphicsImageDrawingActions)actions; + +@end +NS_ASSUME_NONNULL_END +#endif diff --git a/packages/react-native/React/Base/macOS/RCTUIKit.m b/packages/react-native/React/Base/macOS/RCTUIKit.m index decd84cda4c88b..48f2ec5f8eff5c 100644 --- a/packages/react-native/React/Base/macOS/RCTUIKit.m +++ b/packages/react-native/React/Base/macOS/RCTUIKit.m @@ -32,37 +32,6 @@ CGContextRef UIGraphicsGetCurrentContext(void) return [[NSGraphicsContext currentContext] CGContext]; } -void UIGraphicsBeginImageContextWithOptions(CGSize size, __unused BOOL opaque, CGFloat scale) -{ - if (scale == 0.0) - { - // TODO: Assert. We can't assume a display scale on macOS - scale = 1.0; - } - - size_t width = ceilf(size.width * scale); - size_t height = ceilf(size.height * scale); - - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8/*bitsPerComponent*/, width * 4/*bytesPerRow*/, colorSpace, kCGImageAlphaPremultipliedFirst); - CGColorSpaceRelease(colorSpace); - - if (ctx != NULL) - { - // flip the context (top left at 0, 0) and scale it - CGContextTranslateCTM(ctx, 0.0, height); - CGContextScaleCTM(ctx, scale, -scale); - - NSGraphicsContext *graphicsContext = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES]; - objc_setAssociatedObject(graphicsContext, &RCTGraphicsContextSizeKey, [NSValue valueWithSize:size], OBJC_ASSOCIATION_COPY_NONATOMIC); - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:graphicsContext]; - - CFRelease(ctx); - } -} - NSImage *UIGraphicsGetImageFromCurrentImageContext(void) { NSImage *image = nil; @@ -83,12 +52,6 @@ void UIGraphicsBeginImageContextWithOptions(CGSize size, __unused BOOL opaque, C return image; } -void UIGraphicsEndImageContext(void) -{ - RCTAssert(objc_getAssociatedObject([NSGraphicsContext currentContext], &RCTGraphicsContextSizeKey), @"The current graphics context is not a React image context!"); - [NSGraphicsContext restoreGraphicsState]; -} - // // functionally equivalent types // @@ -1040,4 +1003,45 @@ - (void)setImage:(UIImage *)image @end +@implementation RCTUIGraphicsImageRendererFormat + ++ (nonnull instancetype)defaultFormat { + RCTUIGraphicsImageRendererFormat *format = [RCTUIGraphicsImageRendererFormat new]; + return format; +} + +@end + +@implementation RCTUIGraphicsImageRenderer +{ + CGSize _size; + RCTUIGraphicsImageRendererFormat *_format; +} + +- (nonnull instancetype)initWithSize:(CGSize)size format:(nonnull RCTUIGraphicsImageRendererFormat *)format { + if (self = [super init]) { + self->_size = size; + self->_format = format; + } + return self; +} + +- (nonnull NSImage *)imageWithActions:(NS_NOESCAPE RCTUIGraphicsImageDrawingActions)actions { + + NSImage *image = [NSImage imageWithSize:_size + flipped:YES + drawingHandler:^BOOL(NSRect dstRect) { + + RCTUIGraphicsImageRendererContext *context = [NSGraphicsContext currentContext]; + if (self->_format.opaque) { + CGContextSetAlpha([context CGContext], 1.0); + } + actions(context); + return YES; + }]; + return image; +} + +@end + #endif diff --git a/packages/react-native/React/Views/RCTBorderDrawing.m b/packages/react-native/React/Views/RCTBorderDrawing.m index 69518c98ec6d13..6fb3f7b5519513 100644 --- a/packages/react-native/React/Views/RCTBorderDrawing.m +++ b/packages/react-native/React/Views/RCTBorderDrawing.m @@ -171,27 +171,16 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn return RCTPathCreateWithRoundedRect(rect, RCTGetCornerInsets(cornerRadii, UIEdgeInsetsZero), NULL); } -#if !TARGET_OS_OSX // [macOS] -static UIGraphicsImageRenderer * -RCTUIGraphicsImageRenderer(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) +static RCTUIGraphicsImageRenderer * // [macOS] +RCTMakeUIGraphicsImageRenderer(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) // [macOS] { const CGFloat alpha = CGColorGetAlpha(backgroundColor); const BOOL opaque = (drawToEdge || !hasCornerRadii) && alpha == 1.0; - UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat]; + RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] rendererFormat.opaque = opaque; - UIGraphicsImageRenderer *const renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:rendererFormat]; + RCTUIGraphicsImageRenderer *const renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:size format:rendererFormat]; // [macOS] return renderer; } -#else // [macOS -static CGContextRef -RCTUIGraphicsBeginImageContext(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge, CGFloat scaleFactor) -{ - const CGFloat alpha = CGColorGetAlpha(backgroundColor); - const BOOL opaque = (drawToEdge || !hasCornerRadii) && alpha == 1.0; - UIGraphicsBeginImageContextWithOptions(size, opaque, scaleFactor); - return UIGraphicsGetCurrentContext(); -} -#endif // macOS] static UIImage *RCTGetSolidBorderImage( RCTCornerRadii cornerRadii, @@ -237,16 +226,11 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn return nil; } // macOS] -#if !TARGET_OS_OSX // [macOS] - UIGraphicsImageRenderer *const imageRenderer = - RCTUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge); - UIImage *image = [imageRenderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull rendererContext) { + RCTUIGraphicsImageRenderer *const imageRenderer = + RCTMakeUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge); // [macOS] + CGColorRetain(backgroundColor); // [macOS] CGColorRefs are not atuomtically retained when passed into a block + UIImage *image = [imageRenderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; -#else // [macOS - CGContextRef context = RCTUIGraphicsBeginImageContext(size, backgroundColor, hasCornerRadii, drawToEdge, scaleFactor); - // Add extra braces for scope to match the indentation level of the iOS block - { -#endif // macOS] const CGRect rect = {.size = size}; CGPathRef path = RCTPathCreateOuterOutline(drawToEdge, rect, cornerRadii); @@ -255,6 +239,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextAddPath(context, path); CGContextFillPath(context); } + CGColorRelease(backgroundColor); // [macOS] CGContextAddPath(context, path); CGPathRelease(path); @@ -402,13 +387,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } CGPathRelease(insetPath); -#if !TARGET_OS_OSX // [macOS] }]; -#else // [macOS - } - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); -#endif // macOS] if (makeStretchable) { #if !TARGET_OS_OSX // [macOS] @@ -509,16 +488,10 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } // macOS] const BOOL hasCornerRadii = RCTCornerRadiiAreAboveThreshold(cornerRadii); -#if !TARGET_OS_OSX // [macOS] - UIGraphicsImageRenderer *const imageRenderer = - RCTUIGraphicsImageRenderer(viewSize, backgroundColor, hasCornerRadii, drawToEdge); - return [imageRenderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull rendererContext) { + RCTUIGraphicsImageRenderer *const imageRenderer = // [macOS] + RCTMakeUIGraphicsImageRenderer(viewSize, backgroundColor, hasCornerRadii, drawToEdge); // [macOS] + return [imageRenderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; -#else // [macOS - CGContextRef context = RCTUIGraphicsBeginImageContext(viewSize, backgroundColor, hasCornerRadii, drawToEdge, scaleFactor); - // Add extra braces for scope to match the indentation level of the iOS block - { -#endif // macOS] const CGRect rect = {.size = viewSize}; if (backgroundColor) { @@ -549,14 +522,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextStrokePath(context); CGPathRelease(path); -#if !TARGET_OS_OSX // [macOS] }]; -#else // [macOS - } - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; -#endif // macOS] } UIImage *RCTGetBorderImage( diff --git a/packages/rn-tester/RCTTest/FBSnapshotTestCase/UIImage+Diff.m b/packages/rn-tester/RCTTest/FBSnapshotTestCase/UIImage+Diff.m index 8cdbee6d6c345a..22546e70d5a2f2 100644 --- a/packages/rn-tester/RCTTest/FBSnapshotTestCase/UIImage+Diff.m +++ b/packages/rn-tester/RCTTest/FBSnapshotTestCase/UIImage+Diff.m @@ -16,20 +16,13 @@ - (UIImage *)diffWithImage:(UIImage *)image } CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); -#if !TARGET_OS_OSX // [macOS] - UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat]; + RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] rendererFormat.opaque = YES; - UIGraphicsImageRenderer *const renderer = [[UIGraphicsImageRenderer alloc] initWithSize:imageSize - format:rendererFormat]; + RCTUIGraphicsImageRenderer *const renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:imageSize // [macOS] + format:rendererFormat]; - return [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull rendererContext) { + return [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; -#else // [macOS - UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0.0); - CGContextRef context = UIGraphicsGetCurrentContext(); - // Add extra braces for scope to match the indentation level of the iOS block - { -#endif // macOS] [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayer(context, NULL); @@ -38,14 +31,7 @@ - (UIImage *)diffWithImage:(UIImage *)image CGContextSetFillColorWithColor(context, [RCTUIColor whiteColor].CGColor); CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); CGContextEndTransparencyLayer(context); -#if !TARGET_OS_OSX // [macOS] }]; -#else // [macOS - } - UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return returnImage; -#endif // macOS] } @end From 8cd5b677f0cb0494d2d2a8637e9f8315501dfef5 Mon Sep 17 00:00:00 2001 From: Navneet Kambo <72474613+nakambo@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:23:54 -0400 Subject: [PATCH 11/14] Multi line text view key handling: add check for first responder (#2215) --- .../Libraries/Text/TextInput/Multiline/RCTUITextView.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm index ef17a793e55cb6..679d8c423eb831 100644 --- a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm +++ b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm @@ -587,7 +587,7 @@ - (void)deleteBackward { } #else // [macOS - (BOOL)performKeyEquivalent:(NSEvent *)event { - if (!self.hasMarkedText && ![self.textInputDelegate textInputShouldHandleKeyEvent:event]) { + if (self.window.firstResponder == self && !self.hasMarkedText && ![self.textInputDelegate textInputShouldHandleKeyEvent:event]) { return YES; } From db89ff48df11efe22f555bedbeed94dc39d88a27 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Sun, 13 Oct 2024 14:15:55 -0500 Subject: [PATCH 12/14] cherrypick: Bring changes to improve our RCTUIGraphicsImageRenderer shim (#2219) * Rename `RCTUIGraphicsImageRenderer` to `RCTMakeUIGraphicsImageRenderer` (#46772) Summary: Because `UIGraphicsImageRenderer` doesn't exist on macOS, I need to shim it for React Native macOS (See https://github.com/microsoft/react-native-macos/pull/2209). I planned to use the name `RCTUIGraphicsImageRenderer`. However.. it seems that is used by a static helper function in `RCTBorderDrawing.m`. So.. let's rename it? The function is just a helper method to make an instance of the class, so I think the name `RCTMakeUIGraphicsImageRenderer` is slightly more idiomatic anyway. This method is not public, so it should not break the public API of React Native. [IOS] [CHANGED] - Rename `RCTUIGraphicsImageRenderer` to `RCTMakeUIGraphicsImageRenderer` Pull Request resolved: https://github.com/facebook/react-native/pull/46772 Test Plan: CI should pass Reviewed By: joevilches Differential Revision: D63765490 Pulled By: cipolleschi fbshipit-source-id: de68dce0f92ec249ea8586dbf7b9ba34a8476074 * fix(iOS): Replace uses of `CGColorRef` with UIColor to avoid manual memory management (#46847) Summary: Update React Native on iOS to do less manual memory management, by replacing uses of `CGColorRef` with `UIColor`, and only calling `UIColor.CGColor` when needed. This results in much less manual memory management, which is probably a good thing in 2024 :D. The downside is there is a breaking change: the signature of a method in `RCTBorderDrawing` changes. This is a followup to https://github.com/facebook/react-native/issues/46797 . After that PR merged and I tested merging React Native macOS to the `0.76-stable` branch cut commit again, I saw even more places I needed to manually call `CGColorRetain` / `CGColorRelease`. The reason is due to React Native macOS specifics (explained below) and I could update React Native macOS to not need these changes, but I thought I would at least throw up a PR to propose the changes, as it may be good to move away from using Core Graphics' C base API as much as possible. With https://github.com/microsoft/react-native-macos/pull/2209 , I wrote a shim of [UIGraphicsImageRenderer](https://developer.apple.com/documentation/uikit/uigraphicsimagerenderer) for macOS. The main difference is my shim calls the NSImage API [imageWithSize:flipped:drawingHandler:](https://developer.apple.com/documentation/appkit/nsimage/1519860-imagewithsize?language=objc) to shim the UIGraphicsImageRenderer API [imageWithData:](https://developer.apple.com/documentation/uikit/uiimage/1624137-imagewithdata). The difference between the two is that the macOS API copies the block, and executes it when Appkit is about to draw the image, while the iOS API executes the block right away. Because of this, I think I am hitting way more places where `CGColorRef` variables needed to be retained / released. Additionally, I hit more of them when I merge to the 0.76 branch cut commit (this is why I didn't catch it with https://github.com/facebook/react-native/issues/46797). Given this constraint, I have a couple of options: 1. Refactor my macOS shim to use the deprecated API [[NSImage lockFocus]](https://developer.apple.com/documentation/appkit/nsimage/1519891-lockfocus) - I am not a fan of this because `lockFocus` was deprecated for `imageWithSize:flipped:drawingHandler:` 2. Refactor my macOS shim to do what we used to do: Create a CGContext manually and write it to an image - This is probably OK. Relies on less Appkit specifics, and potentially gives more control to RN on the rendering layer, which I recall lenaic told me is better for Fabric) 3. Refactor React Native to avoid CGColorRef altogether, and use `UIColor` (which ARC will memory manage for us) as much as possible. - This is the approach of this PR and my preferred approach. The downside is this changes the signature of some of the methods in `RCTBorderDrawing` which is a breaking change. I've seen other PRs do this, so maybe its OK? [IOS] [BREAKING] - Replace uses of `CGColorRef` with UIColor to avoid manual memory management Pull Request resolved: https://github.com/facebook/react-native/pull/46847 Test Plan: Launching RNTester's View example (which tests a lot of the border / outline / shadow rendering) does not crash for me on both iOS and macOS. Reviewed By: NickGerleman Differential Revision: D63989547 Pulled By: joevilches fbshipit-source-id: 5e85e17567e3dd8b4b0388452398954ad2e02464 * Followup fixes * Remove extra scaleFactor argument that is now unused * Further reduce diffs related to scaleFactor * fix typos and dead code --- .../View/RCTViewComponentView.mm | 42 ++++-------- .../React/Fabric/RCTConversions.h | 6 -- .../React/Views/RCTBorderDrawing.h | 13 ++-- .../React/Views/RCTBorderDrawing.m | 65 +++++++++---------- packages/react-native/React/Views/RCTView.m | 37 ++++------- 5 files changed, 60 insertions(+), 103 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index f0958d5fbc4fd6..066ddb6de776c1 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -260,9 +260,8 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & // `shadowColor` if (oldViewProps.shadowColor != newViewProps.shadowColor) { - CGColorRef shadowColor = RCTCreateCGColorRefFromSharedColor(newViewProps.shadowColor); - self.layer.shadowColor = shadowColor; - CGColorRelease(shadowColor); + RCTUIColor *shadowColor = RCTUIColorFromSharedColor(newViewProps.shadowColor); // [macOS] + self.layer.shadowColor = shadowColor.CGColor; needsInvalidateLayer = YES; } @@ -584,18 +583,10 @@ static RCTCornerRadii RCTCornerRadiiFromBorderRadii(BorderRadii borderRadii) static RCTBorderColors RCTCreateRCTBorderColorsFromBorderColors(BorderColors borderColors) { return RCTBorderColors{ - .top = RCTCreateCGColorRefFromSharedColor(borderColors.top), - .left = RCTCreateCGColorRefFromSharedColor(borderColors.left), - .bottom = RCTCreateCGColorRefFromSharedColor(borderColors.bottom), - .right = RCTCreateCGColorRefFromSharedColor(borderColors.right)}; -} - -static void RCTReleaseRCTBorderColors(RCTBorderColors borderColors) -{ - CGColorRelease(borderColors.top); - CGColorRelease(borderColors.left); - CGColorRelease(borderColors.bottom); - CGColorRelease(borderColors.right); + .top = RCTUIColorFromSharedColor(borderColors.top), + .left = RCTUIColorFromSharedColor(borderColors.left), + .bottom = RCTUIColorFromSharedColor(borderColors.bottom), + .right = RCTUIColorFromSharedColor(borderColors.right)}; } static CALayerCornerCurve CornerCurveFromBorderCurve(BorderCurve borderCurve) @@ -800,9 +791,9 @@ - (void)invalidateLayer (*borderMetrics.borderColors.left).getUIColor() != nullptr)); #if !TARGET_OS_OSX // [macOS] - CGColorRef backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor; + RCTUIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection]; #else // [macOS - CGColorRef backgroundColor = _backgroundColor.CGColor; + RCTUIColor *backgroundColor = _backgroundColor; #endif // macOS] if (useCoreAnimationBorderRendering) { @@ -810,14 +801,12 @@ - (void)invalidateLayer [_borderLayer removeFromSuperlayer]; layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left; - CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left); - layer.borderColor = borderColor; - CGColorRelease(borderColor); + layer.borderColor = RCTUIColorFromSharedColor(borderMetrics.borderColors.left).CGColor; layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft; layer.cornerCurve = CornerCurveFromBorderCurve(borderMetrics.borderCurves.topLeft); - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; } else { if (!_borderLayer) { CALayer *borderLayer = [CALayer new]; @@ -835,12 +824,6 @@ - (void)invalidateLayer RCTBorderColors borderColors = RCTCreateRCTBorderColorsFromBorderColors(borderMetrics.borderColors); -#if TARGET_OS_OSX // [macOS - CGFloat scaleFactor = _layoutMetrics.pointScaleFactor; -#else - // On iOS setting the scaleFactor to 0.0 will default to the device's native scale factor. - CGFloat scaleFactor = 0.0; -#endif // macOS] UIImage *image = RCTGetBorderImage( RCTBorderStyleFromBorderStyle(borderMetrics.borderStyles.left), layer.bounds.size, @@ -848,10 +831,8 @@ - (void)invalidateLayer RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths), borderColors, backgroundColor, - self.clipsToBounds, - scaleFactor); // [macOS] + self.clipsToBounds); - RCTReleaseRCTBorderColors(borderColors); if (image == nil) { _borderLayer.contents = nil; @@ -866,6 +847,7 @@ - (void)invalidateLayer _borderLayer.contents = (id)image.CGImage; _borderLayer.contentsScale = image.scale; #else // [macOS + CGFloat scaleFactor = _layoutMetrics.pointScaleFactor; _borderLayer.contents = [image layerContentsForContentsScale:scaleFactor]; _borderLayer.contentsScale = scaleFactor; #endif // macOS] diff --git a/packages/react-native/React/Fabric/RCTConversions.h b/packages/react-native/React/Fabric/RCTConversions.h index 66ce1342716a7a..b797136759f8c1 100644 --- a/packages/react-native/React/Fabric/RCTConversions.h +++ b/packages/react-native/React/Fabric/RCTConversions.h @@ -40,12 +40,6 @@ inline RCTUIColor *_Nullable RCTUIColorFromSharedColor(const facebook::react::Sh return RCTPlatformColorFromColor(*sharedColor); } -inline CF_RETURNS_RETAINED CGColorRef _Nullable RCTCreateCGColorRefFromSharedColor( - const facebook::react::SharedColor &sharedColor) -{ - return CGColorRetain(RCTUIColorFromSharedColor(sharedColor).CGColor); -} - inline CGPoint RCTCGPointFromPoint(const facebook::react::Point &point) { return {point.x, point.y}; diff --git a/packages/react-native/React/Views/RCTBorderDrawing.h b/packages/react-native/React/Views/RCTBorderDrawing.h index 497e1100624189..e213bfef40adff 100644 --- a/packages/react-native/React/Views/RCTBorderDrawing.h +++ b/packages/react-native/React/Views/RCTBorderDrawing.h @@ -25,10 +25,10 @@ typedef struct { } RCTCornerInsets; typedef struct { - CGColorRef top; - CGColorRef left; - CGColorRef bottom; - CGColorRef right; + RCTUIColor *top; + RCTUIColor *left; + RCTUIColor *bottom; + RCTUIColor *right; } RCTBorderColors; /** @@ -64,6 +64,5 @@ RCT_EXTERN UIImage *RCTGetBorderImage( RCTCornerRadii cornerRadii, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, - BOOL drawToEdge, - CGFloat scaleFactor); // [macOS] + RCTUIColor *backgroundColor, // [macOS] + BOOL drawToEdge); diff --git a/packages/react-native/React/Views/RCTBorderDrawing.m b/packages/react-native/React/Views/RCTBorderDrawing.m index 6fb3f7b5519513..5961da461088da 100644 --- a/packages/react-native/React/Views/RCTBorderDrawing.m +++ b/packages/react-native/React/Views/RCTBorderDrawing.m @@ -26,9 +26,9 @@ BOOL RCTCornerRadiiAreEqual(RCTCornerRadii cornerRadii) BOOL RCTBorderColorsAreEqual(RCTBorderColors borderColors) { - return CGColorEqualToColor(borderColors.left, borderColors.right) && - CGColorEqualToColor(borderColors.left, borderColors.top) && - CGColorEqualToColor(borderColors.left, borderColors.bottom); + return CGColorEqualToColor(borderColors.left.CGColor, borderColors.right.CGColor) && + CGColorEqualToColor(borderColors.left.CGColor, borderColors.top.CGColor) && + CGColorEqualToColor(borderColors.left.CGColor, borderColors.bottom.CGColor); } RCTCornerInsets RCTGetCornerInsets(RCTCornerRadii cornerRadii, UIEdgeInsets edgeInsets) @@ -172,9 +172,9 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } static RCTUIGraphicsImageRenderer * // [macOS] -RCTMakeUIGraphicsImageRenderer(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) // [macOS] +RCTMakeUIGraphicsImageRenderer(CGSize size, RCTUIColor *backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge) // [macOS] { - const CGFloat alpha = CGColorGetAlpha(backgroundColor); + const CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor); const BOOL opaque = (drawToEdge || !hasCornerRadii) && alpha == 1.0; RCTUIGraphicsImageRendererFormat *const rendererFormat = [RCTUIGraphicsImageRendererFormat defaultFormat]; // [macOS] rendererFormat.opaque = opaque; @@ -187,10 +187,9 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGSize viewSize, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, - BOOL drawToEdge, - CGFloat scaleFactor // [macOS] -) { + RCTUIColor *backgroundColor, // [macOS] + BOOL drawToEdge) +{ const BOOL hasCornerRadii = RCTCornerRadiiAreAboveThreshold(cornerRadii); const RCTCornerInsets cornerInsets = RCTGetCornerInsets(cornerRadii, borderInsets); @@ -227,19 +226,17 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } // macOS] RCTUIGraphicsImageRenderer *const imageRenderer = - RCTMakeUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge); // [macOS] - CGColorRetain(backgroundColor); // [macOS] CGColorRefs are not atuomtically retained when passed into a block + RCTMakeUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge); UIImage *image = [imageRenderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; const CGRect rect = {.size = size}; CGPathRef path = RCTPathCreateOuterOutline(drawToEdge, rect, cornerRadii); if (backgroundColor) { - CGContextSetFillColorWithColor(context, backgroundColor); + CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextAddPath(context, path); CGContextFillPath(context); } - CGColorRelease(backgroundColor); // [macOS] CGContextAddPath(context, path); CGPathRelease(path); @@ -251,7 +248,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn BOOL hasEqualColors = RCTBorderColorsAreEqual(borderColors); if ((drawToEdge || !hasCornerRadii) && hasEqualColors) { - CGContextSetFillColorWithColor(context, borderColors.left); + CGContextSetFillColorWithColor(context, borderColors.left.CGColor); CGContextAddRect(context, rect); CGContextAddPath(context, insetPath); CGContextEOFillPath(context); @@ -316,7 +313,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn } } - CGColorRef currentColor = NULL; + RCTUIColor *currentColor = nil; // RIGHT if (borderInsets.right > 0) { @@ -340,8 +337,8 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){size.width, size.height}, }; - if (!CGColorEqualToColor(currentColor, borderColors.bottom)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.bottom.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.bottom; } @@ -357,8 +354,8 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){0, size.height}, }; - if (!CGColorEqualToColor(currentColor, borderColors.left)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.left.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.left; } @@ -374,15 +371,15 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn (CGPoint){size.width, 0}, }; - if (!CGColorEqualToColor(currentColor, borderColors.top)) { - CGContextSetFillColorWithColor(context, currentColor); + if (!CGColorEqualToColor(currentColor.CGColor, borderColors.top.CGColor)) { + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); currentColor = borderColors.top; } CGContextAddLines(context, points, sizeof(points) / sizeof(*points)); } - CGContextSetFillColorWithColor(context, currentColor); + CGContextSetFillColorWithColor(context, currentColor.CGColor); CGContextFillPath(context); } @@ -466,10 +463,9 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGSize viewSize, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, - BOOL drawToEdge, - CGFloat scaleFactor // [macOS] -) { + RCTUIColor *backgroundColor, // [macOS] + BOOL drawToEdge) +{ NSCParameterAssert(borderStyle == RCTBorderStyleDashed || borderStyle == RCTBorderStyleDotted); if (!RCTBorderColorsAreEqual(borderColors) || !RCTBorderInsetsAreEqual(borderInsets)) { @@ -489,7 +485,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn const BOOL hasCornerRadii = RCTCornerRadiiAreAboveThreshold(cornerRadii); RCTUIGraphicsImageRenderer *const imageRenderer = // [macOS] - RCTMakeUIGraphicsImageRenderer(viewSize, backgroundColor, hasCornerRadii, drawToEdge); // [macOS] + RCTMakeUIGraphicsImageRenderer(viewSize, backgroundColor, hasCornerRadii, drawToEdge); return [imageRenderer imageWithActions:^(RCTUIGraphicsImageRendererContext *_Nonnull rendererContext) { // [macOS] const CGContextRef context = rendererContext.CGContext; const CGRect rect = {.size = viewSize}; @@ -499,7 +495,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextAddPath(context, outerPath); CGPathRelease(outerPath); - CGContextSetFillColorWithColor(context, backgroundColor); + CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillPath(context); } @@ -518,7 +514,7 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn CGContextSetStrokeColorWithColor(context, [RCTUIColor yellowColor].CGColor); // [macOS] CGContextAddPath(context, path); - CGContextSetStrokeColorWithColor(context, borderColors.top); + CGContextSetStrokeColorWithColor(context, borderColors.top.CGColor); CGContextStrokePath(context); CGPathRelease(path); @@ -531,17 +527,16 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn RCTCornerRadii cornerRadii, UIEdgeInsets borderInsets, RCTBorderColors borderColors, - CGColorRef backgroundColor, - BOOL drawToEdge, - CGFloat scaleFactor // [macOS] -) { + RCTUIColor *backgroundColor, // [macOS] + BOOL drawToEdge) +{ switch (borderStyle) { case RCTBorderStyleSolid: - return RCTGetSolidBorderImage(cornerRadii, viewSize, borderInsets, borderColors, backgroundColor, drawToEdge, scaleFactor); // [macOS] + return RCTGetSolidBorderImage(cornerRadii, viewSize, borderInsets, borderColors, backgroundColor, drawToEdge); case RCTBorderStyleDashed: case RCTBorderStyleDotted: return RCTGetDashedOrDottedBorderImage( - borderStyle, cornerRadii, viewSize, borderInsets, borderColors, backgroundColor, drawToEdge, scaleFactor); // [macOS] + borderStyle, cornerRadii, viewSize, borderInsets, borderColors, backgroundColor, drawToEdge); case RCTBorderStyleUnset: break; } diff --git a/packages/react-native/React/Views/RCTView.m b/packages/react-native/React/Views/RCTView.m index ba66126e4169ec..615aa693ab84f1 100644 --- a/packages/react-native/React/Views/RCTView.m +++ b/packages/react-native/React/Views/RCTView.m @@ -1117,10 +1117,10 @@ - (RCTBorderColors)borderColors #endif // [macOS] return (RCTBorderColors){ - (borderTopColor ?: borderColor).CGColor, - (directionAwareBorderLeftColor ?: borderColor).CGColor, - (borderBottomColor ?: borderColor).CGColor, - (directionAwareBorderRightColor ?: borderColor).CGColor, + (borderTopColor ?: borderColor), + (directionAwareBorderLeftColor ?: borderColor), + (borderBottomColor ?: borderColor), + (directionAwareBorderRightColor ?: borderColor), }; } @@ -1165,18 +1165,17 @@ - (void)displayLayer:(CALayer *)layer // the content. For this reason, only use iOS border drawing when clipping // or when the border is hidden. - (borderInsets.top == 0 || (borderColors.top && CGColorGetAlpha(borderColors.top) == 0) || self.clipsToBounds); + (borderInsets.top == 0 || (borderColors.top && CGColorGetAlpha(borderColors.top.CGColor) == 0) || + self.clipsToBounds); // iOS clips to the outside of the border, but CSS clips to the inside. To // solve this, we'll need to add a container view inside the main view to // correctly clip the subviews. - CGColorRef backgroundColor; - #if !TARGET_OS_OSX // [macOS] - backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor; + RCTUIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection]; #else // [macOS - backgroundColor = [_backgroundColor CGColor]; + RCTUIColor *backgroundColor = _backgroundColor; #endif // macOS] #if TARGET_OS_OSX // [macOS @@ -1194,30 +1193,17 @@ - (void)displayLayer:(CALayer *)layer #endif // macOS] if (useIOSBorderRendering) { layer.cornerRadius = cornerRadii.topLeft; - layer.borderColor = borderColors.left; + layer.borderColor = borderColors.left.CGColor; layer.borderWidth = borderInsets.left; - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; layer.contents = nil; layer.needsDisplayOnBoundsChange = NO; layer.mask = nil; return; } -#if TARGET_OS_OSX // [macOS - CGFloat scaleFactor = self.window.backingScaleFactor; - if (scaleFactor == 0.0 && RCTRunningInTestEnvironment()) { - // When running in the test environment the view is not on screen. - // Use a scaleFactor of 1 so that the test results are machine independent. - scaleFactor = 1; - } - RCTAssert(scaleFactor != 0.0, @"displayLayer occurs before the view is in a window?"); -#else - // On iOS setting the scaleFactor to 0.0 will default to the device's native scale factor. - CGFloat scaleFactor = 0.0; -#endif // macOS] - UIImage *image = RCTGetBorderImage( - _borderStyle, layer.bounds.size, cornerRadii, borderInsets, borderColors, backgroundColor, self.clipsToBounds, scaleFactor); // [macOS] + _borderStyle, layer.bounds.size, cornerRadii, borderInsets, borderColors, backgroundColor, self.clipsToBounds); layer.backgroundColor = NULL; @@ -1238,6 +1224,7 @@ - (void)displayLayer:(CALayer *)layer layer.contents = (id)image.CGImage; layer.contentsScale = image.scale; #else // [macOS + CGFloat scaleFactor = self.window.backingScaleFactor; layer.contents = [image layerContentsForContentsScale:scaleFactor]; layer.contentsScale = scaleFactor; #endif // macOS] From 2f944ebd86e6bf7f6becf5da2403bedc0ffa2ccb Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Tue, 15 Oct 2024 14:56:55 -0500 Subject: [PATCH 13/14] fix(CI): Fix `verify react-native-macos-init` job (#2199) * fix: Sync `react-native-macos-init` version with NPM registry * build react-native-macos-init first * fixes --- .ado/jobs/build-test-rntester.yml | 2 +- .ado/jobs/test-react-native-macos-init.yml | 42 ++++++++++++++++--- packages/react-native-macos-init/package.json | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/.ado/jobs/build-test-rntester.yml b/.ado/jobs/build-test-rntester.yml index 33e5ede15fab85..9b3d3d269199cb 100644 --- a/.ado/jobs/build-test-rntester.yml +++ b/.ado/jobs/build-test-rntester.yml @@ -103,7 +103,7 @@ jobs: displayName: Download visionOS SDDK inputs: script: | - set -eox + set -eox pipefail # https://github.com/actions/runner-images/issues/10559 sudo xcodebuild -runFirstLaunch sudo xcrun simctl list diff --git a/.ado/jobs/test-react-native-macos-init.yml b/.ado/jobs/test-react-native-macos-init.yml index f9e510126fa613..2bb208bbdc7c35 100644 --- a/.ado/jobs/test-react-native-macos-init.yml +++ b/.ado/jobs/test-react-native-macos-init.yml @@ -13,6 +13,22 @@ jobs: - template: /.ado/templates/apple-tools-setup.yml@self + - task: CmdLine@2 + displayName: yarn install react-native-macos-init + inputs: + script: | + set -eox pipefail + cd packages/react-native-macos-init + yarn install + + - task: CmdLine@2 + displayName: Build react-native-macos-init + inputs: + script: | + set -eox pipefail + cd packages/react-native-macos-init + yarn build + - template: /.ado/templates/verdaccio-init.yml@self - template: /.ado/templates/verdaccio-publish.yml@self @@ -21,12 +37,15 @@ jobs: - task: CmdLine@2 displayName: yarn install (local react-native-macos) inputs: - script: yarn install --immutable + script: | + set -eox pipefail + yarn install --immutable - task: CmdLine@2 displayName: yarn install (local react-native-macos-init) inputs: script: | + set -eox pipefail cd packages/react-native-macos-init yarn install --immutable @@ -34,29 +53,40 @@ jobs: displayName: yarn build (local react-native-macos-init) inputs: script: | + set -eox pipefail cd packages/react-native-macos-init yarn build - task: CmdLine@2 displayName: Init new project inputs: - script: npx --yes react-native@0.71.5 init testcli --template react-native@0.71.5 --skip-install + script: | + set -eox pipefail + npx --yes @react-native-community/cli init testcli --version 0.75 --skip-install workingDirectory: $(Agent.BuildDirectory) - task: CmdLine@2 - displayName: yarn install (local react-native-macos-init) + displayName: yarn install (testcli) inputs: - script: yarn install --immutable + script: | + set -eox pipefail + yarn install --mode=update-lockfile + # `update-lockfile` skips the linking step, so we need to run `yarn install` again + yarn install workingDirectory: $(Agent.BuildDirectory)/testcli - task: CmdLine@2 displayName: Apply macos template inputs: - script: npx react-native-macos-init --version latest --overwrite --prerelease + script: | + set -eox pipefail + npx react-native-macos-init --version latest --overwrite --prerelease workingDirectory: $(Agent.BuildDirectory)/testcli - task: CmdLine@2 displayName: Run macos [test] inputs: - script: npx react-native run-macos + script: | + set -eox pipefail + npx react-native run-macos workingDirectory: $(Agent.BuildDirectory)/testcli diff --git a/packages/react-native-macos-init/package.json b/packages/react-native-macos-init/package.json index 8d45c1883c5a75..31748b81813d31 100644 --- a/packages/react-native-macos-init/package.json +++ b/packages/react-native-macos-init/package.json @@ -1,6 +1,6 @@ { "name": "react-native-macos-init", - "version": "2.1.1", + "version": "2.1.2", "description": "CLI to add react-native-macos to an existing react-native project", "main": "index.js", "repository": "https://github.com/microsoft/react-native-macos", From 09cf897e0a71b8f5edb1eacc85cc4ef58128a206 Mon Sep 17 00:00:00 2001 From: React-Native Bot <53619745+rnbot@users.noreply.github.com> Date: Tue, 15 Oct 2024 20:02:43 +0000 Subject: [PATCH 14/14] applying package updates ***NO_CI*** --- ...init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json | 7 ------- packages/react-native-macos-init/CHANGELOG.json | 15 +++++++++++++++ packages/react-native-macos-init/CHANGELOG.md | 10 +++++++++- packages/react-native-macos-init/package.json | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json diff --git a/change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json b/change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json deleted file mode 100644 index bd1fdf8776a767..00000000000000 --- a/change/react-native-macos-init-f8ea158b-582a-420c-8fb7-8a1f75eb2cbe.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "patch", - "comment": "fix: Properly import `npm-registry-fetch` in `react-native-macos-init`", - "packageName": "react-native-macos-init", - "email": "sanajmi@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/react-native-macos-init/CHANGELOG.json b/packages/react-native-macos-init/CHANGELOG.json index da31da7cc2813b..9c136b22bb5926 100644 --- a/packages/react-native-macos-init/CHANGELOG.json +++ b/packages/react-native-macos-init/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "react-native-macos-init", "entries": [ + { + "date": "Tue, 15 Oct 2024 20:02:42 GMT", + "version": "2.1.3", + "tag": "react-native-macos-init_v2.1.3", + "comments": { + "patch": [ + { + "author": "sanajmi@microsoft.com", + "package": "react-native-macos-init", + "commit": "b86ac5239832d7d72e22cb84b1878ce2f73138fe", + "comment": "fix: Properly import `npm-registry-fetch` in `react-native-macos-init`" + } + ] + } + }, { "date": "Mon, 18 May 2020 23:31:12 GMT", "tag": "react-native-macos-init_v2.1.0", diff --git a/packages/react-native-macos-init/CHANGELOG.md b/packages/react-native-macos-init/CHANGELOG.md index d2625e41003e5c..29d551dfceb093 100644 --- a/packages/react-native-macos-init/CHANGELOG.md +++ b/packages/react-native-macos-init/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - react-native-macos-init -This log was last generated on Mon, 18 May 2020 23:31:12 GMT and should not be manually modified. +This log was last generated on Tue, 15 Oct 2024 20:02:42 GMT and should not be manually modified. +## 2.1.3 + +Tue, 15 Oct 2024 20:02:42 GMT + +### Patches + +- fix: Properly import `npm-registry-fetch` in `react-native-macos-init` (sanajmi@microsoft.com) + ## 2.1.0 Mon, 18 May 2020 23:31:12 GMT diff --git a/packages/react-native-macos-init/package.json b/packages/react-native-macos-init/package.json index 31748b81813d31..d9f9363d01c6fc 100644 --- a/packages/react-native-macos-init/package.json +++ b/packages/react-native-macos-init/package.json @@ -1,6 +1,6 @@ { "name": "react-native-macos-init", - "version": "2.1.2", + "version": "2.1.3", "description": "CLI to add react-native-macos to an existing react-native project", "main": "index.js", "repository": "https://github.com/microsoft/react-native-macos",