Skip to content

Commit 30d5349

Browse files
committed
feat(macos): port RedBox 2.0 to AppKit + finish 0.85 build bring-up
The big lift: a full native macOS port of upstream's new RedBox 2.0 error overlay (introduced in RN 0.85), plus the assorted compile fixes needed to bring RNTester-macOS to a green build against 0.85. ## RedBox 2.0 macOS port (~1500 new lines of AppKit code) Upstream 0.85 introduced a fullscreen "RedBox 2.0" dev error overlay implemented as a UIKit-only UIViewController hierarchy. We need this on macOS or the fork's dev experience regresses badly. `RCTRedBox2Controller.mm` (+1014 lines macOS branch): full NSViewController port. Owns a borderless NSWindow at NSStatusWindowLevel sized to the key window. NSTableView (wrapped in NSScrollView) renders a flat-row model derived from the iOS section hierarchy: a RCTRedBox2RowDescriptor array with kind ∈ {Message, CodeFrame, SectionHeader, StackFrame}. Custom NSTableCellView factory methods for each row kind. RCTRedBox2NoSelectionRowView suppresses highlight on non-stack rows. RCTRedBox2RootView overrides acceptsFirstResponder + keyDown: to handle Escape / Cmd-R / Cmd-Opt-C shortcuts. NSPasteboard.generalPasteboard for the Copy action. NSTimer-based auto-retry countdown with Reload button title updates. RCTRedBoxHMRClient integration unchanged (pure Foundation). Header bar uses RCTRedBox2ErrorColor, body uses RCTRedBox2BackgroundColor, ANSI-highlighted code frame via RCTRedBox2AnsiParser. `RCTRedBoxController.mm` (+509 lines macOS branch): legacy RedBoxController port (the pre-2.0 RedBox kept as fallback under RCT_DEV_MENU). Presented via presentViewControllerAsSheet: on the key window's content view controller (matches the pre-existing fork pattern in RCTRedBox.mm). NSButton with keyEquivalent + Modifier mask for Esc/Cmd-R/Cmd-Opt-C/Cmd-E shortcuts. NSButton+RCTRedBox category mirrors UIButton+RCTRedBox for block-based handlers. `RCTRedBox2Controller+Internal.h` and `RCTRedBoxController+Internal.h`: gated declarations with #if !TARGET_OS_OSX/#else so consumers pick up the right superclass + protocol set. `RCTRedBox2AnsiParser.{h,mm}`: switched from UIColor to RCTUIColor (fork's cross-platform NSColor alias). UIFont is left as-is since RCTUIKitCompat.h @compatibility_alias-es it to NSFont. `RCTRedBox.mm`: deleted ~757 lines of inline duplicate RCTRedBoxController + UIButton/NSButton+RCTRedBox categories + RCTRedBoxControllerActionDelegate protocol. Those are now provided by the externalized files imported via the +Internal.h headers. ## Build bring-up fixes (other files) - RCTUtils.mm: stray `#if !TARGET_OS_OSX` at line 42 was missing its inner `#endif` for the `#if !TARGET_OS_TV` nest, which silently swallowed lines 49-720 into the iOS branch — meaning RCTKeyWindow, RCTSharedApplication, RCTIsMainQueue, RCTExecuteOnMainQueue, RCTJSONClean, RCTJSONStringify, RCTJSONParse, RCTRoundPixelValue, RCTCeilPixelValue, RCTSizeInPixels, RCTScreenScale, RCTScreenSize, RCTViewportSize, RCTSwitchSize, RCTFontSizeMultiplier, RCTClassOverridesInstanceMethod, RCTJSErrorFromNSError, RCTJSErrorFromCodeMessageAndNSError, RCTRunningInTestEnvironment, RCTAreLegacyLogsEnabled, RCTUnsafeExecuteOnMainQueueSync all went undefined on macOS. Added the missing `#endif` and wrapped RCTPresentedViewController (which is iOS-only — uses UIWindow.rootViewController) in its own `#if !TARGET_OS_OSX`. - RCTDevLoadingView.mm: dealloc was poking _window with iOS-only `.hidden`; switched to RCTPlatformWindow typedef and guarded the hide path with `[window orderOut:nil]` on macOS. - RCTVirtualViewComponentView.mm: `_getParentVirtualViewContainer` switched UIView to RCTUIView typedef. - RCTViewComponentView.mm: guarded `subview.accessibilityElementsHidden` read in RCTRecursiveAccessibilityLabel behind `#if !TARGET_OS_OSX` (NSView has no such property). - RCTSurfaceTouchHandler.mm: guarded `otherGestureRecognizer.cancelsTouchesInView` read behind `#if !TARGET_OS_OSX` (NSGestureRecognizer has no such property). - RCTScheduler.mm: CADisplayLink's `+displayLinkWithTarget:selector:` is iOS-only on the standalone class. Use the macOS 14+ `-[NSScreen displayLinkWithTarget:selector:]` variant. - RCTLegacyViewManagerInteropComponentView.mm: split `hitTest:point withEvent:` into iOS (UIView signature) and macOS (NSView signature without event arg) branches. ## Validation `xcodebuild -workspace RNTesterPods.xcworkspace -scheme RNTester-macOS -configuration Debug -destination 'generic/platform=macOS' ARCHS=arm64 ONLY_ACTIVE_ARCH=YES build` → `** BUILD SUCCEEDED **`. RNTester-macOS.app: 51 MB, dylib links cleanly. Full source tree compiles + links on macOS 14.6 target / Xcode 26.5 SDK / arm64.
1 parent 55e5de4 commit 30d5349

14 files changed

Lines changed: 1591 additions & 771 deletions

packages/react-native/React/Base/RCTUtils.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
// Returns the current device's orientation
4444
#if !TARGET_OS_TV
4545
UIDeviceOrientation RCTDeviceOrientation(void);
46+
#endif // !TARGET_OS_TV
4647
#endif // [macOS]
4748

4849
// Whether the New Architecture is enabled or not
@@ -702,6 +703,7 @@ BOOL RCTRunningInAppExtension(void)
702703
}
703704
#endif
704705

706+
#if !TARGET_OS_OSX // [macOS] RCTPresentedViewController uses iOS-only UIWindow.rootViewController + presentedViewController chain
705707
UIViewController *__nullable RCTPresentedViewController(void)
706708
{
707709
if ([RCTUtilsUIOverride hasPresentedViewController]) {

packages/react-native/React/CoreModules/RCTDevLoadingView.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,15 @@ - (void)dealloc
6868
{
6969
[self clearInitialMessageDelay];
7070
[[NSNotificationCenter defaultCenter] removeObserver:self];
71-
UIWindow *window = _window;
71+
RCTPlatformWindow *window = _window; // [macOS]
7272
_window = nil;
7373
if (window) {
7474
RCTExecuteOnMainQueue(^{
75+
#if !TARGET_OS_OSX // [macOS]
7576
window.hidden = YES;
77+
#else // [macOS
78+
[window orderOut:nil];
79+
#endif // macOS]
7680
});
7781
}
7882
}

0 commit comments

Comments
 (0)