Commit 30d5349
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
File tree
- packages/react-native/React
- Base
- CoreModules
- Fabric
- Mounting/ComponentViews
- LegacyViewManagerInterop
- View
- VirtualView
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| |||
702 | 703 | | |
703 | 704 | | |
704 | 705 | | |
| 706 | + | |
705 | 707 | | |
706 | 708 | | |
707 | 709 | | |
| |||
Lines changed: 5 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
| 71 | + | |
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| 75 | + | |
75 | 76 | | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
76 | 80 | | |
77 | 81 | | |
78 | 82 | | |
| |||
0 commit comments