diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 8866b8a4bd7e24..3b001dd6545855 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -33,6 +33,10 @@ #import #import +#if RCT_DEV_MENU // [macOS +#import "RCTDevMenu.h" +#endif // macOS] + @implementation RCTRootViewFactoryConfiguration - (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled @@ -151,6 +155,14 @@ - (RCTPlatformView *)viewWithModuleName:(NSString *)moduleName // [macOS] #if !TARGET_OS_OSX // [macOS] surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor]; #endif // [macOS] + +#if RCT_DEV_MENU // [macOS + RCTDevMenu *devMenu = [self.reactHost.moduleRegistry moduleForClass:[RCTDevMenu class]]; + if (devMenu) { + surfaceHostingProxyRootView.devMenu = devMenu; + } +#endif // macOS] + if (_configuration.customizeRootView != nil) { _configuration.customizeRootView(surfaceHostingProxyRootView); } @@ -183,6 +195,16 @@ - (RCTPlatformView *)createRootViewWithBridge:(RCTBridge *)bridge { BOOL enableFabric = _configuration.fabricEnabled; RCTPlatformView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); // [macOS] + +#if RCT_DEV_MENU // [macOS + if (enableFabric && [rootView isKindOfClass:[RCTSurfaceHostingView class]]) { + RCTDevMenu *devMenu = [bridge moduleForClass:[RCTDevMenu class]]; + if (devMenu) { + [(RCTSurfaceHostingView *)rootView setDevMenu:devMenu]; + } + } +#endif // macOS] + #if !TARGET_OS_OSX // [macOS] rootView.backgroundColor = [UIColor systemBackgroundColor]; #endif // [macOS] @@ -327,4 +349,4 @@ - (NSURL *)bundleURL return self->_configuration.bundleURLBlock(); } -@end \ No newline at end of file +@end diff --git a/packages/react-native/React/Base/RCTRootView.m b/packages/react-native/React/Base/RCTRootView.m index 9ac9afb245b84b..87d869f19ab918 100644 --- a/packages/react-native/React/Base/RCTRootView.m +++ b/packages/react-native/React/Base/RCTRootView.m @@ -494,9 +494,9 @@ - (void)containingWindowDidResignKey { - (NSMenu *)menuForEvent:(NSEvent *)event { NSMenu *menu = nil; -#if __has_include("RCTDevMenu.h") && RCT_DEV +#if RCT_DEV_MENU menu = [[_bridge devMenu] menu]; -#endif +#endif // RCT_DEV_MENU if (menu == nil) { menu = [super menuForEvent:event]; } diff --git a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h index 5a348bb05ebe64..a5f312c44a6ff5 100644 --- a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h +++ b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h @@ -14,6 +14,9 @@ @class RCTBridge; @class RCTSurface; +#if RCT_DEV_MENU // [macOS +@class RCTDevMenu; +#endif // macOS] typedef RCTPlatformView *_Nullable (^RCTSurfaceHostingViewActivityIndicatorViewFactory)(void); // [macOS] @@ -63,6 +66,14 @@ NS_ASSUME_NONNULL_BEGIN * @param disabled if `YES`, the auto-hide is disabled. Otherwise the loading view will be hidden automatically */ - (void)disableActivityIndicatorAutoHide:(BOOL)disabled; + +#if RCT_DEV_MENU // [macOS +/** + * Dev menu for macOS context menu access. + */ +@property (nonatomic, strong, nullable) RCTDevMenu *devMenu; +#endif // macOS] + @end NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm index 44d8390e2243f6..b2b984b51bafe1 100644 --- a/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm +++ b/packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm @@ -13,6 +13,10 @@ #import "RCTSurfaceView.h" #import "RCTUtils.h" +#if RCT_DEV_MENU // [macOS +#import "RCTDevMenu.h" +#endif // macOS] + @interface RCTSurfaceHostingView () @property (nonatomic, assign) BOOL isActivityIndicatorViewVisible; @@ -134,6 +138,7 @@ - (void)setSizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode _sizeMeasureMode = sizeMeasureMode; [self _invalidateLayout]; } + - (void)disableActivityIndicatorAutoHide:(BOOL)disabled { _autoHideDisabled = disabled; @@ -278,4 +283,23 @@ - (void)surface:(__unused RCTSurface *)surface didChangeIntrinsicSize:(__unused }); } +#if TARGET_OS_OSX // [macOS + +#pragma mark - Context Menu + +- (NSMenu *)menuForEvent:(NSEvent *)event +{ +#if __has_include("RCTDevMenu.h") && RCT_DEV + // Try direct dev menu property first (simplest approach) + if (_devMenu) { + return [_devMenu menu]; + } + + +#endif + + return [super menuForEvent:event]; +} +#endif // macOS] + @end