Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.mm
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,16 +124,6 @@ void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled)
// Necessary to allow NativeModules to lookup TurboModules
[bridge setRCTTurboModuleRegistry:turboModuleManager];

#if RCT_DEV
/**
* Instantiating DevMenu has the side-effect of registering
* shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
* Therefore, when TurboModules are enabled, we must manually create this
* NativeModule.
*/
[turboModuleManager moduleForName:"RCTDevMenu"];
#endif // end RCT_DEV

auto runtimeInstallerLambda = [turboModuleManager, bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
if (!bridge || !turboModuleManager) {
return;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,6 +34,10 @@
#import <react/runtime/JSRuntimeFactory.h>
#import <react/runtime/JSRuntimeFactoryCAPI.h>

#if RCT_DEV_MENU
#import <React/RCTSurfaceHostingView.h>
#endif // RCT_DEV_MENU

@implementation RCTRootViewFactoryConfiguration

- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled
Expand DownExpand Up@@ -189,6 +193,12 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName

RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView =
[[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
#if RCT_DEV_MENU
RCTDevMenu *devMenu = [self.reactHost.moduleRegistry moduleForClass:[RCTDevMenu class]];
if (devMenu) {
surfaceHostingProxyRootView.devMenu = devMenu;
}
#endif // RCT_DEV_MENU

#if TARGET_OS_TV
surfaceHostingProxyRootView.backgroundColor = [UIColor clearColor];
Expand DownExpand Up@@ -216,6 +226,16 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
#else
rootView.backgroundColor = [UIColor blackColor];
#endif

#if RCT_DEV_MENU
if ([rootView isKindOfClass:[RCTSurfaceHostingView class]]) {
RCTDevMenu *devMenu = [bridge moduleForClass:[RCTDevMenu class]];
if (devMenu) {
[(RCTSurfaceHostingView *)rootView setDevMenu:devMenu];
}
}
Comment on lines +231 to +236

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not entirely a fan of the class check here..

#endif // RCT_DEV_MENU

return rootView;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@
#import <React/RCTSurfaceSizeMeasureMode.h>
#import <React/RCTSurfaceStage.h>

@class RCTDevMenu;

typedef UIView *_Nullable (^RCTSurfaceHostingViewActivityIndicatorViewFactory)(void);

NS_ASSUME_NONNULL_BEGIN
Expand DownExpand Up@@ -60,6 +62,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
/**
* Dev menu for key command access (Cmd+D, Cmd+I).
*/
@property (nonatomic, strong, nullable) RCTDevMenu *devMenu;
#endif

@end

NS_ASSUME_NONNULL_END
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,10 @@
#import "RCTSurfaceView.h"
#import "RCTUtils.h"

#if RCT_DEV_MENU
#import "RCTDevMenu.h"
#endif // RCT_DEV_MENU

@interface RCTSurfaceHostingView ()

@property (nonatomic, assign) BOOL isActivityIndicatorViewVisible;
Expand DownExpand Up@@ -249,4 +253,35 @@ - (void)surface:(__unused RCTSurface *)surface didChangeIntrinsicSize:(__unused
});
}

#pragma mark - Dev Menu

#if RCT_DEV_MENU
- (BOOL)canBecomeFirstResponder
{
return YES;
}

- (NSArray<UIKeyCommand *> *)keyCommands
{
return @[
[UIKeyCommand keyCommandWithInput:@"d"
modifierFlags:UIKeyModifierCommand
action:@selector(toggleDevMenu)],
[UIKeyCommand keyCommandWithInput:@"i"
modifierFlags:UIKeyModifierCommand
action:@selector(toggleElementInspector)],
];
}

- (void)toggleDevMenu
{
[_devMenu toggle];
}

- (void)toggleElementInspector
{
[_devMenu toggleElementInspector];
}
#endif // RCT_DEV_MENU

@end
17 changes: 16 additions & 1 deletion packages/react-native/React/CoreModules/RCTDevMenu.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ RCT_EXTERN NSString *const RCTShowDevMenuNotification;
/**
* Whether the hotkeys that toggles the developer menu is enabled.
*/
@property (nonatomic, assign) BOOL hotkeysEnabled;
@property (nonatomic, assign) BOOL hotkeysEnabled DEPRECATED_ATTRIBUTE;

/**
* Whether the developer menu is enabled.
Expand All@@ -84,6 +84,21 @@ RCT_EXTERN NSString *const RCTShowDevMenuNotification;
*/
- (void)show;

/**
* Manually toggle the dev menu.
*/
- (void)toggle;

/**
* Toggle the element inspector (called by key command).
*/
- (void)toggleElementInspector;

/**
* Reload from key command (called by key command).
*/
- (void)reloadFromKeyCommand;

/**
* Deprecated, use `RCTReloadCommand` instead.
*/
Expand Down
89 changes: 15 additions & 74 deletions packages/react-native/React/CoreModules/RCTDevMenu.mm
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,7 +12,6 @@
#import <React/RCTBundleURLProvider.h>
#import <React/RCTDefines.h>
#import <React/RCTDevSettings.h>
#import <React/RCTKeyCommands.h>
#import <React/RCTLog.h>
#import <React/RCTReloadCommand.h>
#import <React/RCTUtils.h>
Expand DownExpand Up@@ -150,74 +149,10 @@ - (instancetype)init

_keyboardShortcutsEnabled = true;
_devMenuEnabled = true;
[self registerHotkeys];
}
return self;
}

- (void)registerHotkeys
{
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];
__weak __typeof(self) weakSelf = self;

// Toggle debug menu
[commands registerKeyCommandWithInput:@"d"
modifierFlags:UIKeyModifierCommand
action:^(__unused UIKeyCommand *command) {
[weakSelf toggle];
}];

// Toggle element inspector
[commands registerKeyCommandWithInput:@"i"
modifierFlags:UIKeyModifierCommand
action:^(__unused UIKeyCommand *command) {
[(RCTDevSettings *)[weakSelf.moduleRegistry moduleForName:"DevSettings"]
toggleElementInspector];
}];
#endif
}

- (void)unregisterHotkeys
{
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];

[commands unregisterKeyCommandWithInput:@"d" modifierFlags:UIKeyModifierCommand];
[commands unregisterKeyCommandWithInput:@"i" modifierFlags:UIKeyModifierCommand];
#endif
}

- (BOOL)isHotkeysRegistered
{
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];

return [commands isKeyCommandRegisteredForInput:@"d" modifierFlags:UIKeyModifierCommand] &&
[commands isKeyCommandRegisteredForInput:@"i" modifierFlags:UIKeyModifierCommand];
#else
return NO;
#endif
}

- (BOOL)isReloadCommandRegistered
{
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];
return [commands isKeyCommandRegisteredForInput:@"r" modifierFlags:UIKeyModifierCommand];
#else
return NO;
#endif
}

- (void)unregisterReloadCommand
{
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];
[commands unregisterKeyCommandWithInput:@"r" modifierFlags:UIKeyModifierCommand];
#endif
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
Expand DownExpand Up@@ -525,23 +460,29 @@ - (BOOL)hotLoadingEnabled

- (void)setHotkeysEnabled:(BOOL)enabled
{
if (enabled) {
[self registerHotkeys];
} else {
[self unregisterHotkeys];
}
// Deprecated: hotkeys are now managed via UIKeyCommand on RCTSurfaceHostingView
}

- (BOOL)hotkeysEnabled
{
return [self isHotkeysRegistered];
// Deprecated: hotkeys are now managed via UIKeyCommand on RCTSurfaceHostingView
return NO;
}

- (void)disableReloadCommand
{
if ([self isReloadCommandRegistered]) {
[self unregisterReloadCommand];
}
// Deprecated: reload command is now managed via UIKeyCommand on RCTSurfaceHostingView
}

- (void)toggleElementInspector
{
RCTDevSettings *devSettings = [_moduleRegistry moduleForName:"DevSettings"];
[devSettings toggleElementInspector];
}

- (void)reloadFromKeyCommand
{
RCTTriggerReloadCommandListeners(@"Dev menu key command");
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -358,16 +358,6 @@ - (void)_start
jsInvoker:jsCallInvoker
devMenuConfigurationDecorator:_devMenuConfigurationDecorator];

#if RCT_DEV
/**
* Instantiating DevMenu has the side-effect of registering
* shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
* Therefore, when TurboModules are enabled, we must manually create this
* NativeModule.
*/
[_turboModuleManager moduleForName:"RCTDevMenu"];
#endif // end RCT_DEV

// Initialize RCTModuleRegistry so that TurboModules can require other TurboModules.
[_bridgeModuleDecorator.moduleRegistry setTurboModuleRegistry:_turboModuleManager];

Expand Down
Loading